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"