今回は、さっそくセキュリティのネタから脱線して、「いい加減に文章を要約するプログラム」を作りたいと思います。
昔から人工無能作って遊んでいたので、ちょっとした応用です。
まずは、サンプルで遊んでみましょう。
では、簡単に解説します。
材料
拙いですがソースを貼っておきます。
きっといい方法がたくさんあるはず...。
#!/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