[[ノート/テキストマイニング]]~ 訪問者数 &counter(); 最終更新 &lastmod();~ **ツイートを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を見ればよい。このプログラムはこのファイルに書ける権限を持つ必要がある。 [[ノート/テキストマイニング]]~ 訪問者数 &counter(); 最終更新 &lastmod();~ #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を見ればよい。このプログラムはこのファイルに書ける権限を持つ必要がある。 [[ノート/テキストマイニング]]~ 訪問者数 &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を見ればよい。このプログラムはこのファイルに書ける権限を持つ必要がある。 これで、画像ファイル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. #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="twitter", host="localhost", port=3306, user="twitter", passwd="chariot7") 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() #print str(tablename) + " " + str(r[0]) 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() #fig.clf() sb = subplot(111) plt.plot(x,y,'bo-') title(u'Number of Observed Kanji Tweets per Hour "'+titleword.encode('utf_8')+u'"', fontname="VL Gothic", 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() [[ノート/テキストマイニング]]~ 訪問者数 &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. #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="twitter", host="localhost", port=3306, user="twitter", passwd="chariot7") 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() #print str(tablename) + " " + str(r[0]) 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() #fig.clf() sb = subplot(111) plt.plot(x,y,'bo-') title(u'Number of Observed Kanji Tweets per Hour "'+titleword.encode('utf_8')+u'"', fontname="VL Gothic", 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に渡す。 [[ノート/テキストマイニング]]~ 訪問者数 &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. #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="twitter", host="localhost", port=3306, user="twitter", passwd="chariot7") 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'"', fontname="VL Gothic", 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に渡す。 [[ノート/テキストマイニング]]~ 訪問者数 &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'"', fontname="VL Gothic", fontsize=20) 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に渡す。 [[ノート/テキストマイニング]]~ 訪問者数 &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に渡す。 漢字を表示するためには(デフォルトのフォントは漢字を含まないので)フォントを変更する必要がある。 フォントの変更は、システム全体に対するrcファイルでも可能だが、困るといけないので、このプログラムの中での設定にする。 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に渡す。 漢字を表示するためには(デフォルトのフォントは漢字を含まないので)フォントを変更する必要がある。 フォントの変更は、システム全体に対するrcファイルでも可能だが、困るといけないので、このプログラムの中での設定にする。 漢字を表示するためには(デフォルトのフォントは漢字を含まないので)フォントを変更する必要がある。 毎回書くたびにフォントを指定する方法だと 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ファイルでも可能だが、他のケースで困るといけないので、このプログラムの中だけの変更にしたい(が書くたびに指定するのは嫌だ)。そういう時には、 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ファイルでも可能だが、他のケースで困るといけないので、このプログラムの中だけの変更にしたい(が書くたびに指定するのは嫌だ)。そういう時には、 のように書くが、面倒に感じる。システム全体に対するフォントの変更はrcファイルでも可能([[ここ参照:http://matplotlib.org/users/customizing.html]])だが、他のケースで困るといけないので、このプログラムの中だけの変更にしたい(が書くたびに指定するのは嫌だ)。そういう時には、 rcParams['font.family'] = 'VL Gothic' # This allows Kanji without MojiBake として設定できる。