裏で形態素解析器を使い長い文をそのままキーとして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