前回の記事に引き続きRaspberry Piネタ。マルコフ連鎖により文章を自動生成しLCDに出力してみた。

出力例の画像

人工無脳とは

考えてるように見えて考えてない。ただ確率に従い文章を生成するプログラム。それでも人間から見ると、意味のある文章に見える文章が生成される。

基本的な生成手順は

  1. 元データを形態素解析して形態素毎に分割
  2. マルコフ連鎖により再構成

形態素解析

自然言語で書かれた文を、形態素 (言語で意味を持つ最小単位) ごとに分割し、各形態素の品詞を特定することを形態素解析と呼ぶ。プログラムで自然言語を扱う場合、よく使われる技術の一つ。細かいことはWikipedia でも見てください。

日本語の形態素解析を行うためのツールは以下の様なものがある。

  • MeCab
    • bi-gram マルコフモデル
    • 学習モデルはCRF
  • ChaSen
    • 可変長マルコフモデル
    • 学習モデルは隠れマルコフモデル(HMM)
  • KyTea
    • 比較的最近でてきたもの
    • ネットスラングや顔文字などの認識も比較的精度がいいらしい
  • 日本語形態素解析Webサービス
    • Webベースの日本語形態素解析API
    • 組み込み系などマシンが非力な場合にも使えそう

今回は使い慣れているMeCabを使いました。

マルコフ連鎖

すごく簡単に言うと、ある要素を次々と発生させる状況を考えたときに、次の要素が現在の要素のみによって決まるのがマルコフ連鎖である。詳しくはWikipediaでも見てください。

これを文章に適用した場合の例だが、解説はこのページがわかりやすい(「それが大事」にマルコフ連鎖を適用してみる)。

ある単語があったとき、その単語の次に現れる可能性のある単語の確率のみを考える場合を単語uni-gramのマルコフ連鎖、2単語ずつをペアにして考える場合を単語bi-gramのマルコフ連鎖、さらに続いてtri-gram、4-gram、…N-gram。と呼ぶ。

例えば、
私/は/旅行/に/行き/たい/。
という文章があった場合、

  • 単語uni-gram:
    • “私”, “は”, “旅行”, “に”, “行き”, “たい”, “。”
  • 単語bi-gram:
    • “私/は”, “は/旅行”, “旅行/に”, “に/行き”, “行き/たい”, “たい/。”
  • 単語tri-gram:
    • “私/は/旅行”, “は/旅行/に”, “旅行/に/行き”, “に/行き/たい”, “行き/たい/。”
      となる。

文章を生成する際のポイント

  1. 要素の単位
    • 文字単位でマルコフ連鎖を行う場合もあるが、単語単位で生成したほうが読みやすい文章になる。N-gramのNが大きくなれば、長文になりやすく、同じパターンのものが生成されやすい。解決するためにはデータ量を増やす必要がある。個人的にいい意味で人工無脳っぽさが出るは単語bi-gramかtri-gramあたりだと思う。
  2. 開始・終了の扱い
    • 開始、終了にも適当な目印を割り当てると楽。[S]/私/は/旅行/に/行き/たい/。/[E]のように。単語[S]から作り始めて、単語[E]が現れたら終了。
  3. 元データの選択
    • ◯◯っぽいものを作りたい場合は◯◯っぽい文章を集めてくる。とりあえず試してみたい場合のデータ収集元としておすすめなのはTwitterやネットのニュースあたり。この辺りを元データにしたものはしゅうまい君圧縮新聞なんかが有名ですね。

プログラム

という訳で、Raspberry Pi + LCD で動くものを実装してみました(MunouChan)。文章生成に使用したのは友人のTweet。@~ から始まるリプライツイートは削除しました。各単語はMeCabで分割し単語の読みに変換(最終出力が半角カナのみなので)。単語の読みのみを考慮して(火と日は”ひ”で同一単語扱い)bi-gramの単語ペアを生成。ペアの出現回数をカウント。次に現れる単語の確率を計算したものをpickleモジュールでダンプしたものが上記URLのプログラムの状態です。

後はプログラム起動時にダンプされたデータを読み込み、開始単語から終了単語が現れるまで確率に従いランダムに単語を選択。LCDに収まる文字数ならLCDに出力し、オーバーしていたら再生成。

./probability.pklを削除またはリネームし、tweetディレクトリの中のsample.tsvを同じ形式で書き換えてやれば、任意の元データでも動くはず。ただ元データに文字数が多いものばかりを選ぶと、制限文字数をオーバしまくるので怪しい動作しそう。

実行したときの画像がこのページトップあたりにある画像です。

まとめ

シンプルな人工無脳を作るのはさほど難しくないが、人間らしい応答をさせようとすると難易度が跳ね上がる。そもそも「人間らしい」という定義すらよくわからない。

これはマルコフ連鎖を文章に適用した例だけど、状態の遷移を確率的に表現できるものに適用できるので、音楽や絵の自動生成など、他分野にもいろいろ適用できるはず。