phpでLingua::JA::Summarize

(写真と本文は関係ありません)


キーワード抽出モジュール Lingua::JA::Summarize を使うコツ (nakatani @ cybozu labs)

以前に、Summarizeをちょっと使っていたんだけど、PHPから呼びたくなったので、peclperlモジュールを使ってみました。

作業

  • 各バージョン確認
  • pecl/perl導入
  • Lingua::JA::Summarize導入
  • perlでテストコード作成
  • phpでテストコード作成
  • 重み付け部分を自分仕様に(長くなったので今度)

各バージョン確認

PHP  : PHP 5.2.3 (cli)
Perl : v5.8.8 built for i386-linux-thread-multi
mecab: mecab of 0.96

pecl::perl導入

# pecl install pecl/perl
    :
/tmp/pear/cache/perl-1.0.0/php_perl.c:1782: 
error: too few arguments to function 'zend_exception_get_default'
make: *** [php_perl.lo] エラー 1

中を見るとzend_exception_get_default()の呼び出しで、引数が設定されていないのが原因ぽいので、とりあえず適当にパッチ。

-  perl_exception_class_entry = zend_register_internal_class_ex(
           &perl_ce, zend_exception_get_default(), NULL TSRMLS_CC);
+  perl_exception_class_entry = zend_register_internal_class_ex(
           &perl_ce, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);

これでOK。

Lingua::JA::Summarize導入

mecabは元々入れてある(utf-8)ので、そのまま投入。

# perl -MCPAN -e shell
cpan> install Lingua::JA::Summarize
     (略)
Failed Test    Stat Wstat Total Fail  Failed  List of Failed
-------------------------------------------------------------------------------
t/02-keyword.t    2   512    18    2  11.11%  15-16
Failed 1/3 test scripts, 66.67% okay. 2/41 subtests failed, 95.12% okay.
make: *** [test_dynamic] エラー 2
  /usr/bin/make test -- NOT OK

そうですか。02-keyword.tをみると「認証api」あたりの文字列のテストでダメ模様。そのうちちゃんと見ようと、今はとりあえず、force installで逃げ。(mecabをutf8で入れていたからかなぁ、なんじゃろ)

perlでテストコード作成

動作確認と言うことで適当に。

use HTTP::GHTTP 'get';
use HTML::Strip;
use Lingua::JA::Summarize;
use Encode::Guess qw/ shiftjis euc-jp 7bit-jis /;
use Encode qw/ decode /;

my $h =  get('http://d.hatena.ne.jp/nemo/');

# convert to UTF-8, clean HTML or so on..

my $hs = HTML::Strip->new();
my $clean_text = $hs->parse( $h );
$hs->eof;

my $s = Lingua::JA::Summarize->new({charset => 'utf8',
                                    mecab_charset => 'utf8',
                                    default_cost => 1.5,
                                    singlechar_factor => 0.2,
                                });
$s->analyze($clean_text);
my @keywords = $s->keywords({threshold => 5);
print join("\n", @keywords) . "\n";

それなりに動作かな。

phpでテストコード作成

<?php
$url        = 'http://d.hatena.ne.jp/nemo/';

// set perl settings.
$perl = new Perl();
$perl->eval('use HTML::Strip;');
$perl->eval('use Lingua::JA::Summarize;');

// get raw data.
$data = file_get_contents($url);

// convert to UTF-8, html cleaning or so on.

$perl_hs = new Perl("HTML::Strip", "new");
$clean_text = $perl_hs->parse($data);

$perl_sm = new Perl ("Lingua::JA::Summarize", "new",
                     array("charset"           => 'utf8',
                           "mecab_charset"     => 'utf8',
                           "default_cost"      => 1.5,
                           "singlechar_factor" => 0.2));

$perl_sm->analyze($clean_text);
// set value type : '->array'
$keywords = $perl_sm->array->keywords(array("threshold" => 5,
                                            "minwords"  => 15,
                                            "maxwords"  => 15));
var_dump($keywords);
}
?>

とりあえず動いた模様。
でも、対象が日本語の文章とわかっている場合、なんかんだと重み付けを変えてみたくなったので、Summarize.pmの方もちゃんとみてみよう。