たつをの ChangeLog : 2009-02-26

Yahoo!デベロッパーネットワーク (YDN) のウェブ検索 API を用いて、入力キーのウェブ検索ヒット件数だけを取り出す簡単な方法について。
ウェブサービスを用いて自然言語処理っぽいことをやろうというときの基本中の基本。

使用している Web API の提供が終了となったため、現在動作しません。ご了承ください。


- Yahoo!デベロッパーネットワーク
http://developer.yahoo.co.jp/
- Yahoo!デベロッパーネットワーク - 検索 - ウェブ検索
http://developer.yahoo.co.jp/webapi/search/websearch/v1/websearch.html

Y!API に投げるURL


http://search.yahooapis.jp/WebSearchService/V1/
webSearch?appid=YahooDemo&query=[URI ESCAPE したキー]&result=1

appid は自分で取得したものを使うこと。
(http://e.developer.yahoo.co.jp/webservices/register_application)

result は 1 にする。
これを 0 にすると 10 件返ってきてしまう。
なるべく検索結果 XML を小さくするのが効率的なのでミニマムである 1 にする。

検索結果 XML からヒット数を取り出す


XML をパーズするまでもない。正規表現で取り出すのが速い。
検索結果 XML の冒頭はこんな感じ。
<ResultSet xsi:schemaLocation="urn:yahoo:srch
http://search.yahooapis.jp/WebSearchService/V1/WebSearchResponse.xsd"
type="web" totalResultsAvailable="19700" totalResultsReturned="1"
firstResultPosition="1" ...
totalResultsAvailable が検索ヒット数なので、
正規表現「/totalResultsAvailable="(\d+)"/」を使えば OK。

Perl によるサンプルプログラム


以上を踏まえたサンプルプログラム (perl)。
#!/usr/bin/perl
use strict;
use warnings;
use LWP::Simple;
use URI::Escape;

while (<>) {
    my $num = get_num($_);
    print "$num\n";
}

sub get_num {
    my ($key) = @_;
    my $ek = URI::Escape::uri_escape($key);
    my $url = "http://search.yahooapis.jp/WebSearchService/V1/".
        "webSearch?appid=YahooDemo&query=$ek&result=1";
    my $res = get($url);
    my ($num) = ($res =~ /totalResultsAvailable="(\d+)"/);
    return $num || 0;
}

実行例:
% cat a.txt
ufj
学校
六本木ヒルズ
% sample.pl a.txt
105000000
1340000000
17400000

サンプルプログラムは Perl で書いたが、
他のスクリプト言語でも簡単に書けるよ。

あらかじめ用意された単語セットがあり、それぞれの単語同士の近さを検索ヒット数とそれによるシンプソン係数で求める手順について。

使用している Web API の提供が終了となったため、現在動作しません。ご了承ください。


Yahoo!デベロッパーネットワーク (YDN) のウェブ検索 API を用いる。

- Yahoo!デベロッパーネットワーク
http://developer.yahoo.co.jp/
- Yahoo!デベロッパーネットワーク - 検索 - ウェブ検索
http://developer.yahoo.co.jp/webapi/search/websearch/v1/websearch.html

ロジック


やってることは、下記で書かれていることと同じ。

- リアルとWebのネットワーク分析 (先端研ブログ - CNET Japan Blog)
http://blog.japan.cnet.com/sentan/archives/002672.html

この内容に沿って、引用を交えて解説する。

シンプソン係数は下記の式で計算される。
 | X ∩ Y |
------------
min(|X|,|Y|)
値が大きいほど「近い」とみなせる。

具体的な計算例:
例えば、パンダとペンギンの関係の強さを計算してみます。
パンダのヒット数|X|は1130万件、
ペンギンのヒット数|Y|は860万件、
「パンダ ペンギン」のヒット数|X∩Y|は141万件、
でしたので、シンプソン係数は約0.16になります。
141万÷860万≒0.16

単語セット


単語セットは一行1ファイル(文字コードはUTF-8)として用意する。
例:animals.txt
パンダ
ペンギン
カピバラ
アザラシ
マントヒヒ

総当たりでこれらの単語同士のシンプソン係数を求める。

Perl によるサンプルプログラム


以上を踏まえたサンプルプログラム (perl)。
#!/usr/bin/perl
use strict;
use warnings;
use LWP::Simple;
use URI::Escape;

my @list;
while (<>) {
    chomp;
    push @list, $_;
}

for (my $i = 0; $i < @list - 1; $i++) {
    my $x = get_num($list[$i]);
    for (my $j = $i + 1; $j < @list; $j++) {
	my $y = get_num($list[$j]);
	my $xy = get_num($list[$i]." ".$list[$j]);
	my $min = ($x < $y) ? $x : $y;
	my $simp = $xy / $min;
	print "$simp $list[$i] vs $list[$j]\n";
    }
}

sub get_num {
    my ($key) = @_;
    my $ek = URI::Escape::uri_escape($key);
    my $url = "http://search.yahooapis.jp/WebSearchService/V1/".
        "webSearch?appid=YahooDemo&query=$ek&result=1";
    my $res = get($url);
    my ($num) = ($res =~ /totalResultsAvailable="(\d+)"/);
    return $num || 0;
}

appid は自分で取得したものを使うこと。
(http://e.developer.yahoo.co.jp/webservices/register_application)

関数 get_num は前回[2009-02-26-1]のものと同じ。

上記コードでは、同じ単語に対して get_num が二回ずつ呼ばれてしまう。
ハッシュでキャッシュすればより効率的になる。

実行例:
% sample.pl animals.txt
0.125558312655087 パンダ vs ペンギン
0.140357852882704 パンダ vs カピバラ
0.0624748490945674 パンダ vs アザラシ
0.141463414634146 パンダ vs マントヒヒ
0.0934393638170974 ペンギン vs カピバラ
0.153923541247485 ペンギン vs アザラシ
0.0626016260162602 ペンギン vs マントヒヒ
0.0349900596421471 カピバラ vs アザラシ
0.0653116531165312 カピバラ vs マントヒヒ
0.00612466124661247 アザラシ vs マントヒヒ

たつをの ChangeLog
Powered by chalow