2章 その8

続き。これで23ページ、deliciousのレコメンデーションまでできた



http://www.bitbucket.org/shokai/collective-intelligence-study/src/0082469f4612/delicious.rb
delicious.rbにget_userposts関数を追加

  # 指定ユーザのpostをできるだけ全部取ってくる
  def get_userposts(user, count=15)
    uri = 'http://feeds.delicious.com/v2/rss/' + user + '?count=' + count.to_s
    doc = REXML::Document.new(open(uri).read)
    results = Array.new
    REXML::XPath.each(doc, '//item//link()'){ |link|
      results.push(link.text)
    }
    return results
  end

p.22より、あるタグに関係のありそうなdeliciousユーザ全員の最近のブックマークを取ってくる
http://www.bitbucket.org/shokai/collective-intelligence-study/src/9bdb46b4fa3a/deliciousrec.rb
deliciousrec.rbに関数追加

  # すべてのユーザによって投稿されたリンクを取得
  def fillItems(user_dict)
    all_items = Hash.new
    
    user_dict.keys.each{ |user|
      posts = Array.new
      3.times do # ユーザの最近の投稿を3回チャレンジする
        begin
          posts = @del.get_userposts(user)
        rescue
          puts 'Failed user ' + user + ', retrying'
          sleep 4 # 4秒停止してリトライ
        end
      end
      
      next if posts.length == 0 # 取得できてなかったら次のユーザへ
      
      posts.each{ |post|
        url = post
        user_dict[user][url] = 1.0
        all_items[url] = 1
      }
      
      # 空のアイテムを 0.0で 埋める
      all_items.keys.each{ |item|
        user_dict.keys.each{ |user|
          user_dict[user][item] = 0.0 if !user_dict[user].key?(item)
        }
      }
    }
    return user_dict
  end

p.22より、arduino関連をブックマークしているユーザのリストを作成
irb

irb(main):004:0> delusers = rec.initializeUserDict('arduino')
=> {"xa2"=>{}, "digrat"=>{}, "evilkingtiger"=>{}, "subflux"=>{}, "psychonaught393"=>{}, "milemist"=>{}, "gf"=>{}, "keithlyk"=>{}, "rootroot"=>{}, "hdrapin"=>{}, "cualquierchica"=>{}, "ximitiejiang"=>{}, "striso"=>{}, "ryanfobel"=>{}, "PedroDiogo"=>{}, "redwyre"=>{}, "natjgreen"=>{}, "stern54"=>{}, "craftygeek"=>{}, "islandzero"=>{}, "xavipolo"=>{}, "m00nsh00t3r"=>{}, "montifas"=>{}, "rgrieselhuber"=>{}, "tedder"=>{}, "widefido"=>{}, "jdkunesh"=>{}, "WuselDusel83"=>{}, "cbrahms"=>{}, "tangobear"=>{}, "super000"=>{}, "katmando"=>{}, "dolfkamper"=>{}, "gerobazant"=>{}, "michael_smyth"=>{}, "cdewane"=>{}, "hoanga"=>{}, "iknowkungfu"=>{}, "malloyca"=>{}, "jafish"=>{}, "rasorface"=>{}, "edasque"=>{}, "seadigs"=>{}, "tpe"=>{}, "endre"=>{}, "jfenwick"=>{}, "vt11"=>{}, "djdunc"=>{}, "lizard43"=>{}, "msodrew"=>{}, "aphony"=>{}, "fcuri"=>{}, "Nylson"=>{}, "lilidmu"=>{}, "craftybenu"=>{}, "tlockney"=>{}, "mat703"=>{}, "abarax"=>{}, "mcmap22"=>{}, "idefarmen"=>{}, "newseal"=>{}, "codes02"=>{}, "zer0_ring"=>{}, "tcbitdennet"=>{}, "jeffshadap"=>{}, "peranchine"=>{}, "guigouz"=>{}, "myamiphil"=>{}, "ijcd"=>{}, "emaaaa"=>{}, "bokunenjin"=>{}, "svet"=>{}}
irb(main):005:0> 

全ユーザの最近のブックマークを取得

delusers['shokai'] = Hash.new
rec.fillItems(delusers)

10分ぐらい待つ。




p.23より、映画レーティングに使った関数をそのまま使う

irb(main):011:0> require 'recommendations.rb'
=> true
irb(main):012:0> c = Critics.new
c.topMatches(delusers, 'shokai')


userリストからランダムに選んで、趣向の近いユーザを計算する

irb(main):026:0> c.topMatches(delusers, user = delusers.keys[rand(delusers.length)])
=> [{0.0525109538254129=>"codes02"}, {-0.00778892423562012=>"mat703"}, {-0.00871263944056619=>"montifas"}, {-0.0117127048094488=>"lilidmu"}, {-0.0151668351870576=>"svet"}]
irb(main):027:0> user
=> "dolfkamper"
irb(main):028:0> c.topMatches(delusers, user = delusers.keys[rand(delusers.length)])
=> [{-0.00778892423562012=>"mat703"}, {-0.00871263944056619=>"montifas"}, {-0.0117127048094488=>"lilidmu"}, {-0.0151668351870576=>"svet"}]
irb(main):029:0> user
=> "tedder"

が、deliciousは各ユーザ最新15件しか取ってないので精度が悪すぎる



ユーザ名からオススメなページを計算。100件ぐらい取らないと駄目だな…

irb(main):030:0> c.getRecommendations(delusers, user = delusers.keys[rand(delusers.length)])
=> [{0.142857142857143=>"http://www.westfordlibrary.org/"}, {0.0=>"http://code.google.com/p/cgvis/"}]
irb(main):031:0> c.getRecommendations(delusers, user = delusers.keys[rand(delusers.length)])
=> [{0.111228945726762=>"http://blog.makezine.com/archive/2008/09/how_to_control_oleds_with.html?CMP=OTC-0D6B48984890"}, {0.0971927635683094=>"http://www.spikenzielabs.com/SpikenzieLabs/I2C-SPI_LCD.html"}, {0.0485963817841547=>"http://www.westfordlibrary.org/"}, {0.0=>"http://code.google.com/p/cgvis/"}]
irb(main):032:0> user
=> "zer0_ring"