はじめに
今回は、多忙でお疲れのような落合陽一さんの代わりに、
「Twitterくらいなら代行できるんじゃね?」
と思い、落合陽一っぽいツイートを自動生成してツイートをするbotを作りました。
文章の自動生成自体は昔からある技術で、既に(特に2016年に)多くの記事が書かれているのですが、そのまま使おうと思うとほとんどの場合現在ではエラーが発生しまくり使いものにならないため、今回バージョンアップしたものを残そうと思いました。
-> GitHubはこちら
文章生成には大きくLSTMを使ったものと、マルコフ連鎖を使ったものがありますが、
LSTMだと毎回文頭を指定する必要があり、めんどくさいため今回はマルコフ連鎖を使いました。
-> LSTMバージョンもやるかも(未定)
学習データ
データ集め
まずは、ひたすら落合陽一のツイートを集めまくる必要があります。
しかし、ここで問題がありました。
落合陽一のツイート、ほとんど写真付きかリツイートだったのです。
うーん。。これは結構編集が大変そうだなあと思っていましたが、
親切なことに落合陽一ワードbotという落合陽一のツイートのうち文字だけを抽出してくれているアカウントがあったので、そちらのデータを使わせていただきました。
-> Twitterの他人のツイートの過去ログを一括ダウンロードする方法
ツイートデータの前処理
おかげで、かなり手間は省けましたが、日時などのデータも一緒に付いてきてしまうため、
ツイート本文のみをゴリ押しで抽出します。
text = open("ochyai.txt","r").read().split()
import string
for line in text:
    for word in line:
        if word in string.ascii_letters or word in string.digits:
            if line in text:
                text.remove(line)
f = open('new_ochyai.txt', 'w')
for x in text:
    f.write(str(x) + "\n")
f.close()
実装
辞書の作成
テキストを形態素解析して辞書を作ります。
形態素解析にちょっと時間がかかり毎回やるのはめんどくさいので、
ここで作った辞書をずっと使えるようjsonファイルに保存しておきます。
from janome.tokenizer import Tokenizer
import json
# テキストファイルを読み込む
sjis = open('new_ochyai.txt', 'rb').read()
text = sjis.decode('utf_8')
# テキストを形態素解析読み込みます
t = Tokenizer()
words = t.tokenize(text)
# 辞書を生成
def make_dic(words):
    tmp = ["@"]
    dic = {}
    for i in words:
        word = i.surface
        if word == "" or word == "\r\n" or word == "\n": continue
        tmp.append(word)
        if len(tmp) < 3: continue
        if len(tmp) > 3: tmp = tmp[1:]
        set_word3(dic, tmp)
        if word == "。":
            tmp = ["@"]
            continue
    return dic
# 三要素のリストを辞書として登録
def set_word3(dic, s3):
    w1, w2, w3 = s3
    if not w1 in dic: dic[w1] = {}
    if not w2 in dic[w1]: dic[w1][w2] = {}
    if not w3 in dic[w1][w2]: dic[w1][w2][w3] = 0
    dic[w1][w2][w3] += 1
dic = make_dic(words)
json.dump(dic, open("markov-blog.json", "w", encoding="utf-8"))
文章の生成
今回は"."を印に、1文ずつ取り出しました。
# -*- coding: utf-8 -*-
# 辞書の読み込み
import json
dic = open("markov-blog.json" , "r")#crontabを使う場合は、絶対パスに書き換える
dic = json.load(dic)
# 文章を生成
tweets_list = []
import random
def word_choice(sel):
    keys = sel.keys()
    ran = random.choice(list(keys))
    return ran
def make_sentence(dic):
    ret = []
    if not "@" in dic: return "no dic"
    top = dic["@"]
    w1 = word_choice(top)
    w2 = word_choice(top[w1])
    ret.append(w1)
    ret.append(w2)
    while True:
        w3 = word_choice(dic[w1][w2])
        ret.append(w3)
        if w3 == ".": break
        w1, w2 = w2, w3
    tweets_list.append(ret)
    return "".join(ret)
    
for i in range(1):
    s = make_sentence(dic)
生成した文章をツイートする
生成した文をいよいよツイートさせていきます。
プロフラムからツイートをさせるためには、ツイートさせたいアカウントでAPIを所得する必要があるので、まずは取得するようにしましょう。
APIのkeyをそれぞれ取得したら、いよいよツイートプログラムを実装します。
-> ここを参考にしました。
# 文章をツイートする
import twitter
auth = twitter.OAuth(consumer_key="",
consumer_secret="",
token="",
token_secret="")
t = twitter.Twitter(auth=auth)
# テキストのみツイート
status = s  #投稿するツイート
t.statuses.update(status=status) #Twitterに投稿
bot化
crontabを使って、定期的に上のプログラムを実行させてbotを作成しようとしたのですが、
以下のエラーが解決できず詰みました。
誰かわかる方いましたらコメントかTwitterの方で教えてください。お願いします。
結果
今の所いちいち手動でプログラム実行するしかないけど、ツイート自体はこんな感じ
なんかそれっぽいこと言ってますね!
(内は全く頭に入ってこないが)
終わりに
元ネタからアイデアを思いついた時は、サクッとできるんじゃね?と思っていたのですが、
そのまま使える文献がなくかなり実は時間がかかりました。。
最後の自動bot化するところは(crontabを使ったことがなかったせいか)どんなに頑張ってもうまくいかず残念でした。
うーん。。
Twitterでは、エンジニア向けの面白そうな情報など発信しているのでフォローしてもらえると嬉しいです。
よろしくお願いします。
DMを頂ければ、個別で何か協力したり質問に答えたりなどもするので何なりと連絡してください。
それでは!


