今回は、botに簡単な学習をさせてみた。
まだ途中だが、現時点での実装完了部分を書き留めておく。
(前回: TwitterBotの作成① - Hello World !)
bot.py
#!/usr/bin/env python #-*- coding: utf-8 -*- import twitter import sys from time import sleep from collections import defaultdict from module import remove_stopwords import random import igo.Tagger # pika_shi CONSUMER_KEY="XXXXXXXXXXXX" CONSUMER_SECRET="XXXXXXXXXXXX" ACCESS_TOKEN="XXXXXXXXXXXX" ACCESS_TOKEN_SECRET="XXXXXXXXXXXX" api = twitter.Api(consumer_key=CONSUMER_KEY, consumer_secret=CONSUMER_SECRET, access_token_key=ACCESS_TOKEN, access_token_secret=ACCESS_TOKEN_SECRET, cache=None) # pika_shi_bot bot_CONSUMER_KEY="XXXXXXXXXXXX" bot_CONSUMER_SECRET="XXXXXXXXXXXX" bot_ACCESS_TOKEN="XXXXXXXXXXXX" bot_ACCESS_TOKEN_SECRET="XXXXXXXXXXXX" bot_api = twitter.Api(consumer_key=bot_CONSUMER_KEY, consumer_secret=bot_CONSUMER_SECRET, access_token_key=bot_ACCESS_TOKEN, access_token_secret=bot_ACCESS_TOKEN_SECRET, cache=None) # 初期設定 since = 0 tweet_dic = {} # {id : tweet, …} for i in range(11): # TL取得 TL = api.GetFriendsTimeline(since_id=since) since = TL[0].id for tweet in TL: # reply除去 while 1: if tweet.text[0] == '@': tweet.text = tweet.text[tweet.text.find(' ')+1:len(tweet.text)] else: break #print tweet.user.screen_name + ' > ' + tweet.text tweet_dic[tweet.id] = tweet.text tweet_list = tweet_dic.items() # [(id,tweet)…] sleep(60*5) # 形態素解析 t = igo.Tagger.Tagger('ipadic_gae', gae=True) tf = defaultdict(list) # {word : [id,id,…]],…} for tweet in tweet_list: l = t.parse(tweet[1]) for m in l: #print m.surface,m.feature # 名詞かつ日本語かつ2文字以上のものを抽出 if m.feature.split(',')[0] == u"名詞" and m.feature.split(',')[len(m.feature.split(','))-1] != u"*" and len(m.surface) >= 2: # ストップワードと、同じツイートに複数出てくる単語は除去 if not remove_stopwords(m.surface) and tweet[0] not in tf[m.surface]: tf[m.surface].append(tweet[0]) # 最頻出単語を検索 max = 0 # idの個数の最大値 for key in sorted(tf.keys()): #print key,tf[key] if len(tf[key]) > max: max = len(tf[key]) # 最頻出単語を含むツイートのIDのリストを生成 id_list = [] for key in sorted(tf.keys()): if len(tf[key]) == max: id_list.extend(tf[key]) # その中からランダムで1つを選択し、つぶやく id = random.choice(id_list) for tweet in tweet_list: if tweet[0] == id: bot_api.PostUpdate(tweet[1])
module.py
#!/usr/bin/env python # -*- coding: utf-8 -*- # ストップワードの除去 def remove_stopwords(word): seq = [] f = open('Japanese.txt','r') while 1: s = f.readline().rstrip() if not s: break seq.append(unicode(s,'utf-8')) f.close() stopwords = frozenset(seq) #print type(stopwords) return word in stopwords
・学習法・アルゴリズム
1.
@pika_shi(Twitter)のTLを約1時間分取得し、reply除去した後に格納する。
2.
取得したツイートを形態素解析し、名詞かつ日本語かつ2文字以上かつストップワードでない単語を抽出。
また、ストップワードは除去し、1ツイートに同じ単語が複数回出てくる場合は、1回とカウントする。
3.
2で抽出された名詞の中で、最も出現回数が多かったもの(最頻出単語)を検索する。
4.
最頻出単語を含むツイートの中で、ランダムに1つを選択し、つぶやく。
簡単な例をあげる。
以下の様なTLがあったとする。
Aさん:地震だ。
Bさん:めっちゃ揺れたー
Cさん:おなかすいた
Dさん:今の地震?
Eさん:眠い
2を満たし、最も出現回数が多い単語は「地震」である。
したがってbotは
地震だ。
今の地震?
のいずれか1つをランダムでツイートする。
・注意点
MeCabは重くてGAEに乗らない
形態素解析にMeCabを用いてプログラムを作成していたが、いざGAEにあげる時に、重くてGAEに乗らないことが判明。
そこで、igo-python(igo-python 0.9.3 : Python Package Index)を導入。
MeCabと同じ形式で出力してくれるので、大幅にプログラムを変更することなく済んだ。
ちなみに、
ImportError: No module named igo.Tagger
がなかなか消えず苦労した。igoディレクトリをルートディレクトリに直接置くことで解消された。
・今後の課題
・ツイート内に@を含むものは取得しないようにする。
・@pika_shi(Twitter)のTLでは限界があるので、学習用のTLを作成し、様々なTLを取得したい。
次はreplyを実装しよう。