work.log

元エンジニアの備忘録的ブログ

PerlのString::Trigramモジュールで文章の類似度を計測する

投稿:2015-01-13 18:05  更新:

Perl の String::Trigram モジュールのメモです。

文章Aと文章Bはどれ位似ているかの類似度を計算する「N-gram」を簡単に使えるモジュールです。

今回はテストなのでユーザー領域にこんな感じでインストールしてみた。

$ mkdir ~/perl
$ cd perl
$ wget http://search.cpan.org/CPAN/authors/id/T/TA/TAREKA/String-Trigram-0.12.tar.gz
$ tar xfz String-Trigram-0.12.tar.gz
$ cd String-Trigram-0.12
$ perl Makefile.PL PREFIX=~/perl
$ make
$ make test
$ make install
$ cd .. ; rm -rf String-Trigram-0.12*

インストールが終わったらこんなスクリプトを書いてテストしてみる。

#!/usr/bin/perl

use strict;
use warnings;

use lib '/home/user/perl/lib/perl5/site_perl/5.18';
use String::Trigram;

    my $str1 = '今は真冬なので外がとても寒いです。';
    my $str2 = '冬の外はとても寒いです。';
    my $str3 = '今は真夏なのに外がとても寒いです。';

    my $score1 = String::Trigram::compare($str1, $str2);
    my $score2 = String::Trigram::compare($str1, $str3);

    print "score (str1 <=> str2): $score1\n"; 
    print "score (str1 <=> str3): $score2\n";

exit;

$str1 をベースに $str2, $str3 がどれ位似ているかを計算します。

実行結果はこんな感じに。

score (str1 <=> str2): 0.542372881355932
score (str1 <=> str3): 0.766666666666667

1 に近づくほど類似しているという結果になります。

文章の意味を加味している訳ではないので $str1 と $str3 の方が似ているという判定に。

N-gram は指定した文字数に分割して比較するアルゴリズムになっているようで、今回は Trigram なので3文字。

$str1 だとこんな感じになる。

今は真
は真冬
真冬な
冬なの
なので
ので外
で外が
外がと
がとて
とても
ても寒
も寒い
寒いで
いです
です。

この調子で $st2, $str3 も分割して単語単位で比較していく模様。

で、今回これを調べたのは、ある特定の記事の「特徴」を抽出してそれに類似した情報を表示するといったようなレコメンドシステムっぽいのを作ろうと思ったのがきっかけ。

ただ、N-gram は文章の中身 (意味) までは加味しないのでこれだとちょっと違ったかなという感じ。

文章はあらかじめ形態素解析をして名詞単位で分類済み。この名詞単位で比べたかった。

下記の参考情報を見ると「コサイン類似度」ってのを使うと良いっぽい。

今度やってみる。