名詞評価極性辞書を利用したTwitterの感情分析(Positeve/Negative判定)
Twitter感情分析所 さんを利用しようとしたら、結構重たくて、大量の処理を実行するのは申し訳ない…。と思い、じゃあ自分でコードを書いてしまえ、と思い、調べていたところ、東山昌彦, 乾健太郎, 松本裕治, 述語の選択選好性に着目した名詞評価極性の獲得, 言語処理学会第14回年次大会論文集, pp.584-587, 2008.(日本語評価極性辞書)がありました。
日本語評価極性辞書(名詞編)ver.1.0(2008年12月版)pn.csv.m3.120408.trim.gz をダウンロード→解凍し、拡張子に.txtを設定し、適当なエディタで開きます。
Python標準モジュールのcsvで読み込ませるときに、タブ区切りが上手く読み込めなかったので、\tを,に置換して、保存します(Mac OSXの場合、\はoption+\でバックスラッシュを入力)。
また、以下のサイトを参考に、Yahoo!のアプリケーションIDを取得し、形態素解析APIを利用可能にします。
PythonからYahoo!形態素解析APIを使う - 人工知能に関する断創録 | http://d.hatena.ne.jp/aidiary/20090415/1239802199
def get_tweets_from_streaming_listener(filename):は、Streaming APIで大量のつぶやきをリアルタイムに保存する方法(Python編) | inquisitor http://blog.unfindable.net/archives/4257 を参考に、tweepyからTwitter Streaming APIを利用して収集したツイートがresult01.datに保存されている場合に使える関数です。
コンソールから実行すると、スクリーンネームを聞かれますので、入力すると、そのひとのツイートと、その評価が出力されます。(※tweepyを使ってOAuth認証が必要です。)
また、毎度のことですが、Python最大の難所、PythonのUnicodeEncodeErrorを知る - HDEラボ http://lab.hde.co.jp/2008/08/pythonunicodeencodeerror.html を参考にしました。
精度がどのくらいのものなのか、P/N以外の感情も判定したい、などと色々考えていますので、コメントなど頂けると嬉しいです。
#!/usr/bin/env python # -*- coding: utf-8 -*- import csv import json import urllib import urllib2 import tweepy from BeautifulSoup import BeautifulSoup # dev.twitter.comから取得してくる。 consumer_token = "********************************" consumer_secret = "********************************" access_token = "********************************" access_token_secret = "********************************" auth = tweepy.OAuthHandler(consumer_token, consumer_secret) auth.set_access_token(access_token, access_token_secret) oauth_api = tweepy.API(auth) # 名詞評価極性辞書を読み込む in_file = csv.reader(open('pne.txt',"rb")) pne = [] for line in in_file: try: if line[1] == 'p': score = 1.0 elif line[1] == 'e': score = 0.5 elif line[1] == 'n': score = 0.0 pne.append((line[0],score)) except: pass # トークンのリストのP/Nを判定する。 def judge_pn(tokens): score = 0 num_score = 0 for token in tokens: for _pne in pne: if token == _pne[0]: score += _pne[1] num_score += 1 if num_score != 0: pn_rate = float(score)/float(num_score) else: pn_rate = 0.5 return pn_rate # 参考:PythonからYahoo!形態素解析APIを使う - 人工知能に関する断創録 http://d.hatena.ne.jp/aidiary/20090415/1239802199 # http://developer.yahoo.co.jp/webapi/jlp/ma/v1/parse.html appid = "********************************" # 登録したアプリケーションID pageurl = "http://jlp.yahooapis.jp/MAService/V1/parse" def morph(sentence, appid=appid, results="ma", filter="9"): sentence = sentence.encode("utf-8") params = urllib.urlencode({'appid':appid, 'results':results, 'filter':filter, 'sentence':sentence}) c = urllib2.urlopen(pageurl, params) soup = BeautifulSoup(c.read()) return [str(w.surface.string) for w in soup.ma_result.word_list] # Twitter Streaming APIを使ってfilenameにツイートが保存されているものとする def get_tweets_from_streaming_listener(filename): # Streaming Listenerから読み込み lines = open(filename,"r") lines = [line for line in lines] tweets=[] for line in lines: try: tweet = json.loads(line) tweets.append(tweet) except: pass # ツイートから本文だけを取り出す texts = [tweet["text"] for tweet in tweets] return tweets # tweets = get_tweets_from_streaming_listener("result01.dat") # 個々のツイート本文をトークン化 def tokenize_list(list): sents = [] for text in texts: tokenized_text = morph(text) sents.append((text, tokenized_text)) return sents # sents = tokenize_list(texts) # 個々のツイート本文のP/Nを判定し、pn_ratesに格納 def pn_rates_and_sents(sents): pn_rates = [] pn_rates_with_sents = [] for sent in sents: pn_rate = judge_pn(sent[1]) pn_rates.append(pn_rate) pn_rates_with_sents.append((sent[0], pn_rate)) return pn_rates, pn_rates_with_sents # pn_rates, pn_rates_with_sents = pn_rate_and_sents(sents) # P/E/Nスコアを算出して出力する def print_scores(pn_rates): p, e, n = 0.0, 0.0, 0.0 p_num, e_num, n_num = 0.0, 0.0, 0.0 for pn in pn_rates: if pn > 0.5: p += pn p_num += 1 elif pn == 0.5: e += pn e_num += 1 elif pn < 0.5: n += pn n_num += 1 sum = p_num + e_num + n_num print p, e, n, p_num, e_num, n_num print p_num/sum, e_num/sum, n_num/sum if __name__ == '__main__': screen_name = raw_input("Enter Screen Name. > ") tweets = oauth_api.user_timeline(screen_name=screen_name, count=20) texts = [tweet.text for tweet in tweets] sents = tokenize_list(texts) pn_rates, pn_rates_with_sents = pn_rates_and_sents(sents) print_scores(pn_rates) for pn_rate_with_sent in pn_rates_with_sents: print "%s\t%s\n" % (pn_rate_with_sent[0], pn_rate_with_sent[1])
- 作者: Steven Bird,Ewan Klein,Edward Loper,萩原正人,中山敬広,水野貴明
- 出版社/メーカー: オライリージャパン
- 発売日: 2010/11/11
- メディア: 大型本
- 購入: 20人 クリック: 639回
- この商品を含むブログ (44件) を見る