【Python】アイテムベース協調フィルタリングでリコメンドの仕組みを作成(関連アイテム推薦)

アイテムベースの協調フィルタリングで簡単なリコメンドエンジンを作成してみました。

内容はほぼこちらのカーネルに拠っています。

https://www.kaggle.com/ajmichelutti/collaborative-filtering-on-anime-data

使用するデータセット

73516人の、12294ものアニメに対する評価データを利用します。

Kaggleのページから入手可能です。

Anime.csvとRating.csvの2つのファイルがあり、中身は以下のようになっています。

Anime.csv

  • anime_id – アニメを識別するmyanimelist.netのユニークなID。
  • name – アニメのフルネーム。
  • ジャンル – このアニメのジャンルのカンマ区切りのリスト。
  • タイプ – 映画、テレビ、OVAなど
  • エピソード – この番組のエピソード数 (映画の場合は1)
  • 評価 – このアニメの10の平均評価
  • メンバー – このアニメの「グループ」に含まれるコミュニティメンバーの数。

Rating.csv

  • user_id – 識別不可能なランダムに生成されたユーザーID。
  • anime_id – このユーザーが評価したアニメ。
  • rating – このユーザーが割り当てた10のうちの評価(ユーザーがそれを見たが評価を割り当てなかった場合は-1)

https://www.kaggle.com/CooperUnion/anime-recommendations-database

今回のゴール

適当な映画名を入れたら、それに似た映画を10個おすすめしてくれるレコメンド関数を作成したいと思います。

パーソナライゼーションではなく、関連アイテム推薦のレコメンド機能です。

リコメンド機能の作成

まずは必要なライブラリをインポートして、各データセットを読み込みます。

データの前処理

ratingの-1をNaNに変換

rating にはユーザーのアニメに対する10段階評価が入っていますが、未評価の場合には-1が入っています。

これはNaNに変換しておきます。

anime.csvとrating.csvをマージする

2つにデータセットが分かれているのでくっつけます。

今回はデータ量が多いので、自前のPCで扱えるよう、TVカテゴリの物だけに絞り込みます。

結合したのち、user_id,name,user_ratingのカラムのみを抽出します。

評点のついていない行を削除する

評点のついていない行に関しては推薦に利用できないので削除してしまいます。

推薦の精度を高めるために、評点平均より低い評点の行を削除

同じ映画に対して、Aさんは6,Bさんが6と評価したとしても、Aさんは甘口評価で、Bさんは辛口評価の人だとした場合、その6という評価の価値は異なります。

そのあたりを公平にする意味でも、ユーザーごとに評点の平均より低い評点の行は削除してしまいます。

 

user×itemのクロス集計表を作成する

pandas のpivot_tableメソッドでuser_id×nameのクロス集計表を作成します。

のちの作業のために、正規化と、NaNを0に変換しておきます。(しておかないとコサイン類似度計算時にエラーを吐かれます)

 

cosine_similarityを用いて類似度計算

コサイン類似度を計算します。1に近いほど似ています。

 

リコメンド関数

最後に、上記のDFをもとに、リコメンドをする関数を作成します。

結果をみると同シリーズが上位にありあまり面白みはありませんが、似ているアニメを選出する、という点ではきっちりできているように思います。

 

おわり