自分のAI(?)を作った話
こんにちは、そーとくです。 今回は、自分のツイッター上の発言を収集してそこからランダムに文章を生成するbotを作ったので簡単に紹介します。
目次
どんなの作ったの?
こんなの
動機
宇部高専のはすみさんという方が書いたhsm_ai( https://twitter.com/hsm_ai )がうらやましかった。Rubyで書かれていたのでPythonで対抗してやろうと思った、
原理
TwitterAPIをたたいて自分のツイートデータを収集→MeCabを使って品詞事に分解して.txt形式で出力→そこからマルコフ連鎖で文章を生成→TwitterAPIでツイート
わからない部分はググりましょう、ちなみにマルコフ連鎖についてはいまだに理解していません()
環境
使用外部ライブラリ
全部pip installできます。
- Tweepy
- natto
- pandas
コード
くそ汚いですがご勘弁を…あと、今後更新する可能性もあります
まず認証関連、各値はTwitterAPI取得して各自でとってください
AK = 'アクセスキー' ASK = 'アクセスシークレットキー' AT = 'アクセストークン' ATS = 'アクセストークンシークレット'
なんか文章集めるとこ
from config import AK, ASK, AT, ATS import time import pandas as pd import tweepy from natto import MeCab #認証のおまじない auth = tweepy.OAuthHandler(AK, ASK) auth.set_access_token(AT, ATS) api = tweepy.API(auth ,wait_on_rate_limit = True) tweet_data = [] #ツイッターの情報を収集するクラス class Twitter_syusyukun: def syusyu(self, auth): self.count = 0 for tweet in tweepy.Cursor(api.user_timeline,screen_name = '@任意のユーザー名',exclude_replies = True).items(): tweet_data.append([tweet.text.replace('\n','')]) self.df = pd.DataFrame(tweet_data, index=None, columns=None, dtype=None, copy=False) #print(self.df) self.count += 1 if self.count == 1000: #1000回取得でループ終了 break #前のクラスで得た情報をMeCabで形態素解析して分かち書きしてtxtに書き込むクラス class mecab_owakatikun(Twitter_syusyukun, MeCab): def owakatikun(self): self.nm = MeCab('-Owakati') self.result = '' self.syusyu(auth) self.tweet_ls = self.nm.parse(str(self.df.values)) i = len(self.tweet_ls) for h in range (i): if '@' in str(self.tweet_ls[h]): h += 1 elif '時報' in str(self.tweet_ls[h]): h += 1 elif 'RT' in str(self.tweet_ls[h]): h += 1 else: self.result += self.tweet_ls[h] h += 1 self.write_txt = ''.join(self.result) with open('ツイートを書き込むファイルのパス', 'a') as f: f.write(str(self.write_txt) + '\n') f.close print(self.write_txt) mok = mecab_owakatikun() while True: mok.owakatikun() time.sleep(18000*24) #1日ごとにループを回す
最後にツイートする部分
import tweepy from config import AK, ASK, AT, ATS import time import random auth = tweepy.OAuthHandler(AK, ASK) auth.set_access_token(AT, ATS) api = tweepy.API(auth ,wait_on_rate_limit = True) #メイン関数 def main(): with open('ツイートを書き込んだtxtファイルのパス') as f: text = f.read() dic = str.maketrans('','',"_/\.%~^|= []'()「」「」??!!@.…::,1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ『』") #余計な文字列を除外 wordlist = str(text.translate(dic)) # マルコフ連鎖用のテーブルを作成する markov = {} w1 = '' w2 = '' w3 = '' for word in wordlist: if w1 and w2 and w3: if (w1, w2, w3) not in markov: markov[(w1, w2, w3)] = [] #print('w1 not in markov ', w1) #print('w2 not in markov ', w2) markov[(w1, w2, w3)].append(word) #print('w1 append:', w1) #print('w2 append:', w2) w1, w2, w3 = w2, w3, word #print('w1:', w1) #print('w2:', w2) # 文章の自動作成 count = 0 sentence = "" w1, w2, w3 = random.choice(list(markov.keys())) N = range(100) while count < random.choice(N): tmp = random.choice(markov[(w1, w2, w3)]) sentence += tmp w1, w2, w3 = w2, w3, tmp count += 1 print(sentence.strip()) api.update_status(sentence.strip()) #5分に一回ループを回す while True: main() time.sleep(3000)
とまあこんな感じです、コミット履歴を見るとどうやらほとんどの部分を一晩で作ったことになってます。 マルコフ連鎖周りは自分でもよく理解してなくて、いろいろ試してみて最後になんかよくわかんないけど動いたのでそれを採用してます() APIたたくところはググったほうが早いので特に説明することはないですね()
課題
- 文章の精度が低い → 品詞事に属性をつけてcsvにまとめるなどしたい
- 返信機能ほしい
- コードが汚い → 一晩で書いたから許して…(適宜修正予定)
まとめ
マルコフ連鎖の知識がなくても取り合えず文章っぽいものが作れるBotはGoogle先生に頼れば一晩で作り上げることができました。誉めて。 もっと細かく解説ほしいとかあったら気が向いたらちゃんと記事書きます、もしかしたらQiitaとかにするかもだけど。 それでは。