文章間の共通点を集めて、日本語の文章から単語抽出。
diffで得た共通点とその出現数を元にして、多数の文章に現れる文字列ほど単語として使える文字列ということにしてみる。
- テキストを2つ用意
- diff
- 共通点を記録
- 同じ共通点が見つかるたびに出現数+1
- 出現数を参考に共通点を評価
- 評価の高い共通点を「単語」と称して出力
コード(Perl)
use utf8; use strict; use feature qw/switch/; use Encode; use Algorithm::Diff qw/sdiff/; my @in = qw{ ※ここに文章を書く ここに文章を書く ここに文章を書く ここに文章を書く }; my %worddict; my %sentencedict; my $c; foreach (@in){ print STDERR "\r", ++$c, '/'.@in; learn($_); } print STDERR " done.\n\n"; { # 評価 my %score; foreach my $k (keys %worddict){ $score{$k} = ($worddict{$k} ** 2) * (length($k) - 1); } # 出力 my $c; print "#: word, score\n"; foreach my $k (sort { $score{$b} <=> $score{$a} } keys %score){ print ++$c, ': ', encode('shiftjis', $k), ", $score{$k}\n"; } } sub learn { my($sentence) = @_; die unless not ref $sentence; foreach my $sentence2 (keys %sentencedict){ ## diff my $sdiff = sdiff([split //, $sentence], [split //, $sentence2]); my @unmodified; my $store = sub { $worddict{join '', @unmodified}++; @unmodified = (); }; foreach my $elem (@$sdiff){ given ($elem->[0]){ when ('u'){ die unless $elem->[1] eq $elem->[2]; push @unmodified, $elem->[1]; } default { $store->() if (@unmodified); } } } $store->() if (@unmodified); } $sentencedict{$sentence} = 0; }
結果
このコードに手近にあった文章リストをかけると…
#: word, score 1: 忍たま, 1782272 2: 中心, 866761 3: 忍たま乱太郎, 108045 4: す。, 35721 5: 五年生, 30258 6: です。, 20808 7: 年生, 13456 8: サークル, 8748 9: ます。, 8712 10: です, 8100 11: たま, 7744 12: たま乱太郎, 7056 13: ほのぼの, 6348 14: 乱太郎, 4802 15: 五年, 3136 16: 落第忍者乱太郎, 2646 17: ギャグ, 2450 18: 三郎, 2116 19: 中心で, 2048 20: サークルです。, 1944 21: 中心です, 1728 22: 中心に, 1682 23: 鉢屋三郎×不破雷蔵, 1568 24: ます, 1521 25: 忍たま , 1323 26: 漫画, 1296 27: 受け, 1296 28: 中心です。, 1156 29: 落乱, 729 30: 中心。, 648 31: オールキャラ, 605 32: 年生中心, 588 33: 竹谷, 576 34: 六年, 529 35: 食満, 441 36: サークルです, 320 37: 鉢雷, 289 38: 善法寺伊作, 256 39: 五年生中心, 196 40: ています。, 196 41: タソガレドキ, 180 42: 小説, 169 43: ています, 147 44: して, 144 45: サークルで, 144 46: 生中心, 128 47: もあり, 128 48: 中心サークル, 125 49: を中心に, 108 50: 新刊, 100 51: など, 100 52: 活動しています, 96 53: こへ, 81 54: ×食満留三郎, 80 55: ります。, 75 ……(続く)……
…などといった出力になる。
全くの無駄ではないけど、もう一つ別の方法が必要みたい。
それとデータ量が区切り位置の精度を上げるので、速さは必要か。