myfinderの技術や周辺的活動のblog

2008年12月27日土曜日

人工無脳(chatbot)を実装してみる -第五回-

第五回は、第四回でやったことの逆をやります。
つまり、キーワード以外の部分をテンプレートとして学習させ、ユーザの発言に応じてテンプレートから回答するというものです。

これを実現するには、ユーザの入力を例によって形態素解析して、名詞部分を特定することが必要です。
この処理はすでに前回実装している、下記のようなものでいいかなと。

def analyze(text)
# MeCabのparseメソッドで解析
parsed_text = parse(text)
parsed_data = []
parsed_text.split(/\n/).map do |line|
parsed_data.push(line.split(/\t/))
end
return parsed_data
end

このメソッドで、例えば「俺ら東京さ行くだ」を解析すると下記のような結果が得られます。

[
["俺", "名詞-代名詞-一般"]
["ら", "名詞-接尾-一般"]
["東京", "名詞-固有名詞-地域-一般"]
["さ", "名詞-接尾-特殊"]
["行く", "動詞-自立"]
["だ", "助動詞"]
]

いい感じのデータ構造です、これならeachで簡単に名詞を置き換えることができます。

parts.each do |word, part|
if @morph.keyword?(part)
word = '%word%'
end
template += word
end

keyword?は前回実装した、下記のようなメソッドです。

def keyword?(part)
return /名詞-(一般|固有名詞|サ変接続|形容動詞語幹)/ =~ part
end

「名詞」でかつ他の品詞分類があるもので「一般」「固有名詞」「サ変接続」「形容動詞語幹」がキーワードとして判定されます。
なのでこの場合「俺ら」と「東京」が「%word%」に置換された文字列が得られるのです。

ここで得られた文字列をテンプレートとしてファイルやDBに保存して、ユーザの入力と突き合わせ、名詞の数が同じものだった場合に置き換えて出力するなどすれば、回答に利用できます。
ただ、名詞を抜いただけのテンプレートなので、場合によってはおかしな返答を返してしまうこともあります。

例えば
「私のお墓の前で泣かないでください」
をこの処理に掛けると
「%word%のお%word%の前で泣かないでください」
というテンプレートが出来るのですが、
ユーザが
「貴方の名前は?」
という入力を与え、このテンプレートとマッチしてしまうと
「貴方のお名前の前で泣かないでください」
という、意味不明な回答が出てきたりしてしまいます。

なので、この手のテンプレートはメンテナンスが必要だったりします。
が、これで、今までのユーザの入力をオウム返しするだけのものから、名詞だけとはいえ自分でフレーズを作って返す機能ができたわけです。

おわり。

0 件のコメント: