ちょっと興味と必要があって、人工無脳に手を出してみることになりました。まあ、人工無脳なんて今更って気もしますが、とりあえずやってみたことはどんなにしょぼくても公開する、というポリシーですので、恋するプログラム―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のおまけゲームであるサルゲッチュが好きなようです。といっても、この様に会話になることはまだ稀で、もう一度同じ質問をしたところ、「セガとサミーがくっつくわ、ファルコムは韓国からゲーム買うようになっちまったわ」とか「今日横断歩道で プーさんの格好でスクーターに乗った人を見かけたけど、その人もバツゲームかなあ。」なんて返してきました。
こんな感じで、まだまだお馬鹿ではありますが、発言データさえ豊富にあれば、簡単なコードでも十分楽しいもんですね。本当は今回作った人工無脳ボット、実際に動いているものを公開したいのですが、なにしろ発言データをすごくプライベートなチャットから採っているものですから、勘弁して頂きたいと思います。
これをベースに、今後少しづつ改良していって、より自然な文章が作れるものを目指したいと思います。