surpriseにある全レコメンドモデルを試す
surpriseとは
surpriseとは明示的な評価データ(explicit feedback)を処理する推薦システムを構築/分析するためのPythonライブラリです。
※暗黙の評価(implicit feedback)やコンテンツベースの推薦をサポートしていません。
この記事では、surpriseライブラリを使って用意されている全てのレコメンドモデルを試します。この結果をもとに、どんなレコメンドモデルが優勢なのか、あるいは実運用しやすいのか理解が深まるのではないかと思います。
事前準備
本記事の実装は、Google Colaboratory上で行います。
まずはsurpriseライブラリをインストールします。
!pip install scikit-surprise
事前に必要なライブラリをインポートします。
import time
import pandas as pd
import numpy as np
from surprise import Dataset, Reader, accuracy
from surprise.model_selection import train_test_split
from surprise import (
NormalPredictor, BaselineOnly, KNNBasic, KNNWithMeans, KNNWithZScore,
KNNBaseline, SVD, SVDpp, NMF, SlopeOne, CoClustering
)
datasetの用意
このdatasetモジュールは、Datasetデータセットの管理に使用されるクラスとその他のサブクラスを定義します。
組み込みでmovielens-100kとmovielens-1Mのデータセットが用意されているので、load_builtin
メソッドを利用することで、簡単に読み込むことができます。
data_ml_100k = Dataset.load_builtin(name=u'ml-100k', prompt=False)
data_ml_1m = Dataset.load_builtin(name=u'ml-1m', prompt=False)
実運用を想定して公式サイトからmovielens-100kのデータセットをダウンロードし、カスタムデータとしてDatasetを作成します。
pandas.DataFrameからロードできるload_from_df
を利用します。またこのメソッドを利用するためには、あらかじめReaderクラスで評価スケール(rating_scale)を定義する必要があります。
ML100K_URL = 'http://files.grouplens.org/datasets/movielens/ml-100k/u.data'
df_custom = pd.read_csv(
ML100K_URL, names=["userid", "itemid", "rating", "timestamp"], sep="\t"
)
reader = Reader(rating_scale=(1, 5))
data_custom = Dataset.load_from_df(
df_custom[["userid", "itemid", "rating"]], reader
)
データの分割方法
学習データとテストデータを8:2に分割します。(本記事ではこちらのデータセットを使います。)
trainset, testset = train_test_split(data_custom, test_size=.2)
分割せずに学習とテストで同じデータセットを使うこともできます。
trainset_all = data_custom.build_full_trainset()
testset_all = trainset_all.build_testset()
SVDモデルを試す
SVDモデルを試します。fit
関数で学習し、test
関数で推論します。連結して1文で書くこともできます。最後に4つの指標(RMSE,MSE,MAE,FCP)で評価します。
algo = SVD()
algo.fit(trainset)
pred = algo.test(testset)
#pred = algo.fit(trainset_all).test(testset_all)
accuracy.rmse(pred),accuracy.mse(pred),accuracy.mae(pred),accuracy.fcp(pred)
出力結果:
RMSE: 0.9388
MSE: 0.8813
MAE: 0.7421
FCP: 0.6948
surpriseにある全てのレコメンドモデルを試す
アルゴリズムの解説
surpriseには11個のアルゴリズムが用意されています。簡単な解説を載せますが、詳しく知りたい方は各自でお調べください。
アルゴリズム | 概要 |
---|---|
NormalPredictor | 正常なトレーニングセットの分布に基づいてランダムな評価を予測するアルゴリズム。 |
BaselineOnly | 特定のユーザーとアイテムのベースライン見積もりを予測するアルゴリズム。 |
KNNBasic | 基本的な協調フィルタリングアルゴリズム。 |
KNNWithMeans | 各ユーザーの平均評価を考慮した、基本的な協調フィルタリングアルゴリズム。 |
KNNWithZScore | 各ユーザーのZスコア(データ群の該当する数値から平均値を引いて、標準偏差で割る)の正規化を考慮した基本的な協調フィルタリングアルゴリズム。 |
KNNBaseline | ベースライン評価を考慮した基本的な協調フィルタリングアルゴリズム。 |
SVD | 特異値分解。 |
SVDpp | SVD++アルゴリズム、SVDを拡張して暗黙の評価を考慮する。 |
NMF | 非負行列因子分解に基づく協調フィルタリングアルゴリズム。 |
SlopeOne | シンプルでありながら正確な協調フィルタリングアルゴリズム。 |
CoClustering | 共同クラスタリングに基づく協調フィルタリングアルゴリズム。 |
評価方法
surpriseには、RMSE, MSE, MAE, FCPと4種類のオフライン評価手法が予め用意されています。(詳しく知りたい方は、以下略)
surpriseにある全レコメンドモデルを試すを実装する
algo_list = {
"NormalPredictor" : NormalPredictor,
"BaselineOnly" : BaselineOnly,
"KNNBasic" : KNNBasic,
"KNNWithMeans" : KNNWithMeans,
"KNNWithZScore" : KNNWithZScore,
"KNNBaseline" : KNNBaseline,
"SVD" : SVD,
"SVDpp" : SVDpp,
"NMF" : NMF,
"SlopeOne" : SlopeOne,
"CoClustering" : CoClustering
}
11個のレコメンドモデルに対し、4種類のオフライン評価結果と実行時間を測定します。
df_result = pd.DataFrame(columns=["algo","rmse","mse","mae","fcp","time"])
for key, value in algo_list.items():
start = time.time()
algo = value()
pred = algo.fit(trainset).test(testset)
end = time.time() - start
record = pd.Series(
[key, accuracy.rmse(pred), accuracy.mse(pred), accuracy.mae(pred),
accuracy.fcp(pred), end], index=df_result.columns
)
df_result = df_result.append(record, ignore_index=True)
df_result
出力結果:
algo | rmse | mse | mae | fcp | time |
---|---|---|---|---|---|
NormalPredictor | 1.51978 | 2.30972 | 1.21849 | 0.49576 | 2.38026 |
BaselineOnly | 0.92274 | 0.85146 | 0.73127 | 0.71898 | 1.12585 |
KNNBasic | 0.77807 | 0.60539 | 0.60821 | 0.82728 | 19.30517 |
KNNWithMeans | 0.77279 | 0.59720 | 0.60449 | 0.83454 | 20.06934 |
KNNWithZScore | 0.76543 | 0.58589 | 0.59611 | 0.82940 | 21.54288 |
KNNBaseline | 0.75132 | 0.56448 | 0.58576 | 0.82631 | 24.56300 |
SVD | 0.67199 | 0.45156 | 0.53195 | 0.88548 | 6.83804 |
SVDpp | 0.75998 | 0.57757 | 0.59878 | 0.82622 | 277.93482 |
NMF | 0.81857 | 0.67006 | 0.64244 | 0.78013 | 7.11345 |
SlopeOne | 0.85808 | 0.73631 | 0.67414 | 0.77514 | 12.66350 |
CoClustering | 0.91066 | 0.82930 | 0.71226 | 0.73465 | 2.96320 |
SVDがスコアも良く、実行時間も短いという結果になりました。
フィシルコムのテックブログです。マーケティングSaaSを開発しています。 マイクロサービス・AWS・NextJS・Golang・GraphQLに関する発信が多めです。 カジュアル面談はこちら(ficilcom.notion.site/bbceed45c3e8471691ee4076250cd4b1)から
Discussion