裏で形態素解析器を使い長い文をそのままキーとしてWeb検索する
2006-09-17-1
[YahooHacks][NLP]
今回の YahooHacks は、
長い文を検索キーとしてWeb検索をするというハックです。
一年前の検索会議[2005-09-30-3]で紹介しましたが、
今回ゼロから書き直しました。
サンプルコードが長くなってしまってすいません…。
(一時的にデモを置いておきます。そのうち消えます。ご了承ください。
http://chalow.net/misc/yahoohacks-samp/hack_sentence.cgi
検索例:SEOの10ステップと...←うろ覚えタイトル
)
■■■長い文をそのまま検索キーとして Web 検索する
どこかからコピペしてきた長い文をそのまま Yahoo! で検索しても
ヒットしないことが多いです。
そういう場合でも何かしら検索結果を出すことを目指し、
文の中から名詞だけ取り出してAND 検索 (スペースで区切って検索) する、
というハックを紹介します。
■基本ロジック
まず入力された文をそのまま検索キーとして Yahoo! API で検索します(1)。
検索結果がゼロだったら、文を形態素解析し、名詞だけ取り出し(2)、
それらを並べて再度 Yahoo! API で検索します(3)。
例:
(1) 「著者名の一部から本を検索できる」で検索→見つからない。
(2) 形態素解析&名詞抽出→「著者」「名」「一部」「本」「検索」
(3) 「著者 名 一部 本 検索」で再度検索。
■コード
形態素解析には工藤拓さんの MeCab を使っています。
MeCab はオープンソースの形態素解析器で、Perl モジュールもあります。
MeCab のページ(http://mecab.sourceforge.jp/)から、
mecab, mecab-ipadic, mecab-perl の
3つの最新のパッケージを取得し、インストールします。
以下、前述のロジックで長文検索を行う CGI のコードです。
yapi_search() は与えられたキーで Y!API で Web 検索する関数です。
検索結果をハッシュの配列のリファレンスとして返します。
ハッシュのキーは、Title, Url, Summary など XML のエントリと同じです。
get_term_frequency() は Mecab で形態素解析し、名詞だけを取り出し、
ハッシュに格納する関数です。ハッシュのリファレンスを返します。
Mecab の Perl モジュールで扱う日本語文字コードは EUC-JP なので、
UTF-8 との間の変換を行っています。
■Hack の実行
そのままWebサーバに置けば動作するはずです。
検索実行例を下図に示します。

参考ページ:
- Yahoo!デベロッパーネットワーク
http://developer.yahoo.co.jp/
- MeCab
http://mecab.sourceforge.jp/
- Taku Kudo (工藤拓、MeCabの作者)
http://chasen.org/~taku/
関連書籍:
- Yahoo! Hacks
長い文を検索キーとしてWeb検索をするというハックです。
一年前の検索会議[2005-09-30-3]で紹介しましたが、
今回ゼロから書き直しました。
サンプルコードが長くなってしまってすいません…。
(一時的にデモを置いておきます。そのうち消えます。ご了承ください。
http://chalow.net/misc/yahoohacks-samp/hack_sentence.cgi
検索例:SEOの10ステップと...←うろ覚えタイトル
)
使用している Web API の提供が終了となったため、現在動作しません。ご了承ください。
■■■長い文をそのまま検索キーとして Web 検索する
どこかからコピペしてきた長い文をそのまま Yahoo! で検索しても
ヒットしないことが多いです。
そういう場合でも何かしら検索結果を出すことを目指し、
文の中から名詞だけ取り出してAND 検索 (スペースで区切って検索) する、
というハックを紹介します。
■基本ロジック
まず入力された文をそのまま検索キーとして Yahoo! API で検索します(1)。
検索結果がゼロだったら、文を形態素解析し、名詞だけ取り出し(2)、
それらを並べて再度 Yahoo! API で検索します(3)。
例:
(1) 「著者名の一部から本を検索できる」で検索→見つからない。
(2) 形態素解析&名詞抽出→「著者」「名」「一部」「本」「検索」
(3) 「著者 名 一部 本 検索」で再度検索。
■コード
形態素解析には工藤拓さんの MeCab を使っています。
MeCab はオープンソースの形態素解析器で、Perl モジュールもあります。
MeCab のページ(http://mecab.sourceforge.jp/)から、
mecab, mecab-ipadic, mecab-perl の
3つの最新のパッケージを取得し、インストールします。
以下、前述のロジックで長文検索を行う CGI のコードです。
#!/usr/bin/perl -T
use strict;
use warnings;
use Encode;
use CGI;
use LWP::Simple;
use XML::Simple;
use HTML::Template;
use MeCab;
my $q = new CGI;
my $key = $q->param('key') || "";
my $new_key;
my $r = yapi_search({key => $key});
if (@$r == 0) {
my $word = get_term_frequency($key);
my @keys = sort {$word->{$b} <=> $word->{$a}} keys %$word;
if (@keys > 0) {
$new_key = join(" ", @keys);
$r = yapi_search({key => $new_key});
}
}
my $template = join("", <DATA>);
my $t = HTML::Template->new(scalarref => \$template,
associate => $q,
die_on_bad_params => 0);
$t->param(results => $r);
$t->param(new_key => $new_key);
print $q->header(-charset => 'UTF-8'), $t->output();
sub yapi_search {
my ($args_ref) = @_;
my $key = $args_ref->{key};
my $num = $args_ref->{num} || 10;
return [] unless $key;
$key =~ s/([^0-9A-Za-z_])/'%'.unpack('H2',$1)/ge;
$key =~ s/ /+/g;
my $url = "http://search.yahooapis.jp/WebSearchService/V1/"
."webSearch?appid=YahooDemo&query=$key&results=$num";
my $yahoo_response = get($url);
my $xmlsimple = XML::Simple->new();
my $yahoo_xml = $xmlsimple->XMLin($yahoo_response);
if (ref($yahoo_xml->{Result}) eq "ARRAY") { # found: many
return $yahoo_xml->{Result};
} elsif (ref($yahoo_xml->{Result}) eq "HASH") { # found: 1
return [$yahoo_xml->{Result}];
}
return []; # not found
}
sub get_term_frequency {
my ($str) = @_;
Encode::from_to($str, 'utf-8', 'euc-jp');
my $m = new MeCab::Tagger("");
my $n = $m->parseToNode($str);
my %word;
while ($n = $n->{next}) {
if ($n->{feature} =~ /^\xcc\xbe\xbb\xec/) { # 名詞
my $w = $n->{surface};
Encode::from_to($w, 'euc-jp', 'utf-8');
$word{$w}++;
}
}
return \%word;
}
__DATA__
<html lang="ja">
<head>
<title>Sentence Search</title>
</head>
<body>
<h1>Sentence Search</h1>
<form method="get">
<input type="text" name="key" value="<TMPL_VAR name=key>" size="80">
<input type="submit" value="search">
</form>
<TMPL_IF name=new_key>
<p>Not Found: <TMPL_VAR name=key></p>
<p>New Search Key: <TMPL_VAR name=new_key></p>
</TMPL_IF>
<h2>Search Results</h2>
<TMPL_LOOP name=results>
<h3><a href="<TMPL_VAR name=Url>"><TMPL_VAR name=Title></a></h3>
<p><TMPL_VAR name=Summary></p>
</TMPL_LOOP>
</body>
</html>
yapi_search() は与えられたキーで Y!API で Web 検索する関数です。
検索結果をハッシュの配列のリファレンスとして返します。
ハッシュのキーは、Title, Url, Summary など XML のエントリと同じです。
get_term_frequency() は Mecab で形態素解析し、名詞だけを取り出し、
ハッシュに格納する関数です。ハッシュのリファレンスを返します。
Mecab の Perl モジュールで扱う日本語文字コードは EUC-JP なので、
UTF-8 との間の変換を行っています。
■Hack の実行
そのままWebサーバに置けば動作するはずです。
検索実行例を下図に示します。

参考ページ:
- Yahoo!デベロッパーネットワーク
http://developer.yahoo.co.jp/
- MeCab
http://mecab.sourceforge.jp/
- Taku Kudo (工藤拓、MeCabの作者)
http://chasen.org/~taku/
関連書籍:
- Yahoo! Hacks
