ちょっと興味と必要があって、人工無脳に手を出してみることになりました。まあ、人工無脳なんて今更って気もしますが、とりあえずやってみたことはどんなにしょぼくても公開する、というポリシーですので、恋するプログラム―Rubyでつくる人工無脳を参考にしながら、perlで実装していく過程をここに載せていきたいと思います。
といっても、この本の流れに沿っていくわけではなく、俺の思いつきのままにやっていきますので、そこんとこよろしくです。
で、今回は人工無脳のパターン辞書を、何らかのデータから自動生成することを考えてみます。
パターン辞書というのは、人工無脳への問いかけの中に、「A」という言葉がある場合に、「B」という応答を返す、というパターンが記述された辞書です。これをひとつひとつ設定していくのではなく、自動的に生成するにはどうすればいいのか、という話ですね。
これは形態素解析を利用して、以下の様な処理を行います。
perlで実装してみるとこんな感じです。形態素解析にはMeCabを利用しています。(たまたまインストールされていたので。)
#!/usr/local/bin/perl use MeCab; use strict; use Storable qw(lock_retrieve lock_store); my $text_file = $ARGV[0]; open(IN, $text_file) or die $!; my $pattern_dic_file = "pattern_dic"; my $pattern_dic = {}; eval { $pattern_dic = lock_retrieve($pattern_dic_file); }; my @arg = ($0); my $m = new MeCab::Tagger(\@arg); while(<IN>){ my $n = $m->parseToNode($_); while ($n->hasNode () != 0) { my $s = $n->getSurface; my $f = $n->getFeature; if($f =~ /名詞/ and ($f =~ /一般/ or $f =~ /固有/ or $f =~ /サ変/ or $f =~ /形容動詞語幹/)){ push(@{$pattern_dic->{$s}}, $_); } $n = $n->next (); } } lock_store($pattern_dic, $pattern_dic_file); exit;
辞書を作っただけではおもしろくないので、実際に辞書データをもとに応答してくれる簡単な人工無脳ボットbot.pmを作ってみます。
package bot; use base qw(CGI::Application); use strict; use Storable qw(lock_retrieve); my $pattern_dic_file = 'pattern_dic'; sub setup { my $self = shift; $self->mode_param('rm'); $self->start_mode('bot'); $self->run_modes ( bot => 'bot'); $self->param( pattern_dic => lock_retrieve($pattern_dic_file), ); $self->header_props( -type => 'text/html', -charset => 'euc-jp', ); $self->tmpl_path('/path/to/template'); } sub bot { my $self = shift; my $pattern_dic = $self->param('pattern_dic'); my $input = $self->query->param('input'); my $output; foreach (keys %$pattern_dic){ if($input =~ /$_/ig){ my $num = $#{$pattern_dic->{$_}}; $output = $pattern_dic->{$_}->[int(rand($num+1))]; last; } } if(!$output){ $output = "何それ?"; } my $template = $self->load_tmpl('bot.html', die_on_bad_params => 0); $template->param( input => $input, output => $output, ); return $template->output; } 1;
こいつをCGIとして呼び出すコードbot.cgiです。
#!/usr/local/bin/perl use bot; use strict; my $bot = bot->new; $bot->run;
あと、HTMLファイルbot.htmlですね。
<form method="post" action="bot.cgi"> <input type="text" name="input" size="50" id="input" value="<!-- TMPL_VAR NAME=input -->"> <input type="submit" value="submit"> </form> <!-- TMPL_VAR NAME=output --> <script type="text/javascript"> document.getElementById('input').select(); </script>
試しに、「最近おもしろいゲームある?」と聞いてみたところ、「MGS3もおまけゲームが魅力的です。」という答えが返ってきました。どうやらこの人工無脳、メタルギアソリッド3のおまけゲームであるサルゲッチュが好きなようです。といっても、この様に会話になることはまだ稀で、もう一度同じ質問をしたところ、「セガとサミーがくっつくわ、ファルコムは韓国からゲーム買うようになっちまったわ」とか「今日横断歩道で プーさんの格好でスクーターに乗った人を見かけたけど、その人もバツゲームかなあ。」なんて返してきました。
こんな感じで、まだまだお馬鹿ではありますが、発言データさえ豊富にあれば、簡単なコードでも十分楽しいもんですね。本当は今回作った人工無脳ボット、実際に動いているものを公開したいのですが、なにしろ発言データをすごくプライベートなチャットから採っているものですから、勘弁して頂きたいと思います。
これをベースに、今後少しづつ改良していって、より自然な文章が作れるものを目指したいと思います。