0
0

More than 1 year has passed since last update.

markovifyで文章生成時にKeyErrorが発生する【Python+markovify】

Posted at

経緯

markovifyを用いて自分のツイートから文章を自動生成してツイートするbotを作った。
ツイートするだけじゃ物足りないのでリプライを送る機能を追加しようとした。
リプライを送る際、送り先のツイートから単語を抜き出してその単語を起点として文章を自動生成しようとした。
ここでエラーが発生した。

内容

発生箇所のコードは以下の通り

test.py
model = markovify.Text(text, well_formed=False, state_size=3)
sentence = model.make_sentence_with_start(beginning='テスト')

エラーの内容は以下の通り

KeyError: ('___BEGIN__', '___BEGIN__', 'テスト')

これは、テストという単語を起点としてマルコフ連鎖を行い文章を自動生成する処理。
make_sentence_with_start関数の引数beginningが起点となる文字を表している。

markovifyKeyErrorというキーワードで検索するとwell_formed=Falseにするといい、という記事が多数ヒットするが、上記にある通り、それはすでにやっている。
ではなぜエラーが発生するのか。

スタックトレースを見てみるとエラーの発生している箇所は、markovifyライブラリの以下のところ。

chain.py
choices, weights = zip(*self.model[state].items())

どうやらself.modelの中に該当するKeyがないのが問題らしいです。
この中には学習したテキストが格納されるのですが、ここで疑問に思ったのが「学習したテキストに完全一致しないと文章を自動生成できないの?」ということ。
そこでmake_sentence_with_startの中を見ていると、ありました。
引数にstrictというものがあり、以下のようにコメントが書かれていました。

If strict == True, then markovify will draw its initial inspiration
only from sentences that start with the specified word/phrase.

If strict == False, then markovify will draw its initial inspiration
from any sentence containing the specified word/phrase.

英語なのでよくわからないですが、strictという名前なので厳密にみるかどうかを表しているようです。
先ほどの「キーが学習内容に完全一致しないとエラー」という話に通じる気がします。
この引数はデフォルトでTrueになっているので、ここをFalseにするとKeryErrorが発生しなくなりました!

test.py
model = markovify.Text(text, well_formed=False, state_size=3)
sentence = model.make_sentence_with_start(beginning='テスト', strict=False)

まとめ

markovifyのmake_sentence_with_startで単語を起点に文章を自動生成する際、その単語から始まる学習データがないとエラーなる。
その際には引数にstrict=Falseを指定すると解決する。

参考資料

0
0
0

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
0
0