takuti.me ABOUT

2013-07-28

マルコフ連鎖でTwitter Botをつくりました

ひとまず動けばいいや程度に作りました。 @yootakuti がそれですよろしくおねがいします。

Twitter公式から自分の過去ツイート5万弱をダウンロードして、そのCSVからしゅうまい君で有名になったマルコフ連鎖(らしきこと)で文章を作ります。それを30分おきに行なって、しゃべります。

我ながらおもしろい。

マルコフ連鎖 is 何

なんだかついったーbot界(?)では「マルコフ連鎖」というワードばかりが一人歩きしている印象を受けますが、そもそもマルコフ連鎖ってどんなものなんでしょうか。Wikipedia先生に聞いてみましょう。

マルコフ連鎖は、未来の挙動が現在の値だけで決定され、過去の挙動と無関係である(マルコフ性)。各時刻において起こる状態変化(遷移または推移)に関して、マルコフ連鎖は遷移確率が過去の状態によらず、現在の状態のみによる系列である。

ふむふむ。

そして一般に「マルコフ連鎖でついったーbot」と言われた時にみんながやっているのは(たぶん)下のようなこと。

まずはツイートひとつひとつを分かち書きする。

私はヨーグルトが好きです。
を分かち書きすると
私 は ヨーグルト が 好き です 。
になる。

ここから1つずらしながら、3つずつの要素からなる塊を以下のようにたくさんつくる。

(はじまり) 私 は
私 は ヨーグルト
は ヨーグルト が
ヨーグルト が 好き
が 好き です
好き です 。
です 。 (おわり)

これを対象となるすべてのツイートに対して作ってあげる。

上の「私はヨーグルトが好きです。」の他にもう1つ、「ヨーグルトが嫌いだ」というフレーズに対しても同様に作れば、

(はじまり) ヨーグルト が
ヨーグルト が 嫌い
が 嫌い だ
嫌い だ (おわり)

となる。

こんな中で、3つの要素の塊をつなげていくのがマルコフ連鎖。

ちなみに要素3つずつで塊を作っていくのは、Wikipedia先生によるところの「3階マルコフ連鎖」にあたるという認識で大丈夫なのかな。

次の状態が現在を含めた過去N個の状態履歴に依存して決まる確率過程を、N階マルコフ連鎖(もしくは、N重マルコフ連鎖、N次マルコフ連鎖)という。

階数が高いほど元の文章に近づいていって、低いほどめちゃめちゃになる。

さて、話を戻して「私はヨーグルトが好きです。」「ヨーグルトが嫌いだ」の2つの文章からマルコフ連鎖で新しいツイートを生成してみましょう。

例えば最初に
(はじまり) 私 は
を選んだとしたら、次に来るのは「は」から始まる塊だけ。
上で作った塊たちの中で、「は」から始まる塊は
は ヨーグルト が
だけなのでこれを選択。この時点で、「私はヨーグルトが」となる。

その次に来るのは、先ほどと同様に、今度は「が」から始まる塊だけ。
候補は、
が 好き です
が 嫌い だ

の2つ。このどちらかをランダムで選ぶ。

上が選ばれれば「私はヨーグルトが好きです」と連鎖するし、下が選ばれれば「私はヨーグルトが嫌いだ」と連鎖して、元々の文とは真逆の意味になっちゃったりして面白い。

更にこれを(おわり)が来るまで繰り返していくと1つの文章が出来上がるという仕組み。元のツイートが多ければ多いほど3つずつの要素からなる塊はたくさんできて、最終的に生成される文章の幅も広がるというわけですね。

ここでWikipedia先生の教えに戻ると、マルコフ連鎖とは未来の挙動が現在の値だけで決定され、過去の挙動と無関係であるという、マルコフ性と呼ばれる特性に依るものでした。

つまり、
は ヨーグルト がの次に繋がる塊(=未来の挙動) は
は ヨーグルト が(=現在の値) だけで決定され、
(はじまり) 私 は(=過去の挙動) と無関係である。
ということ、なのかな・・・?

もし過去の挙動を見ていれば、どれだけ塊がたくさんあったとしても、「私はヨーグルトが」と始まってしまったら「私はヨーグルトが好きです」しかできあがらない。過去の挙動を無視するから、既存のツイートから新しいツイートが生み出せる。

というわけで、「マルコフ連鎖でついったーbot」なんだなぁと僕は解釈しました。しかしこのあたり、なんだかスッキリしないのでもっと理論的な話を近いうちに勉強できればと思います。

ここまでで何か間違いがあれば指摘していただけると嬉しいです。

実装の話

実装にあたり以下を参考にさせていただきました。コード面では、リプライのツイートに含まれるID(@なんちゃら)やRT/QT以降の文章、URLを除外する部分のみ参考にさせていただき、あとは上で書いたマルコフ連鎖をそのまま強引に自力で。

【参考】マルコフ連鎖でTwitter BOTを作る - FLYING

このほかに、CSVの読み込みに関して以下を参考にさせていただきました。確かに最強な感じある。
【参考】Ruby標準添付ライブラリcsvのCSV.tableメソッドが最強な件について

実際に今 @yootakuti で動いてるものは以下より。
takuti/twitter_bot

改善すべき点は多々ありますがとりあえず動けばいいやーな気持ちです。徐々に改善して行く予定です。しかし予定は未定です。

これをさくらのVPS上でcrontabから30分に一度回してあげればオーケイ。このとき、ローカル(Mac)では問題なかったのですが、さくらVPS上だと文字コード関係で怒られるので ruby のオプションに -Ku を付けてあげます。
【参考】Ruby, My Dear? (1) 日本語処理でハマる: ほらかわブログ

botたのしい


4年も前から同じような仕組みでしゅうまい君は動いてるっていうんだから、すごいですね。

前々から作ってみたかったついったーbotですが、実際に作ってみるとやっぱり面白いし可愛いですね。

そんなわけで、 @yootakuti よろしくおねがいします。(再)