Rubyで『集合知プログラミング』(2)
第3章「グループを見つけ出す」
3.2 単語ベクトル
"generatefeedvector.rb"を実装してみます。
RSSの解析にはRSS Parserを使います。
RSSフィードのタイトルと,単語のカウントを返すメソッドから。
require 'rss' def get_word_counts(url) # RSSをParse rss_parse = open(url){|f| RSS::Parser.parse(f.read)} wc = Hash.new(0) # 全エントリから単語のリストを取り出す rss_parse.items.each do |e| words = get_words(e.title + ' ' + e.description) words.each{|w| wc[w] += 1} end return rss_parse.channel.title, wc end
単語リストの取得。
def get_words(html) # タグを除去 txt = html.gsub(/<[^>]>/, '') # 非アルファベットで分割 txt.downcase.split(/[^A-Za-z]+/).reject{|w| w==''} end
単語のカウントを計算します。と同時に,その単語が登場するRSSのカウントを取ります。
apcount = Hash.new(0) # その単語が登場するRSSのカウント word_counts = Hash.new(0) # RSSのURLリストを取得 feed_list = open('feedlist.txt') do |f| f.readlines.map{|l| l.chomp} end # 各RSSについてタイトルと単語のカウントを取得 feed_list.each do |url| begin title, wc = get_word_counts(url) word_counts[title] = wc wc.each do |word, count| apcount[word] += 1 if count > 1 end rescue puts("Failed to parse feed #{url}") end end
単語を,その出現頻度により絞り込みます。
word_list = [] apcount.each do |w, bc| frac = bc.to_f / feed_list.length word_list.push(w) if 0.1 < frac and frac < 0.5 end
単語の出現数の表を作成します。
open('blogdata.txt', 'w') do |f| line = ['Blog'] + word_list f.puts line.join("\t") word_counts.each do |blog, wc| line = [blog] + word_list.map{|word| wc[word] || 0} f.puts line.join("\t") end end
ここまで。
結果の'blogdata.txt'はかなり巨大なので,省略します。