「あなたのはてブランキング」ではてなブックマークのロングテールを捕まえ、た?

先日書いた、

要は、各ユーザーにパーソナライズしたはてなブックマークランキングつくれば、はてなブックマークの底にあるロングテール部分も拾えて腐っているエントリが少なくなるんじゃないの?というお話。

の続きで、はてなブックマークの「ロングテール」を捕まえられそうなものを実装してみた。実は前の話を書いた時には、既に基本部分は出来ていたんだけれども、見栄えを良くするのに時間がかかったのでこのタイミングでご紹介。
作ったのは、各ユーザーが蓄積しているブックマーク情報からそのユーザーが注目しているキーワードを抽出して、それに基づいてはてなブックマークにランク付けをして、ランキングの結果をHTMLとして生成する仕組み。「あなたのはてブ ランキング」とでもいいましょうか。
まあ、見てもらうのが早いと思うので、生成したサンプルをxreaに置いてみた。id:sshiの「今日のはてブランキング」はこちら(http://sshi.s57.xrea.com/hbr/sample_sshi.html)。サンプルが一人だけだとつまんないので、はてなおや(id:naoya)さんのランキングも勝手に作ってみた*1。こちら(http://sshi.s57.xrea.com/hbr/sample_naoya.html)。(あ、はてなの画像とかCSSとかもそのまま使っちゃったぞ。まずかったかな。まずかったら御一報ください。すぐ消します。)
ユーザーごとのはてなブックマークを解析すると、それぞれに異なる(重み付きの)注目キーワードが抽出されるので、同じ日のはてなブックマークでもランキングにかなり差がある。そのへんは はてなおやさんと僕のランキングを見比べてもらえばわかると思う。はてなおやさんと僕だったら、そこそこ似たランキングになるかと思ったけど、結構違うものになったのは驚き。
数日前から、個人的にこのランキングを通してはてなブックマークを見ているんだけど、それなりに(僕にとって)興味深いエントリが上位にきてくれる気がする。ちなみに、ブックマークしているユーザー数は評価には全く考慮されないので、「興味深いエントリなのに、1人しかブックマークしてない」なんてのもちゃんと上位にくる。まあ、「気がする」程度でちゃんとした評価*2なんかはしてないんだけども。どうですかね?こんな感じのをはてなでやってもらえませんかね?
ランキングの仕組みは以下。

仕組み概要

実は全然たいしたことはしてない。おおまかには、

  1. 個々のユーザーを特徴付けるキーワードと重みを算出する。(ユーザーのキーワード特徴量)
  2. 注目キーワードのそれぞれの最新50件分に含まれるはてブのエントリを集めてくる。(注目キーワードは10個に限定しているので最大500エントリ)
  3. 集めたエントリに対して、ユーザーのキーワード特徴量で得点を算出。

という流れ。

ステップ1

1のステップでは、ユーザーの特徴量を算出する。今回使ったのはキーワード。ユーザーのはてなブックマークに多く登場するキーワードは、そのユーザーが興味あるキーワードだといえるので、これを各ユーザーの特徴量として使う。具体的には、とにかくユーザーがブックマークしているエントリを全て集めてきて、それぞれのエントリに付けられたキーワードの数を累積していく。例えば今日までの僕のブックマークだと、(累積)キーワード数が4876個で、そのうち一番多いのが「JavaScript」で57個、次は「エディタ」で37個、、、以下僕のブックマークに含まれるキーワードとその個数を全部算出する。僕のブックマークの中には、「JavaScript」をキーワードとして持つエントリが57個、「エディタ」をキーワードとして持つエントリが37個あるということだ。こうやって算出した『「キーワードと個数の組」の集合』がユーザーの特徴量になる。

ステップ2

2のステップでは、得点を算出する対象のエントリを集める。今回は、ユーザーのブックマークに登場しているキーワードのうち、上位10個をそのユーザーの「注目キーワード」として、注目キーワード各々の最新ブックマーク50件を集めることにした。例えば、キーワード「Ruby」ならこのページ(http://b.hatena.ne.jp/keyword/ruby)からエントリを集める。今日の時点の僕の注目キーワードは、 JavaScript、エディタ、RubyAjax、ブラウザ、XML、データベース、プログラミング、カスタマー、Javaの10個。それぞれのキーワードで最新のキーワード50件を集めてきて、最大500件。重複もあるので500件にはならないけど。

ステップ3

3のステップでは、集めた500件の候補に特徴量で得点を付けていく。得点の付け方は簡単で、得点付けするエントリが含むキーワードそれぞれに、ユーザーが持つ特徴量でのキーワードの個数を足す。例えば、僕の特徴量で「JavaScript」と「エディタ」と「漫画」というキーワードを含むエントリの得点付けをすると、JavaScriptの個数とエディタの個数と漫画の個数を足しあわせたものになる。それぞれ、57個、37個、3個だと97点になる。ユーザーが興味をもっているキーワードが多く含まれているほど、高得点になるという仕組み。一応理論的な最高点が10000点になるように正規化してある。
なんだか説明すると長くなっちゃったけど、まあ、こんな感じです。

改善点

改善点もいろいろ考えられる。集めてくるエントリを2のステップみたいに中途半端なものにしないで、はてなブックマーク全体のエントリに得点をつければ、もっとちゃんとしたランキングになるだろう。今のだと結局「最新」という時間のフィルタをかけてしまっているので、昔にブックマークされたエントリは浮かびあがってこない。まあ、ある時点の「ロングテール」を捕まえている、ということもできるかもしれない。あと、特徴量の定義とか、点数計算も考慮の余地ありまくり。傾斜を考えてキーワードの重みを変えるとか、明かに有意でないキーワードをはぶくとか、逆に有意なキーワードだけを特徴量とするとか。あ、キーワードをクラスタリングしてから重み付けるとかすると、個々人の特徴をもっと表現できるかもしれないな。それに、エントリとは直接関係ないキーワードが付与されているエントリがたまにあった。特にアマゾンのページ。関係ないキーワードはノイズになってしまうので、取り除いたほうがいいかもしれない。改善点はいっぱいあるとはいえ、これだけの仕組みでも結構使えそうなので個人的には満足。

愚痴

最後に愚痴。はてなブックマークの各エントリのキーワードを取得するのがすげー面倒だった。何故だか知らないが、ブックマークをリスト表示しているほとんどのページでエントリに付いてるキーワードを全部表示してくれていない。5個くらいに制限されてしまっている。唯一、「キーワード「xxx」を含む注目エントリー」のページだけがリスト中に全部のキーワードを表示してくれる。2のステップがこんな仕様になっているのも、それを使ってトラフィックを抑えるため。
一方、個人がブックマークしているエントリのキーワードは、どうやっても一気にとれそうになかったので、いちいち各エントリの詳細ページ(コメントが一覧でみれるとこね)を取得するしかなかった。なので、個人の特徴量を算出する1のステップでは、そのユーザーがブックマークしている数だけリクエストが飛んでいる。ごめんなさい。まあ、一度取得したらキャッシュするようにはしたけども、それでもなあ。せめて、Atomフィードにタグだけじゃなくて、キーワードのカテゴリもつけてくれないかなあ。

*1:問題あったらすぐに消します。>はてなおやさん

*2:どういうのがちゃんとした評価なのかよくわからないし