はてブユーザ間の類似度

注目の動画問題と総合メディア論事件との関連

いつか書こうと思いつつ随分と放置していた話題.きっかけは,NO!と言えるようになりたい:「注目の動画」は本当に劣化したのかより.注目の動画(特にニコニコ動画側?)にアイドルマスターやらアニメ関係の動画ばかりが挙がっていて[これはひどい]と言う話題が一時期盛んでした.これに関連して,ひとつ気になっていたことがあったので調べてみました.

注目の動画(ニコニコ動画)からidolm@sterタグのついているエントリを新しいものから50個抜き出して,それらのエントリをブックマークしているユーザの分布を調べました.その結果がこちら(完全なログ:user_dist_nicovideo.log).一番右がユーザ名で,その隣が50エントリの中でそのユーザがブックマークしていたエントリの数です.

get 50 entries

  0  47 Ubuntu
  1  44 ak9
  2  30 kishida_w
  3  29 sphynx
  4  29 yamifuu
  5  27 thomyou
  6  23 momdo
  7  18 w84_yuto
  8  18 red_black_72
  9  17 fs001493
 10  16 sekiryo
 11  11 misui-shi
 12  10 Nota
 13   9 Philos
 14   9 kosyu
 15   8 nicovideoch
 16   7 acqua_alta
 17   7 deb
 18   7 miyagawa
 19   6 FTTH
 20   6 mine-o

・・・(以下略)・・・

この結果を見ると分かりますが,(注目の動画に挙がっている)アイドルマスター関係の動画のほとんどをブックマークしている人が数人存在することが分かります.このため,その数人+他の数人がブックマークすると,それだけでそのエントリが注目の動画へ反映されることになります(半分以上のエントリをブックマークしている人も数人いるので,敷居はさらに下がっている).すなわち,この問題は“限られた人達の趣向の結果が全体(注目の動画)に大量に反映されてしまっている”ために発生したと見ることができます.「注目の動画」急速劣化問題についてにおいて,注目の動画へ表示される閾値を上げると改善できるという指摘がありましたが,これは閾値を上げることによって“限られた人達の集団”だけでは注目の動画にランクインさせるためのブックマーク数を確保することができなくなるためであろうと思います.

この問題を見たとき,好奇心と怠惰の間:これはspamですか?で取り上げられた問題に近い印象を受けました.そこで,実際に“総合メディア論”事件の対象となったエントリのユーザの分布を調べてみました(完全なログ:user_dist_media.log).

get 18 entries

  0  18 K--N
  1  18 abububu
  2  18 i-yuuji
  3  18 tomomimomi
  4  18 tetsumasyu
  5  17 rika0101
  6  17 panda0122
  7  17 y-ken
  8  16 sanzenri
  9  16 ryo-19
 10  16 kondouhisashi
 11  15 keita1986
 12  15 sekiwake
 13  15 yasutokun
 14  10 anpanman2
 15   9 wakhok
 16   9 ipresearch
 17   1 miffuy

こちらは,アイドルマスターの動画よりもさらに偏った結果になっていますが,“限られた人達の趣向が全体(この例ではホットエントリ)に反映された”という同じ傾向は持っていると思います.

類似度の利用

上記を調べたのは,はてブのユーザ間の類似度を何らかの方法で求めておくことで,その結果を

に利用できるのではないか,と考えたためでした.あるユーザの視点から見ると,そのユーザと類似度の高いユーザのブックマークを表示すれば,そのユーザの満足度が高まることが期待できます.また,システム全体と言う視点から見ると,あるエントリをブックマークしているユーザ間の類似度を調べ,その類似度(の平均値か?)があまりにも高い場合にはフィルタリングするなどの対処を取ることによって,先に出たような不満を解消することができます.後者に関しては,SPAMブックマークされたエントリを“ある特定の人にしか興味のないエントリ”と捉えることによって,今よりも様々なケースに対応できるのではないか,と考えています.

さて,どうやって類似度を求めるのかですが,まずは簡単に,過去の自分のブックマークからブックマークしているユーザの分布を取得してそれを利用する,と言う方法を考えて見ます.サンプルプログラムは以下のようになります(プログラム中で使用しているライブラリの説明は後述).

#!/bin/ruby -Ku
require 'hatena'

SAMPLE = 50
LOWER_BOUND = 10
UPPER_BOUND = 100

if (ARGV.size < 1)
    $stderr.print("usage: ruby similarity.rb UserID\n")
    exit(-1)
end

dist = Hatena::Bookmark::Distribution.new
Hatena::Bookmark::URITrace.new(ARGV[0]).each { |uri|
    count = Hatena::Bookmark::count(uri)
    next if (count < LOWER_BOUND || count > UPPER_BOUND)
    
    puts(uri) if (dist.add(uri))
    break if (dist.sample >= SAMPLE)
    
    sleep(2)
}

puts("--")
puts("get #{dist.sample} entries")
puts

# ユーザ数で降順にソートした後,出力
i = 0
dist.sort_users.each { |item|
    printf("%3d %3d b:id:%s\n", i, item[1], item[0])
    i += 1
}

idを指定すると,そのidのブックマーク履歴からブックマーク数がLOWER_BOUND以上UPPER_BOUND以下のエントリをSAMPLE件取得し,それらのエントリのブックマークユーザの出現頻度分布を表示しています.例えば,b:id:tt_clownで試した結果は以下のようになります(完全なログ:user_dist_tt_clown.log).

get 50 entries

  0  50 b:id:tt_clown
  1  31 b:id:Ubuntu
  2  13 b:id:westerndog
  3  10 b:id:andsoatlast
  4   8 b:id:kitakyudai
  5   6 b:id:pc_nagomu
  6   6 b:id:yumizou
  7   6 b:id:zu2
  8   5 b:id:toronei
  9   4 b:id:fgh
 10   4 b:id:mirrorbz
 11   4 b:id:activecute
 12   4 b:id:lliorzill
 13   4 b:id:yachimon
 14   4 b:id:ohkami3
 15   4 b:id:bunoum
 16   4 b:id:hamasta
 17   4 b:id:Itisango
 18   4 b:id:cs133
 19   4 b:id:lizy
 20   4 b:id:kanose

・・・(以下略)・・・

この結果を基にしてユーザ毎にパーソナライズする場合は,類似度の高いユーザがブックマークしているエントリから表示していくとうまく機能しそうです(はてブお気に入りサジェスタは,これに近い方法でやっているのではないかなと予想).また,あるエントリが“SPAM*1”かどうかを判定するには,そのエントリをブックマークしているユーザの集合をUとすると

average(∀x∈U, ∀y∈U | similarity(x, y))

のような形でそのエントリをブックマークしているユーザ間の類似度の平均値を導出し,その値があまりにも高い場合にはフィルタリングをすると良いのではないかと思います.

今回は,類似度の導出方法や利用方法に関してはあまり深く考えてないので,計算量が多すぎるなどの問題でそのままでは使えないだろうと思います.ただ,うまく類似度を求めておくことができれば,いろいろな場面で使えそうだなぁと感じました.SBMにおけるユーザ間の類似度の導出方法とクラスタ解析については,どっかでやられてそうなので,一度調べてみたいと思います.

Download

*1:ここでは,限られたユーザにっとてしか有用でないエントリと言う意味で使います