マルコフ連鎖の生成文をファイルに保存

スポンサーリンク

環境
Windows SP1
Python 3.4.4
Janome 0.3.6

文章を自動生成したくてマルコフ連鎖を使ってみました。コードは知識のサラダボウルさんのマルコフ連鎖による文章生成のほとんどの部分を借用させてもらいました。##は追加で記入しました。
違うのはファイルopenの所に ,encoding=”utf-8″ を付け加えた事と括弧削除を付け加えた事と最後の方で with open~ というマルコフ連鎖で生成した文章をファイルに保存するコードを2行付け加えただけです。最初テキスト名を

dics/markov.txt

にしたら失敗しました。

dics_markov.txt

にしたら自動でファイルが生成されました。
プレフィックス(連続する2つか3つの単語)を格納する変数はw1, w2, w3の3つでも成功しましたが、コードを改変していくと文章を何も生成しなくなったので2つの方が改変しやすいのかもしれません。
形態素解析はcmd.exeでJanomeを以下でインストールしました。

pip install janome

以下のコードをデスクトップ上の任意のフォルダ(仮にmarkov_sentenceフォルダとします)内に作った、txtファイルにUTF-8の文字コードで保存します。また、同じフォルダ内に例えば、青空文庫からダウンロードした「夜明け前」 第一部上をUTF-8の文字コードでtestという名前のtest.txtで保存します。

# -*- coding: utf-8 -*-
 
import random
from janome.tokenizer import Tokenizer
  
# Janomeを使用してテキストデータを単語に分割する
def wakati(text):
    text = text.replace('\n','') #改行を削除
    text = text.replace('\r','') #スペースを削除
    text = text.replace('「','') ##開き括弧を削除
    text = text.replace('」','') ##閉じ括弧を削除
    t = Tokenizer()
    result =t.tokenize(text, wakati=True)
    return result
 
#デフォルトの文の数は5
def generate_text(num_sentence=5):
    filename = "test.txt"
    src = open(filename, "r",encoding="utf-8").read()
    wordlist = wakati(src)
##    src = open(filename, "r").read() に,encoding="utf-8"を追加
  
    #マルコフ連鎖用のテーブルを作成
    markov = {}
    w1 = ""
    w2 = ""
    for word in wordlist:
        if w1 and w2:
            if (w1, w2) not in markov:
                markov[(w1, w2)] = []
            markov[(w1, w2)].append(word)
        w1, w2 = w2, word
  
    #文章の自動生成
    count_kuten = 0 #句点「。」の数
    num_sentence= num_sentence
    sentence = ""
    w1, w2  = random.choice(list(markov.keys()))
    while count_kuten < num_sentence:
        tmp = random.choice(markov[(w1, w2)])
        sentence += tmp
        if(tmp=='。'):
            count_kuten += 1
            sentence += '\n' #1文ごとに改行
        w1, w2 = w2, tmp
##        sentence += tmp # sentenceにtmpを加える
##            count_kuten += 1 # count_kutenの数を1増やす

    with open('dics_markov.txt', 'a', encoding = 'utf_8') as f:
             f.writelines(sentence)
##     with open('dics_markov.txt', 'a', encoding = 'utf_8') as f:  # dics_markov.txtを末尾追加で書き込み用で開く
##              f.writelines(sentence) # fにsentenceを書き込む
     
    print(sentence)
     
if __name__ == "__main__":
    generate_text()
## if __name__ == "__main__":  # 外部からインポートした時に自動で実行しないようにする

この.txtファイルを.pyに変える(仮にmarkov_sentence.pyとします)
そして、(左下)スタート→(左下)検索でcmdと入力→表示されるcmd.exeをクリック

cd C:/Users/(ユーザー名)/Desktop/markov_sentence

で.pyが置いてあるmarkov_sentenceフォルダに移動します。そして

python markov_sentence.py

でコードを実行します。1分くらい待つとコマンド画面にマルコフ連鎖で生成された文章が表示されます。
また、markov_sentenceフォルダには生成された文章が書かれたdics_markov.txtというファイルが自動で生成されます。

(生成された文章の例)

大石へ見通しということから家事の世話まで、彼はそれほどの憎まれ者も、交通輸送の困難をしのいでいると聞くように中津川を伝わって来るともなく、時おりは長歌をも持つ人である。
幕府内の庭掃除そうじにはかなわぬことを言った昔の人たちが一層半蔵の前に置いて、それほど実力をも感じのするほど古い太い柱のそばへ来て、米の売買だ。
燈火あかりが街道に目をさまさせまいとしたと同じ道を伝えたころは、谷間からだんだん空の明るくなることも起こって来てすすめる妻に言いつけて置いた。
その村民が五木を伐採したり、国学をやる人は右を見た。
彼は美濃みのの国境くにざかいにあたる一里塚づかに近い。

    while count_kuten < num_sentence:
(略)
        w1, w2 = w2, tmp
    with open('dics_markov.txt', 'a', encoding = 'utf_8') as f:
             f.writelines(sentence)

記録コードを以下のようにwhile文の中に入れると、マルコフ連鎖による文章生成過程が記録されるようです。

    while count_kuten < num_sentence:
(略)
        w1, w2 = w2, tmp
        with open('dics_markov.txt', 'a', encoding = 'utf_8') as f:
                 f.writelines(sentence)

プログラミングはよくわからないのでreplaceのようなあらかじめ定義されている関数と
count_kutenのようなコードを書いた人が名づけた変数と見分けるのが難しかったです。
なのでファイルへの書き込むコードの挿入位置や書き方がふさわしいかわかりません。