LoginSignup
68
72

More than 5 years have passed since last update.

markovifyで日本語の文章を学習して、マルコフ連鎖により文章生成を行う

Last updated at Posted at 2018-03-15

TL; DR

mecab 等を利用してサンプルとなる文章を分かち書きしたのちに、区切りを改行にして markovify.NewlineText に渡すことで日本語の文章からモデルが作成できる。英語の場合と同様、 make_sentence を利用してマルコフ連鎖の結果を得られる。本稿では日本語文章を学習させて文章生成をした。

目的

現在、趣味でしゅうまい君からしちゃんのようにマルコフ連鎖を利用して文章生成をするbotを作成している。

マルコフ連鎖の辞書作成と連鎖を行うコードを書いた経験はあるが、今回は既存のライブラリを利用してみようと考えた。そこで、GitHubでスター数が多い(2018/03/14時点で:star:1352) jsvine/markovify を利用し、日本語文章をサンプルとしてモデルを作成しつつ文章生成を行うことを目標とした。
jsvine/markovify: A simple, extensible Markov chain generator.

markovify

markovifyとは、マルコフ連鎖のモデル生成と文章生成のためのライブラリである。

マルコフ連鎖 - Wikipedia

シンプルでありながら高機能なライブラリだが、Qiitaにはこれを取り扱う記事が存在しなかったため、この記事を書いて投稿した。

動作例

様子見として、PEP 20 -- The Zen of Pythonを学習させて、文章を生成させた。

ソースコード: https://gist.github.com/kakakaya/14d109a0398d04b654ab1d6d53580e8d

zen.py
# learn model from text.
text_model = markovify.Text(zen_of_python)
# ... and generate from model.
for _ in range(5):
    print(text_model.make_sentence())
output.txt
Sparse is better than implicit.
Now is better than implicit.
If the implementation is easy to explain, it's a bad idea.
Explicit is better than nested.
Explicit is better than *right* now.

ランダムに生成しているため当然内容は無意味だが、The Zen of Pythonは文章の形が整っているからか、文章としては自然であるという面白い結果が得られた。

実験:江戸川乱歩を学習して文章を生成する

概要

markovifyの使い方を確認したので、より本来の目的に近付けるため日本語の文章を学習、生成させる。そこで、今回は学習データとして青空文庫にて公開されている江戸川乱歩の作品を利用してみる。但し、markovifyでは英文章、あるいはそれに類するもののみの読み込みをサポートしており、日本語の文章は自分で最小単位ごとに分割する必要がある。そこで、mecabを利用して分かち書きを行う。

準備

全部パッケージ管理システムなり pip なりで簡単に入るので説明は割愛します。

  • Python
    • https://www.python.org
    • 3.7.0リリース予定日まであと3ヶ月ですね。新機能も楽しみです。
  • mecab
  • mecab-python3
  • markovify
  • 青空文庫
    • https://github.com/aozorabunko/aozorabunko
    • 著作権が消滅した、あるいは著者が許諾した作品を公開する電子図書館。
    • GitHubで全文が公開されてるのは今回初めて知った。
    • しかし、git cloneで無限に時間が掛かってしまったので、本家青空文庫サイトから手作業込みでクローリングする羽目になった。

実装

読み込んで学習させるだけ。だが、いくつかのハマりポイントがあった。
ソースコード: https://gist.github.com/kakakaya/141838e738a2fd9667b5e4fd2b79c4c7

  • MeCabがエラーを出さずに死亡する
    • 改行を含む文章だとダメらしい(それはそう)
    • 記号によっても死ぬことがある?
  • Python側プロセスが死んでいてもMeCabが動いていることがある
    • この場合エラーが出る?
  • MeCabが分割した形態素を取り出そうとしたら UnicodeDecodeError が発生することがある
    • 原因不明。try-catchで対処。
  • markovifyは括弧でエラーを起こす

実験の結果

次のような文章が生成された。

  • 小林君は、大きなアーム・チェアに腰をすえて、フラフラと歩いている。
    • 歩いているのか、座っているのか。
  • 」明智がびっくりして、ぴったり、かべにからだをくくりつけてあったことである。
    • 壁に体を括り付けるのは難しそうだ。
  • 黒山の見物人には、人のいないようです。
    • どっちやねん。

100個生成した結果はこちら
https://gist.github.com/kakakaya/1daeb8e5d9a9f8f48a78af7aa5c8e568

まとめと感想

jsvine/markovify というライブラリを使って日本語の文章を学習させ、文章生成を行った。シンプルながら使いやすいことが分かったため、先述したbot作成にも活用するつもりである。

ところで円城塔のエピローグという小説が文章の自動生成をテーマにしており、面白いのでおすすめです(布教)。

68
72
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
68
72