マルコフ連鎖はデータ数が少なくても比較的文章生成ができやすいとのことなので、いろいろな種類の〇〇っぽい文章を生成し比べてみました。

チャレンジ&ナレッジ最終更新日: 20180626

マルコフ連鎖を使って〇〇っぽい文章を自動生成してみた

今回はマルコフ連鎖を使って〇〇っぽい文章を自動生成します。最近はディープラーニングを用いた手法に注目が集まっていますが、マルコフ連鎖はデータ数が少なくても比較的いい感じに文章生成ができるそうなので、いろいろな種類の〇〇っぽい文章を生成し比べてみました。

マルコフ連鎖について

マルコフ連鎖はTwitterの人気botであるしゅうまい君(https://twitter.com/shuumai)やからしちゃん(https://twitter.com/karashichan)にも使われている手法です。

このマルコフ連鎖について簡単に説明します。ウィキペディアの解説には以下のように説明されています。

“各時刻において起こる状態変化(遷移または推移)に関して、マルコフ連鎖は遷移確率が過去の状態によらず、現在の状態のみによる系列である。”
マルコフ連鎖」( 2018年6月10日 (日) 10:49 UTC)『ウィキペディア日本語版』引用

つまり、マルコフ連鎖は現在の状態のみで未来の状態が決まるようなモデルです。過去N個の状態の影響を受けて未来の状態が決まるマルコフ連鎖については、N階マルコフ連鎖といいます。今回用いるのは3階マルコフ連鎖です。

例えば、「私はピーマンを食べる」「私は犬と猫を飼った」という2文を与えたとします。

このように文章を分ち書きにし、3単語ずつのブロックに分けられます。

始まりが「(文頭) 私 は」である場合、次に「は」から始まるブロックを探します。すると、「は ピーマン を」もしくは「は 犬 と」からランダムに続くブロックが決定されます。同様の作業を「(文末)」がくるまで繰り返します。この場合、「私はピーマンを飼った…」「私は犬と猫を食べる」という文章が生成されたりします。

1ブロックあたりの単語数が多くなればなるほど元の文章に近いものが生成され、少なくなればなるほどぐちゃぐちゃな文章になるようです。

〇〇っぽい文章を自動生成してみた

準備

まず、Pythonを使うのが初めてという人は記事([Windowsで始めるPython]環境構築からライブラリのインストールまで)を参考にPythonが実行できる環境を整えてください。

今回は、マルコフ連鎖のモデルを用いて文章生成を行うためのライブラリ「Markovify」と形態素解析を行うためのライブラリ「Mecab」を使うので、上記の記事を参考にしながらライブラリを追加してください。

ライブラリ追加の様子(Windows)

また、実際の文章生成は下記のGitHubのレポジトリよりソースコードを借りて行います。

https://gist.github.com/kakakaya/141838e738a2fd9667b5e4fd2b79c4c7

上記URLのソースコードを用いて文章生成

上記ページの右上の「Download ZIP」からソースファイルをダウンロードしてください。

右上の「Download ZIP」からソースファイルをダウンロード

上記URLで取得したソースコード「learn.py」の上記「ファイル名」の部分に元となるテキストデータのファイル名を設定すれば準備完了。あとは、「learn.py」をPython上で実行するだけです。

def main():
    # load text
    rampo_text = load_from_file('ファイル名')

    # split text to learnable form
    splitted_text = split_for_markovify(rampo_text)

    # learn model from text.
    text_model = markovify.NewlineText(splitted_text, state_size=3)

    # ... and generate from model.
    sentence = text_model.make_sentence()
    print(''.join(sentence.split()))    # need to concatenate space-splitted text

    # save learned data
    with open('learned_data.json', 'w') as f:
        f.write(text_model.to_json())

上図赤字部分にファイル名を設定して実行

コマンドプロントもしくはターミナルから「learn.py」を実行します。
※使用しているPythonのバージョンが3.xの場合は、実行時に「python3 learn.py」と、「3」をpythonの後につけて実行してください

ちなみに、「state_size=3」となっている部分が先ほど説明した何単語ずつのブロックで文章を分けるかを設定する箇所になります。今回は3階マルコフ連鎖なので、「3」に設定されていますが、ぜひここの数字を減らしたり増やしたりして求めている結果に最適な数字を探してみてください。

では、いろいろなテキストデータを利用してそれぞれ5つずつ〇〇っぽい文章を作成してみたいと思います。各テキストデータ源については本記事の最後に書いてあります。

白雪姫っぽい文章

そして、櫛を買うことがきまったときに、鏡かがみの前にいって、戸をあけて、きれいなしめひもを買いとりました。

その主人たちというのは、この鏡は、うそをいわないということを知ったからです。

小人こびとはじぶんたちの七つのランプを持っておいでになりました。

みんなでかわいがっていた白雪姫が、地べたの上にのせました。

白雪姫が、また生きかえったということを知っていられない。

人間失格っぽい文章

焼酎を買うお金がほしかったのですし、こんなに、それこそ冗談から駒が出た形でした。

中学校へはいって来て、とても、あの、ハイスクール・スピリットとかいうものに違いないのに、ごまかしました。

夜が明けて厳寒の夜、自分は酔って煙草を買いに行くたびに、笑って忠告するのでした。

また、事実、自分は、そんなふざけた、やにさがった気持で、「思い当るところもあったのか、思い出した、というような思いばかりが募り、自分はお道化に依って、学校中の尊敬を得そうになりました。

現にその嘲笑する人をも含めて、人間は、お互い何も相手をわからない、まるっきり間違って見ていた事さえあったほどでした。

寿限無(じゅげむ)っぽい文章

水の行く末、雲の来る末...八五郎だいたいさ、今はこれがいいと思ってもさ、偉れぇ野郎ってのは物知りなんだから。

いつまでも「このガキ」じゃ具合が悪いや...お焼香はどこだい?八五郎はぁ...ああ、そうじゃ、今思い出したが、「無期限の名前ってねぇですか?和尚「出物」ということがあるか...まぁ、そりゃそうだ。

かかぁに見せて相談しますから和尚...かみさん何言ってんだよ。

これなんか、なかなかいいぞ八五郎毛虫じゃねぇ、罰が当たるぞ。

こればっかりは本人に相談する、実家のおじいちゃん、おばあちゃんにたずねてみる...明日でやっとお七夜なんだよ、違うよ、まったく、貧乏臭いこと言わないでおくれよ。

中には文法的におかしかったり、原文のままのものもありますが、確かにそれっぽい文章を生成することができました。記事の最後にそれぞれのテキストデータのURLを載せているので、もとの文章と比較しながら見てみてください。

まとめ

以上、マルコフ連鎖を使っていろんな種類の〇〇っぽい文章を生成してみました。

上記の他に有名アーティストの歌詞でも試してみたのですが、歌詞のようなテキストの場合はもともと厳密に文法を守っていないので、今回の中で生成後の文章に一番違和感がない結果となりました。逆に、新聞記事や小説の場合、品詞の順番が狂っているとかなり違和感を感じてしまいました。なので、くだけた表現の多いLINE上での会話テキストなどで行うといい感じに文章生成ができるのではないかと思いました。

今回は3階マルコフ連鎖で行いましたが、今後はディープラーニングを使った文章生成の手法にもチャレンジしてみようと思います。ぜひ、みなさんもお気に入りの小説のテキストや身近な人とのLINEなどの会話テキストを元にマルコフ連鎖を使って文章生成をしてみてください!

参考URL

シンデレラ(青空文庫)

http://www.aozora.gr.jp/cards/001091/files/42308_17916.html

人間失格(青空文庫)

http://www.aozora.gr.jp/cards/000035/files/301_14912.html

寿限無(東西落語特選)

http://www.niji.or.jp/home/dingo/rakugo2/view.php?file=jugemu

ライタープロフィール ranran

工学部女子大生とライターをしています。卒業研究で彼氏の浮気を防ぐためにSNS上で彼氏と彼氏のフォロワーの親密度推定に挑戦中。大学院では計量言語学を専攻予定。

記事を
シェア