Kotz’i’jに恋して16

ここ数日間取り組んできたマルコフ連鎖による文書生成アルゴリズムをようやくTzijonikプログラムに取り入れた。重要な更新なのでバージョンを2にした。 慣れないRubyで色々とメソッドを書いたので、ttr_readerとか今まで曖昧だった部分も理解できる様になった。

コードはやはりDictionary.rbとResponder.rbへの追加修正が主。Dictionary.rbにはマルコフ連鎖関連の下記コードを追加:

 

それからResponder.rbにはマルコフ連鎖で回答を作成するクラスを追加:

 

プログラムを起動してみる。

5割の確率でマルコフ連鎖で生成された文章で返事をするようにしている。ただ、入力した文章からキーワードを拾っている訳ではないので、意味のある会話にはなりにくい。でもKotzi’ijがある程度長い返答を出来るようにはなった。

今後はキーワードを拾う仕様にすることと、文法を考慮した上でマルコフ連鎖アルゴリズムに修正を加える必要がある。ただ、そうするとマルコフ連鎖では無くなってしまうけど。

 

 

Kotz’i’jに恋して15:マルコフ連鎖(マヤ・キチェ語その2)

昨日載せたコードを少し修正してみた。辞書ファイルへの書き込みも加えた。

MarkovChain.rb

 

MarkovChainTestKiche.rb

 

辞書ファイルの読み込みはこの様に:

 

単純だけど必要なことは全てこれらのコードで出来ている。しかし、コードを見ると統計分析を行っているような書き方になっている。癖が抜けないなぁと思う。

 

 

Kotz’i’jに恋して14:マルコフ連鎖(マヤ・キチェ語)

 

 

キチェ語のテキストを何点か用意したのでマルコフ連鎖を用いたキチェ語の文章作成を試みた。

ここでは4点紹介する。まずはグアテマラ教育省の絵本数冊の文章をテキストとして採り入れた場合。

 

次にマイクロソフトのサービス・アグリーメント

 

マイクロソフト関連の単語が見られる。次に聖書の一部分(フィリピ人への手紙)から。

 

スペル等が現在一般的に用いられているキチェ語のものと異なる。最後にキチェ族の聖典ポポル・ブフの一部から。

コードは下記の通り。

 

MarkovChain.rb

 

MarkovChain.rb

Rubyにおける文字列分割方法:split & scan

前回Rubyでマルコフ連鎖を用いた文章作成アルゴリズムを書いてみたけど、その際に文章の分割方法に少し苦労したので備忘録として。

英語やスペイン語みたいに単語と単語が空白で分かれている場合のケースを想定。単純に単語毎に分割したい場合は.split(sentence.splitみたいに)を使えばいいけど、今回は一文毎に分割する方法について書いてみる。

例としてフランツ・カフカの「変身(Metamorphosis)」の第二段落を使用(?も含んでいるため)。文章毎に分割するということなので区切り文字としてピリオドとクエスチョンマークを採用。

最初は単純にsplitを使ってこういう風に書いてみた。

結果はこうなる。

しっかり分けられているけど、区切り文字が取り除かれてしまっているのでこれでは使えない。次に試したのが同じsplitメソッドだけど少し修正を加えたもの。具体的にはブラケットの丸括弧(parenthesis)で囲う。

今回はこういう風に出力された。

今回は区切り文字もしっかり含まれているけれど、区切り文字自体も一つの独立した部分として戻された。マルコフ連鎖アルゴリズムでは区切り文字は勿論文章の単語にくっつく形でなければならないのでこれも不十分。

で色々調べた結果、splitではなくscanメソッドを使えることに気付いた。試行錯誤した後、こう書いてみた。

簡単に説明するとブラケット([^])内の文字を除いた文字を全てスキャンし、その省いた文字を区切り文字として利用する仕様。こうすると下記の様な結果を得られる。

取り敢えず、これで必要な結果は得られた。なお、この方法だとどうしても二文目以降の文頭に空白が出来てしまう。これはstripメソッドで解決。

空白がしっかり取り除かれている。入力されたテキストを文に分割することが出来たのでマルコフ連鎖による文章作成の準備が整った!

一応、参考まで今回のコードはこんな感じ。

Kotz’i’jに恋して13:マルコフ連鎖

前回述べた通り、マルコフ連鎖による文章作成のコードを書いてみた。辞書ファイルの保存を言語に関係無く容易に出来る様にするため、統計分析で用いることの多い二次元配列にした。

辞書のサイズが今後増えることを考えればツリー構造にすべきだろうけど、取り敢えず今は単純な2次元配列。

もう出し尽くされた感のあるテーマだけどコードは下の通り。

物凄く単純。これはキチェ語に限らず単語間を空白で話す言語であれば何語にも使える。例としてJuan RulfoのNo oyes ladrar a los perrosを辞書に取り入れてみた。出力結果はこんな感じ。

英語で書かれた「老人と海」を採り入れた場合の出力例。

英語とスペイン語で色んな文章を採り入れて試した結果、ある程度しっかりとしたボット・プログラム、つまり回答をマルコフ連鎖は使い物にならないということ。ベースとしてはマルコフ連鎖は使えるけどある程度文法を考慮した仕様にしたり、キーワードで返答を作成するのであれば、文章の構築方法も頭から書き始める以外の選択肢も必要。それが分かっただけでも収穫かな。

取り敢えず、このコードをTzijonikに取り入れてから改良していこうと思う。