今回は、さっそくセキュリティのネタから脱線して、「いい加減に文章を要約するプログラム」を作りたいと思います。
昔から人工無能作って遊んでいたので、ちょっとした応用です。
まずは、サンプルで遊んでみましょう。
では、簡単に解説します。
材料
拙いですがソースを貼っておきます。
きっといい方法がたくさんあるはず...。
#!/usr/bin/perl use strict; use CGI; use Time::HiRes qw/gettimeofday/; my $mecab = '/usr/local/bin/mecab -O wakati'; my $echo = '/bin/echo'; # CGIモジュールで値を受け取る my $cgi = new CGI; my $sentence = $cgi->param('sentence'); $sentence =~ s/'/\\'/g; # MeCabで分かち書きする my $result; if (open(*P, "$echo '$sentence' | $mecab |")) { while(){ $result .= $_; } close(P); } my $result2; foreach (split(/\s/, $result)) { chomp; $result2 .= ' '; $result2 .= $_; $result2 .= ' '; } $result2 =~ s/\s+/ /g; $result2 =~ s/^\s+//g; $result2 =~ s/\s+$//g; $result2 =~ s/「//g; $result2 =~ s/」//g; $result2 =~ s/(//g; $result2 =~ s/)//g; $result2 =~ s/\(//g; $result2 =~ s/\)//g; # マルコフ連鎖辞書の作成 my @seeds = split(/ /, $result2 . ' EOS'); my @markov_table; for (my $i = 0; $i < $#seeds; $i++) { push @markov_table, $seeds[$i] . "\t" . $seeds[$i+1] . "\t" . $seeds[$i+2]; if ($seeds[$i+2] eq 'EOS') { last; } } # 文章の連結 my $count = 100; my ($word1, $word2, $word3) = split(/\t/, $markov_table[0]); my $new_sentence = $word1 . $word2; my $next = $word3; my $eos = 0; for (0..$count) { $next =~ s/\//\\\//g; $next =~ s/\[/\\\[/g; $next =~ s/\]/\\\]/g; $next =~ s/\(/\\\(/g; $next =~ s/\)/\\\)/g; $next =~ s/\\\\/\\\>/g; $next =~ s/\{/\\\{/g; $next =~ s/\}/\\\}/g; my @seek = grep(/^$next\t/, @markov_table); my ($hi_time, $hi_micro) = gettimeofday(); srand(time + $$ + $hi_micro); my @rand = 0..$#seek; my ($word1, $word2, $word3) = split(/\t/, $seek[rand @rand]); $new_sentence .= $word1 . $word2; if ($word2 eq '。') { $new_sentence .= "\n"; } if ($word3 eq 'EOS') { $eos = 1; last; } $next = $word3; } if ($eos == 0) { ($word1, $word2, $word3) = split(/\t/, $markov_table[$#markov_table]); $new_sentence .= $word1 . $word2; } print "Content-Type: text/plain; charset=utf-8\r\n\r\n$new_sentence";
Leave a comment