高専中退系エンジニアの意識高めな奴

高専をやめてwebエンジニアになったそーとくが、日々思ったことや意識の高そうなことを徒然なるままに書く意識の低いブログです。当面の目標は続けることです。

自分のAI(?)を作った話

こんにちは、そーとくです。 今回は、自分のツイッター上の発言を収集してそこからランダムに文章を生成するbotを作ったので簡単に紹介します。

目次

どんなの作ったの?

こんなの

f:id:Umisyo1210:20190124204838p:plain
訳が分からないよ…

Twitter twitter.com

GitHub github.com

動機

宇部高専のはすみさんという方が書いた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にまとめるなどしたい
  • 返信機能ほしい
  • コードが汚い → 一晩で書いたから許して…(適宜修正予定)

まとめ

マルコフ連鎖の知識がなくても取り合えず文章っぽいものが作れるBotGoogle先生に頼れば一晩で作り上げることができました。誉めて。 もっと細かく解説ほしいとかあったら気が向いたらちゃんと記事書きます、もしかしたらQiitaとかにするかもだけど。 それでは。