今回はレコメンドで最近注目されている「Factorization Machines」というアルゴリズムを使ってみたので実装方法などを紹介したいと思います。
Factorization Machinesとは?
Matrix Factorizationを一般化したアルゴリズム。
- Matrix Factorizationではユーザとアイテムの情報しか扱えなかったが、それ以外の情報も扱うことができる
- Logistic Regressionなどと異なり、疎な行列を扱うことができる
- 特徴量の間で影響を与え合う交互作用(Interaction)を考慮できるため、相関関係がある特徴量も適切に扱うことができる
イメージ図
引用:srendle/libfm: Library for factorization machines
参照:https://zenn.dev/panyoriokome/scraps/d521e032f3be15
前準備
ライブラリ
前準備としてfastFM
をインストールする必要があります。ただこのライブラリは少し癖があり
fastFMには、 Linux(Ubuntu 14.04 LTS)およびOS X Mavericks用の継続的インテグレーション/テストサーバー(Travis)があります。他のOSは積極的にサポートされていません。
とのことです
# ライブラリをインストールする $ pip install fastFM
あと「No module named ‘category_encoders’」と出た場合は以下もインストールしてください。
# ライブラリをインストールする $ pip install category_encoders
ちなみに軽く調べた感じPython3.7だとインストールでCpython関連のエラーが発生するので3.6以下の環境でしか使えないみたいです。GitHubのソースコードを直接読み込むことで動作するかも?
データセットの用意
今回は業務で協調フィルタリングを用いたレコメンドロジックをPythonで実装した際のメモになります。使用するデータセットはKaggleに用意されているレコメンド用のアニメ視聴データです。
簡単なロジックの仕組みとしてはメモリベースでユーザーの視聴履歴からコサイン類似度を計算し、似たようなユーザーを抽出してその評価数値から上位のものをレコメンドするというユーザーベースのレコメンドロジックになります。
データセット→ Anime Recommendations Database | Kaggle
<前処理>
import numpy as np import pandas as pd df_rating = pd.read_csv(r"C:\Users\~~rating.csv") df_label = pd.read_csv(r"C:\Users\~~anime.csv") # 量が多いので500000件以上レビューがある人気アニメに絞る df_label =df_label[df_label['members']>500000] # anime_idをキーにして内部結合する df = pd.merge(df_rating, df_label, on='anime_id', how='inner')[['user_id','anime_id','name','rating_x']]
<実行結果>
import category_encoders as ce from sklearn.model_selection import train_test_split # ユーザーの視聴履歴を集約 user_data = df.pivot_table(index="user_id",columns="name",values="rating_x") #ユーザーの評価履歴に過去の評価履歴を内部結合(メモリをかなり食うので10000件だけ) test_df = pd.merge(df_rating.iloc[:10000,:], user_data, on='user_id', how='inner') # ユーザーIDの列を削除して欠損値を0埋め test_df = test_df.drop('user_id',axis=1).fillna(0) data_y = test_df['rating'] data_X = test_df.drop(['rating'], axis=1)
<データの分割>
# 指定の列をone-hotエンコード enc = ce.OneHotEncoder(cols=['anime_id']) X = enc.fit_transform(data_X) y = data_y # データ分割 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0)
Factorization Machinesによるレコメンド回帰予測をPythonで実装する
from fastFM import als
from scipy.sparse import csr_matrix
from sklearn.metrics import mean_squared_error, mean_absolute_error
# モデル作成
fm = als.FMRegression(n_iter=1000, init_stdev=0.1, rank=8, l2_reg_w=0.5, l2_reg_V=0.5, random_state=1)
fm.fit(csr_matrix(X_train), y_train)
# 評価
## 学習データへの当てはまり具合
train_loss = mean_absolute_error(y_train, fm.predict(csr_matrix(X_train)))
## テストデータの誤差
test_loss = mean_absolute_error(y_test, fm.predict(csr_matrix(X_test)))
als.FMRegression()
のパラメーター設定については公式ドキュメント(https://ibayer.github.io/fastFM/api.html)参照
評価予測する際の注意点としては予測の際に使用するデータは通常のデータフレームではなく疎行列用のscipyのcsr_matrix()で変換したデータを指定しないといけない点です。
ちなみにcsr_matrixは疎行列(0が多くスカスカな行列)を通常の3×3のような行列とは違い([0,0]地点に 1) ([1,1]地点に 3)といった情報のある個所だけを記載した形に変換する関数です。これにより従来の行列よりも計算量を削減することが可能になるみたいです。
参考:https://qiita.com/stkdev/items/a1824c4249a519a523fd
コメント