協調フィルタリングによるアイテムの推薦

こんばんは、south37です。前回のブログではユーザー同士の類似度を見積もる方法について考えました。距離空間を使う方法、相関関数を使う方法等が存在し、はてなブックマークを利用するユーザ同士の比較ではjaccard相関関数が悪く無い値を与える事が分かりました。

今回は、類似度を「アイテムの推薦」に活かす方法について考えてみたいと思います。

協調フィルタリング

自分と他のユーザとの類似度を見積もる事が出来れば、アイテムの推薦を行う事が出来ます。具体的には、それぞれのユーザがアイテムに割り振ったスコアに自分とユーザとの類似度をかけ合わせ(類似度で重み付けし)、それを足し合わせる事で類似度を反映したアイテムのスコアを算出します。

類似度をかけ合わせる事で、自分と似たユーザが良いと判断したものが高評価を受ける事になります。実際、自分と似たユーザが良いと思うなら自分も良いと思う可能性は高そうです。そう考えれば、良い手法ですよね。

こういった、他者との類似度を利用したアイテムのスコア付け、そしてそれを利用したフィルタリングを、「協調フィルタリング(Collaborative Filtering)」といいます。他者とのcollaborateによってアイテムのスコア付けを行うので、この様な呼び方がなされているのだと思います。

「ユーザベースの推薦」と「アイテムベースの推薦」

上記で紹介したような、「ユーザ同士の類似度」を算出してからその情報を元にアイテムのスコア付けを行い、オススメのアイテムを選ぶ方法を、「ユーザベースの推薦」といいます。

実はこの方法には欠点があります。新しいユーザに対して何か推薦を行いたい場合には、「ユーザベースの推薦」ではそのユーザと他の全てのユーザの間で類似度の計算を行う必要があります。ユーザがN人いる時には、ユーザが一人増える度に N × (類似度の計算) という量の計算を行う必要がある為、類似度の計算の処理が重くユーザ数も多いケースでは毎回重い計算を走らせる事になります。これは実用上大きな問題となります。

その問題を解決するのが、「アイテムベースの推薦」です。

アイテムベースの推薦とは?

「ユーザ同士の類似度」を算出する変わりに「アイテム同士の類似度」を算出し、それを利用して推薦を行うのが「アイテムベースの推薦」です。

具体的な手法としては、まず、ある用意されたアイテムの集合に対して 事前に お互いの類似度を算出しておきます。次に、新しくユーザが加わった際に「そのユーザが評価しているアイテム」とその他のアイテムの類似度を「その他のアイテム1つ1つ」に対して足し合わせます。その結果、新しいユーザが持ってるアイテムの 集合 と最も類似度の高いアイテムを見つけ出す事が出来、推薦が可能となります。

ポイントは、ユーザを「アイテムの集合」と見なす事です。そして、その「集合」と類似度の高いアイテムを見つけ出す方法として、単純に「集合内のアイテム1つ1つとの類似度の足し合わせ」を使います。重い処理だと考えられる「類似度の計算」は事前に行っているため、「ユーザベースの推薦」と比べるとはるかに軽い処理となります。

はてなブックマークで、「アイテムベースの推薦」を試す

前回と同様に、はてなブックマークで試してみたいと思います。

まず、はてなブックマークのリストを用意して、それぞれの類似度を算出し、テーブルを作ります。NC2個の類似度データが出来る事になるはず。 はてなブックマークのリストとしては、「south37としてブックマークしてるサイト50個」をブックマークしてるユーザが「ブックマークしてるサイト」とします。

類似度の算出方法としては、ブックマークのリストに対して、それをブックマークしてるユーザの集合を取得(はてなのエントリー情報取得APIを使用)してjaccard相関関数による比較を行うとしましょう。

データ取得

で、まず最初のはてなブックマークのリストを取得しようとしたのですが、リクエストの数が多い為か全然処理が終わりません...

現在15万ほどのurlが取得出来たのですが、まだまだ続いています...

中途半端ですが、今回はここまでにします。しょうがないですよね。

結果がどうなるかは後日のお楽しみという事でお願いします!!!

補足

類似度を用いたスコア付けの際に、単純にスコアに類似度をかけ合わせて足し合わせると書きましたが、「集合知プログラミング」いわく「類似度の和」で割って正規化を行う必要があるそうです。アイテムごとに評価者の数が全然違う場合には、この正規化をきちんと行わなければまずい事になりそうです。

集合知プログラミング

集合知プログラミング