[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
[[ノート/テキストマイニング]]~
訪問者数 &counter(); 最終更新 &lastmod();~
Contents~
#contents
**ツイートをMeCabで分解して、targetの単語を含むツイートを数える --- 2012/10/21 [#q26a8d62]
やることは
-DBを読出し、それぞれのツイートをMeCabに食わせる
-切り出した単語が、targetとして指定した単語に等しいとき、ツイート数をカウントする~
1時間ごとに、該当語を含むツイート数/全ツイート数 を求める
-過去HH時間内のデータについて、上記の比を求め、matplotlibによってグラフに表示する
プログラムは次のようになった。2つ間違いがある。
1つは、ヒットしたツイート数を数える代わりに、ヒットした回数を数えてしまっている。だから、もし1つのツイート中に複数のヒットがあれば、その数を数えてしまう。
もう1つは、パフォーマンス上のものだが、単にtarget単語を含むツイートを数えるだけなら、SQLでLIKEとCOUNTを使うか、またはツイート全体をPythonの正規表現を使った方が、ここでやっているようなMeCabでの形態素解析をするより、はるかに早いはずである。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# dbtowordfreq.py <word>
# 1) DBから読む
# 2) MeCabで単語に分割する
# 3) targetの語に一致する語を含むツイート数を数え、全ツイート数との比を求める
# 4) グラフに表示する
import sys
import codecs
import time
import datetime
import matplotlib
matplotlib.use('Agg') # グラフをpngで出力するため
import matplotlib.pyplot as plt
from pylab import *
import MeCab
import MySQLdb
import string
from dbinit import dbinit # 自前のdbinitを呼出すため
argvs = sys.argv # コマンドラインパラメタとしてtargetを与える
argc = len(argvs)
if (argc != 2):
print 'Usage: python %s targetword' % argvs[0]
quit()
target = argvs[1]
print target
while 1:
try:
con = dbinit()
d = datetime.datetime.today()
x = []
xt = []
y = []
fig = plt.figure()
mt = MeCab.Tagger()
#for i in range(-2,1):
for i in range(-48,1): # 過去48時間にさかのぼってツイート数を計算
t = (d + datetime.timedelta(hours=i)).strftime("%y%m%d%H") # テーブル名に当る文字列 yymmddHH を現在時刻から作成
tablename = "tw" + t
# DB内に、上記tで指定したテーブルが未だ出来ていないことがあるのでチェックする(時刻が変わった直後)
s = "SHOW TABLES FROM twitter like '" + tablename + "'" # SHOW TABLEからテーブル名を検索
cur = con.cursor()
cur.execute(s.encode('utf_8'))
cnt = cur.rowcount
if (cnt==0):
cur.close()
print "No table" # テーブルがなかったら何もしないことにした
break
cur.close()
# テーブルの有無チェック終り
c = 0
count = 0
s = "SELECT text FROM " + tablename
cur = con.cursor()
cur.execute(s)
r = cur.fetchone()
while (r != None):
m = mt.parseToNode(r[0].encode('utf_8')) # MeCabで単語に分解
while m:
go = m.surface
if (target == go):
count = count + 1 # 一致する語数をカウントする
m = m.next
# print "EOS"
r = cur.fetchone()
c = c+1 # cは総ツイート数をカウントする
cur.close()
if (c!=0): # cが0のことがあるためチェック
ratio = float(count)/float(c) * 10000.0
else:
ratio = 0.0
x.append(i) # xの側はiのリストを作る。この順に表示する
#nichiji = t[4:6]+u'日'+t[6:]+u'時'
nichiji = t[6:]+u'時' # グラフx軸の刻みに表示するための時刻部分
xt.append(nichiji) # xt (xtick) のリストを作る
y.append(ratio) # yの側はratioのリストを作る
print u"時刻", nichiji, u"サンプル数", c, u"カウント数", count, u"比率", ratio
con.close()
# ここからグラフ表示処理 matplotlibを使う
fig.clf() # figureをクリア
sb = subplot(111) # subplotを作る(後でtickを書き直すときに必要)
plt.plot(x,y,'bo-') # グラフを描く。b=青、o=丸を描く。-=直線
title(u'語「' + unicode(target) + u'」を含むツイート数(1時間当り)', fontname="VL Gothic", fontsize=20) # 漢字なのでフォント指定必要
#xlabel(u'日/時', fontname="VL Gothic")
xlabel(u'時刻', fontname="VL Gothic")
for tick in sb.xaxis.get_major_ticks(): # すべてのx tickの向きを270度にする
#tick.label.set_rotation('vertical')
tick.label.set_rotation(270)
xticks(x, xt) # xの値に対してxtのtick値を描く
ylabel(u'ツイート比', fontname="VL Gothic")
ylim(ymin=0) # y軸の起点を0からにする(そうしないと適当な値から描く)
plt.savefig('/var/www/html/tw/twplot2.png') # 図を絵としてファイル出力
plt.close(fig)
#print y
time.sleep(30) # 30秒おきに繰り返す
except KeyboardInterrupt:
print "終了Ended by Ctrl-C"
quit()
これで、画像ファイルtwplot2.pngが作られるので、それを見ればよい。このプログラムはこのファイルに書ける権限を持つ必要がある。
画像ファイルを見るためのHTMLは、この程度でよい
<html>
<head>
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="refresh" content="30">
</head>
<body>
<img src="twplot.png">
</body>
</html>
**ツイートをMeCabで分解して、targetの単語を含むツイートを数える (改良版) --- 2013/06/21 [#f2d5f75f]
グラフ図画をファイルに書き出すとCGIにしたときにそのファイルの管理(アクセス権も含めて)が面倒なので、直接描画させる(=pngファイルを作らない)。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import MySQLdb
import codecs
import os
import sys
import cgi
import cgitb; cgitb.enable()
import time
import datetime
import tempfile
os.environ[ 'MPLCONFIGDIR' ] = tempfile.mkdtemp() ## This is necessary before importing matplotlib
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from pylab import * ## Needs this instead of "import pylab" for some reason
## Note that "sys.stdout = codecs.getwriter('utf_8')(sys.stdout)" should be omitted.
## Otherwise, output image data will be transcoded.
# Change default settings
rcParams['font.family'] = 'VL Gothic' # This allows Kanji without MojiBake
rcParams['figure.figsize'] = (9,7) # Size of figure to 9in x 7in
#Path input data from the html FORM page
form = cgi.FieldStorage()
titleword = unicode(form["keyword"].value)
sstring = u'%' + unicode(titleword) + u'%'
try:
while 1: # This infinite loop may be omitted.
d = datetime.datetime.today()
con = MySQLdb.connect(db="****", host="localhost", port=3306,
user="****", passwd="****")
x = []
xt = []
y = []
#fig = plt.figure(figsize=(12,7))
for i in range(-72,1):
#for i in range(-120,1):
t = (d + datetime.timedelta(hours=i)).strftime("%y%m%d%H")
tablename = "tw" + t
s = "SHOW TABLES FROM twitter like '" + tablename + "'"
cur = con.cursor()
cur.execute(s.encode('utf_8'))
cnt = cur.rowcount
if (cnt==0):
cur.close()
#print "No table"
break
cur.close()
s = ("SELECT COUNT(*) FROM " + tablename + " WHERE text LIKE '" + sstring + "'").encode('utf_8')
#print s
cur = con.cursor()
cur.execute(s)
r = cur.fetchone()
cur.close()
x.append(i)
nichi = t[4:6]
ji = t[6:]
if ((int(ji)%3)==0):
xt.append(nichi+'/'+ji)
else:
xt.append('')
y.append(r[0])
con.close()
sb = subplot(111)
plt.plot(x,y,'bo-')
title(u'Number of Observed Kanji Tweets per Hour "'+titleword.encode('utf_8')+u'"', fontsize=20)
xlabel('Day/Hour')
ylabel('Number of Tweets')
for tick in sb.xaxis.get_major_ticks():
tick.label.set_rotation(270)
xticks(x, xt)
# save the plot as a png and output directly to webserver
print "Content-Type: image/png\n"
plt.savefig( sys.stdout, format='png' )
time.sleep(60)
except KeyboardInterrupt:
#print "終了Ended by Ctrl-C"
quit()
このファイル名を cgi-bin/tw/twplot3.py であるとすると、それを起動する<FORM>を含むHTMLファイルは、
<html>
<body>
<form method="POST" action="../cgi-bin/tw/twplot3.py">
<input type="text" name="keyword">
<input type="submit" value="送信">
</form>
</body>
</html>
のように書くことになる。ここのkeywordから検索キーワードをCGIに渡す。
漢字を表示するためには(デフォルトのフォントは漢字を含まないので)フォントを変更する必要がある。 毎回書くたびにフォントを指定する方法だと
title(u'Number of Observed Kanji Tweets per Hour "'+titleword.encode('utf_8')+u'"', fontsize=20, fontname='VL Gothic')
xlabel('Day/Hour', fontname='VL Gothic')
ylabel('Number of Tweets', fontname='VL Gothic')
のように書くが、面倒に感じる。システム全体に対するフォントの変更はrcファイルでも可能([[ここ参照:http://matplotlib.org/users/customizing.html]])だが、他のケースで困るといけないので、このプログラムの中だけの変更にしたい(が書くたびに指定するのは嫌だ)。そういう時には、
rcParams['font.family'] = 'VL Gothic' # This allows Kanji without MojiBake
として設定できる。
終了行:
[[ノート/テキストマイニング]]~
訪問者数 &counter(); 最終更新 &lastmod();~
Contents~
#contents
**ツイートをMeCabで分解して、targetの単語を含むツイートを数える --- 2012/10/21 [#q26a8d62]
やることは
-DBを読出し、それぞれのツイートをMeCabに食わせる
-切り出した単語が、targetとして指定した単語に等しいとき、ツイート数をカウントする~
1時間ごとに、該当語を含むツイート数/全ツイート数 を求める
-過去HH時間内のデータについて、上記の比を求め、matplotlibによってグラフに表示する
プログラムは次のようになった。2つ間違いがある。
1つは、ヒットしたツイート数を数える代わりに、ヒットした回数を数えてしまっている。だから、もし1つのツイート中に複数のヒットがあれば、その数を数えてしまう。
もう1つは、パフォーマンス上のものだが、単にtarget単語を含むツイートを数えるだけなら、SQLでLIKEとCOUNTを使うか、またはツイート全体をPythonの正規表現を使った方が、ここでやっているようなMeCabでの形態素解析をするより、はるかに早いはずである。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# dbtowordfreq.py <word>
# 1) DBから読む
# 2) MeCabで単語に分割する
# 3) targetの語に一致する語を含むツイート数を数え、全ツイート数との比を求める
# 4) グラフに表示する
import sys
import codecs
import time
import datetime
import matplotlib
matplotlib.use('Agg') # グラフをpngで出力するため
import matplotlib.pyplot as plt
from pylab import *
import MeCab
import MySQLdb
import string
from dbinit import dbinit # 自前のdbinitを呼出すため
argvs = sys.argv # コマンドラインパラメタとしてtargetを与える
argc = len(argvs)
if (argc != 2):
print 'Usage: python %s targetword' % argvs[0]
quit()
target = argvs[1]
print target
while 1:
try:
con = dbinit()
d = datetime.datetime.today()
x = []
xt = []
y = []
fig = plt.figure()
mt = MeCab.Tagger()
#for i in range(-2,1):
for i in range(-48,1): # 過去48時間にさかのぼってツイート数を計算
t = (d + datetime.timedelta(hours=i)).strftime("%y%m%d%H") # テーブル名に当る文字列 yymmddHH を現在時刻から作成
tablename = "tw" + t
# DB内に、上記tで指定したテーブルが未だ出来ていないことがあるのでチェックする(時刻が変わった直後)
s = "SHOW TABLES FROM twitter like '" + tablename + "'" # SHOW TABLEからテーブル名を検索
cur = con.cursor()
cur.execute(s.encode('utf_8'))
cnt = cur.rowcount
if (cnt==0):
cur.close()
print "No table" # テーブルがなかったら何もしないことにした
break
cur.close()
# テーブルの有無チェック終り
c = 0
count = 0
s = "SELECT text FROM " + tablename
cur = con.cursor()
cur.execute(s)
r = cur.fetchone()
while (r != None):
m = mt.parseToNode(r[0].encode('utf_8')) # MeCabで単語に分解
while m:
go = m.surface
if (target == go):
count = count + 1 # 一致する語数をカウントする
m = m.next
# print "EOS"
r = cur.fetchone()
c = c+1 # cは総ツイート数をカウントする
cur.close()
if (c!=0): # cが0のことがあるためチェック
ratio = float(count)/float(c) * 10000.0
else:
ratio = 0.0
x.append(i) # xの側はiのリストを作る。この順に表示する
#nichiji = t[4:6]+u'日'+t[6:]+u'時'
nichiji = t[6:]+u'時' # グラフx軸の刻みに表示するための時刻部分
xt.append(nichiji) # xt (xtick) のリストを作る
y.append(ratio) # yの側はratioのリストを作る
print u"時刻", nichiji, u"サンプル数", c, u"カウント数", count, u"比率", ratio
con.close()
# ここからグラフ表示処理 matplotlibを使う
fig.clf() # figureをクリア
sb = subplot(111) # subplotを作る(後でtickを書き直すときに必要)
plt.plot(x,y,'bo-') # グラフを描く。b=青、o=丸を描く。-=直線
title(u'語「' + unicode(target) + u'」を含むツイート数(1時間当り)', fontname="VL Gothic", fontsize=20) # 漢字なのでフォント指定必要
#xlabel(u'日/時', fontname="VL Gothic")
xlabel(u'時刻', fontname="VL Gothic")
for tick in sb.xaxis.get_major_ticks(): # すべてのx tickの向きを270度にする
#tick.label.set_rotation('vertical')
tick.label.set_rotation(270)
xticks(x, xt) # xの値に対してxtのtick値を描く
ylabel(u'ツイート比', fontname="VL Gothic")
ylim(ymin=0) # y軸の起点を0からにする(そうしないと適当な値から描く)
plt.savefig('/var/www/html/tw/twplot2.png') # 図を絵としてファイル出力
plt.close(fig)
#print y
time.sleep(30) # 30秒おきに繰り返す
except KeyboardInterrupt:
print "終了Ended by Ctrl-C"
quit()
これで、画像ファイルtwplot2.pngが作られるので、それを見ればよい。このプログラムはこのファイルに書ける権限を持つ必要がある。
画像ファイルを見るためのHTMLは、この程度でよい
<html>
<head>
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="refresh" content="30">
</head>
<body>
<img src="twplot.png">
</body>
</html>
**ツイートをMeCabで分解して、targetの単語を含むツイートを数える (改良版) --- 2013/06/21 [#f2d5f75f]
グラフ図画をファイルに書き出すとCGIにしたときにそのファイルの管理(アクセス権も含めて)が面倒なので、直接描画させる(=pngファイルを作らない)。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import MySQLdb
import codecs
import os
import sys
import cgi
import cgitb; cgitb.enable()
import time
import datetime
import tempfile
os.environ[ 'MPLCONFIGDIR' ] = tempfile.mkdtemp() ## This is necessary before importing matplotlib
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from pylab import * ## Needs this instead of "import pylab" for some reason
## Note that "sys.stdout = codecs.getwriter('utf_8')(sys.stdout)" should be omitted.
## Otherwise, output image data will be transcoded.
# Change default settings
rcParams['font.family'] = 'VL Gothic' # This allows Kanji without MojiBake
rcParams['figure.figsize'] = (9,7) # Size of figure to 9in x 7in
#Path input data from the html FORM page
form = cgi.FieldStorage()
titleword = unicode(form["keyword"].value)
sstring = u'%' + unicode(titleword) + u'%'
try:
while 1: # This infinite loop may be omitted.
d = datetime.datetime.today()
con = MySQLdb.connect(db="****", host="localhost", port=3306,
user="****", passwd="****")
x = []
xt = []
y = []
#fig = plt.figure(figsize=(12,7))
for i in range(-72,1):
#for i in range(-120,1):
t = (d + datetime.timedelta(hours=i)).strftime("%y%m%d%H")
tablename = "tw" + t
s = "SHOW TABLES FROM twitter like '" + tablename + "'"
cur = con.cursor()
cur.execute(s.encode('utf_8'))
cnt = cur.rowcount
if (cnt==0):
cur.close()
#print "No table"
break
cur.close()
s = ("SELECT COUNT(*) FROM " + tablename + " WHERE text LIKE '" + sstring + "'").encode('utf_8')
#print s
cur = con.cursor()
cur.execute(s)
r = cur.fetchone()
cur.close()
x.append(i)
nichi = t[4:6]
ji = t[6:]
if ((int(ji)%3)==0):
xt.append(nichi+'/'+ji)
else:
xt.append('')
y.append(r[0])
con.close()
sb = subplot(111)
plt.plot(x,y,'bo-')
title(u'Number of Observed Kanji Tweets per Hour "'+titleword.encode('utf_8')+u'"', fontsize=20)
xlabel('Day/Hour')
ylabel('Number of Tweets')
for tick in sb.xaxis.get_major_ticks():
tick.label.set_rotation(270)
xticks(x, xt)
# save the plot as a png and output directly to webserver
print "Content-Type: image/png\n"
plt.savefig( sys.stdout, format='png' )
time.sleep(60)
except KeyboardInterrupt:
#print "終了Ended by Ctrl-C"
quit()
このファイル名を cgi-bin/tw/twplot3.py であるとすると、それを起動する<FORM>を含むHTMLファイルは、
<html>
<body>
<form method="POST" action="../cgi-bin/tw/twplot3.py">
<input type="text" name="keyword">
<input type="submit" value="送信">
</form>
</body>
</html>
のように書くことになる。ここのkeywordから検索キーワードをCGIに渡す。
漢字を表示するためには(デフォルトのフォントは漢字を含まないので)フォントを変更する必要がある。 毎回書くたびにフォントを指定する方法だと
title(u'Number of Observed Kanji Tweets per Hour "'+titleword.encode('utf_8')+u'"', fontsize=20, fontname='VL Gothic')
xlabel('Day/Hour', fontname='VL Gothic')
ylabel('Number of Tweets', fontname='VL Gothic')
のように書くが、面倒に感じる。システム全体に対するフォントの変更はrcファイルでも可能([[ここ参照:http://matplotlib.org/users/customizing.html]])だが、他のケースで困るといけないので、このプログラムの中だけの変更にしたい(が書くたびに指定するのは嫌だ)。そういう時には、
rcParams['font.family'] = 'VL Gothic' # This allows Kanji without MojiBake
として設定できる。
ページ名: