【英語編】マルコフ連鎖を使った文章生成について | 自然言語処理
マルコフ連鎖とは、マルコフ過程のうち離散的なものであり、「現在の状態のみで未来の状態が決まる」というモデルのことです。
今回は、そんなマルコフ連鎖の特性を使って、類似文章の作成をしてみたいと思います。
使うライブラリは、MeCabとMarcovifyです。pythonでコードを書いております。
マルコフ連鎖による類似文章の自動生成
日本語の文章の自動生成には、二つの技術が必要です。
一つは、形態素解析です。
形態素解析とは、テキストを形態素と呼ばれる単位に分け、各形態素に対して品詞を付与する処理のことです。

上のコンテンツでは、形態素解析を詳しく解説しております。ぜひご覧ください。
二つ目は、マルコフ連鎖です。
マルコフ連鎖の理論に関しては、別のコンテンツで扱うことにしますが、「確率仮定の1種類であるマルコフ過程のうち、各時刻において起こる状態変化に関して遷移確率が過去の状態によらず、現在の状態のみで未来の状態が決まるモデル」のことです。
マルコフ連鎖では、文章の流れを作ります。形態素解析で分割した単語を、再構築していくことです。

単語ごとにバラバラにした後に、文章が作り直されていることがわかります。
当然ですが、意味が通らない場合もありますが、学習した文章の「癖」を反映することができるので、好きな作家の文章を入力データに入れると、それっぽい文章が自動生成できるかもしれません。
これは、1ブロックに1つの単語が入っているので、1階マルコフ連鎖と呼びます。
k階マルコフ連鎖
k階マルコフ連鎖というのは、1つのブロックに形態素をk個入れてマルコフ連鎖を行うということです。
当然ですが、kが1に近いほどオリジナリティのある文章を作れますが、意味が通らないことが大半です。
一方で、kが大きいほど入力した文章とさほど変わらない文章が生成されますが、当然意味が通じる場合が多いです。
例 2階マルコフ連鎖:(私 は) (は 統計学)というように形態素2個分ごと動かす
CODE
pip install markovify
まずは、マルコフ連鎖に使うライブラリ markovify をインストールしましょう。
今回は、英語でマルコフ連鎖をやってみます。
驚くべきことに英語は単語ごとに分かちがきされているので、形態素解析をするまでもありません。
まずは、長文のテキストファイルを作りましょう。
今回は、赤毛のアン(anne of green gables)の冒頭をテキストデータにしてみました。少し載せておきます。
MRS. Rachel Lynde lived just where the Avonlea main road dipped down into a little hollow, fringed with alders and ladies’ eardrops and traversed by a brook that had its source away back in the woods of the old Cuthbert place; it was reputed to be an intricate, headlong brook in its earlier course through those woods, with dark secrets of pool and cascade; but by the time it reached Lynde’s Hollow it was a quiet, well-conducted little stream, for not even a brook could run past Mrs. Rachel Lynde’s door without due regard for decency and decorum; it probably was conscious that Mrs. Rachel was sitting at her window, keeping a sharp eye on everything that passed, from brooks and children up, and that if she noticed anything odd or out of place she would never rest until she had ferreted out the whys and wherefores thereof. ‥
#ライブラリのインポート
import markovify
#テキストにfile1という変数を割り付ける
with open("anne.txt") as file1:
text = file1.read()
#マルコフ連鎖ライブラリを使用してモデルを構築します。
text_model = markovify.Text(text)
#200文字以内の文章を5回生成します
for i in range(5):
print(text_model.make_short_sentence(200))
text_modelのmake_short_sentenceというメソッドを使っております。
こんな出力結果5つが出ました。
「ん??」って感じですね。文法がめちゃくちゃで読めないということにはならないようですが、長文になればなるほどやはり意味はよくわかりません。
We mean to give in. (管理人訳:私たちは諦めるつもりです) The sun was coming in at the kitchen door and stepped in when bidden to do so. (管理人訳:太陽がキッチンの勝手口から入ってきて、どうぞと言われてその通りに足を踏み入れた) It was unsupposable that Marilla was making fun of her, but Mrs. Rachel would have been cheerful if it had been done without her advice being asked, and must perforce be disapproved. (管理人訳:マリラが彼女をからかったということは考えられないが、レイチェル夫人は自分の助言を求められないで行われたのなら嬉しかったであっただろうし、強制的に棄却しなければならないのだろう。) Her cousin lives there and Mrs. Rachel, in spite of—or perhaps because of—their dissimilarity. (管理人訳:彼女の従兄弟はそこに住んでいる。そしてレイチェル夫人はその異質さにもかかわらず、いやひょっとするとその異質さ故に) Mrs. Rachel, before she had received a severe mental jolt. (管理人訳:酷い精神的苦痛を受ける前のレイチェル夫人)
日本語のマルコフ連鎖もいずれ扱います。
自然言語処理について興味が出た方は、自然言語処理をご覧ください。