プログラマでありたい

おっさんになっても、プログラマでありつづけたい

RubyでYahoo! キーフレーズ抽出APIを使ってテキストマイニング

 Rubyでキーワード抽出およびTF-IDFでキーワードの重要度の重み付けが出来んかなと思ってGemを漁ってみました。残念ながら、日本語データに関しては、それらしいのは見つかりませんでした。キーワード抽出については、Mecabで形態素解析後に品詞同士のつながりのパターンを考えれば、割りと簡単に作れます。昔作ったことがあるけど、ソースはどっかに旅立たれていたので、改めて作った上でGitHubに登録しようかなぁと思います。またTF-IDFについては、何と言ってもIDFのデータをどうするかがポイントになります。そのあたりのデータ含めて、PerlのLingua::JA::TFIDFを参考に移植させて貰おうかなぁと考えています。

 一方で、てっとり早く上記の2つを実現する方法もあります。Yahooのキーフレーズ抽出APIを利用すると、キーワード抽出と重要度のスコアリングを同時にやってくれます。ただし、24時間あたり5万リクエストと1リクエストあたりのサイズや、レスポンスが上位20件までしか返さないという制約があります。
 それで充分という場合は、さくっと利用するとよいでしょう。下記は、簡単なサンプルです。Yahooのニュースを抜き出して、重要なキーワードを抜き出すといったイメージです。定期的に流していると、ニュースのトレンドの推移などが解ってくるのではないでしょうか?

require 'open-uri'
require 'rexml/document'
require 'nokogiri'

APPLICATION_ID = ENV["YAHOO_API_KEY"]
BASE_URL   = 'http://jlp.yahooapis.jp/KeyphraseService/V1/extract'

$word_list = Hash::new

def request(text)
  app_id = APPLICATION_ID
  params = "?appid=#{app_id}&output=xml"
  url = "#{BASE_URL}#{params}"+"&sentence="+URI.encode("#{text}")
  response = open(url)
  doc = REXML::Document.new(response).elements['ResultSet/']
  doc.elements.each('Result') {|element|
    text = element.elements["Keyphrase"][0]
    score = element.elements["Score"][0] #キーワードの重要度は、とりあえず切り捨て
    $word_list["#{text}"] = $word_list["#{text}"].nil? ? 1 : $word_list["#{text}"]+1
  }
end

def get_urls(page_url)
  urls = Array.new()
  uri = URI.parse(page_url)
  doc = Nokogiri::HTML(open(page_url))
  doc.xpath("//*[@id='main']//ul[@class='list']//a").each do |anchor|
    url = anchor[:href]
    url = uri.merge(url) if not uri =~ /^http/
    urls << url
  end
  return urls
end

def get_headline_text(page_url)
  text = ""
  doc = Nokogiri::HTML(open(page_url))
  if page_url.to_s.match(/dailynews/)
    text = doc.xpath("//*[@id='detailHeadline']").text
  else
    text = doc.xpath("//*[@id='main']//p[@class='hbody']").text
  end
  return text.gsub(/\n/,"")
end

def get(page_url)
  urls = get_urls(page_url)
  urls.each {|url|
    text = get_headline_text(url)
    #p text
    request(text)
  }
end

page_url = 'http://news.yahoo.co.jp/list/?c=economy'
get(page_url)
$word_list.each{ |key,value|
  p "#{key}=#{value}"
}


 サクッと作っただけなので、悪しからず。



See Also:
これはセンスが良い。Lingua::JA::TFIDF - プログラマになりたい
特徴語抽出のあれこれ - プログラマになりたい
キーワード抽出モジュール Lingua::JA::Summarize - プログラマになりたい


参照:
Lingua::JA::TFIDF - search.cpan.org
テキスト解析:キーフレーズ抽出API - Yahoo!デベロッパーネットワーク