surpriseに基づく2つの推奨アルゴリズムの実現
6470 ワード
surpriseはscikitシリーズの1つであり、簡単で使いやすく、基礎アルゴリズム、協同フィルタリングアルゴリズム、マトリクス分解(隠語義モデル)など、多くの推奨アルゴリズムをサポートしています.surpriseドキュメント:https://surprise.readthedocs.io/en/stable/getting_started.htmlデータセット:movielens-100 kデータセットデータセットダウンロードアドレス:http://files.grouplens.org/datasets/movielens
1.近傍ベースの方法(協同フィルタリング):user-based,item-based.
1.1ユーザーベースの共同フィルタリングアルゴリズム:
テスト、idが1のユーザーに10本の映画を推薦します:
出力結果は次のとおりです:
1.2物品に基づく協同フィルタリングアルゴリズム:
idが2の映画(GoldenEye(1995))に最も類似度の高い10本の映画を与えた.
推奨結果:
2.隠語的意味に基づく方法(行列分解):SVD.
idが1のユーザーに10本の映画を推薦します.
出力結果は次のとおりです:
補足:GridSearchCVの使用
出力結果0.961300130118{‘n_epochs’:10,‘lr_all’:0.005,‘reg_all’:0.4}
1.近傍ベースの方法(協同フィルタリング):user-based,item-based.
import os, io, collections
import pandas as pd
from surprise import Dataset, KNNBaseline, SVD, accuracy, Reader
from surprise.model_selection import cross_validate, train_test_split
#
# movielens-100k , , 。
data = Dataset.load_builtin('ml-100k')
# # path to dataset filefile_path = os.path.expanduser('~/.surprise_data/ml-100k/ml-100k/u.data')# Reader , line_format ( ), sep reader = Reader(line_format='user item rating timestamp', sep='\t')# data = Dataset.load_from_file(file_path, reader=reader)
data_df = pd.read_csv(file_path, sep='\t', header=None, names=['user','item','rating','timestamp'])
item_df = pd.read_csv(os.path.expanduser('~/.surprise_data/ml-100k/ml-100k/u.item'), sep='|', encoding='ISO-8859-1', header=None, names=['mid','mtitle']+[x for x in range(22)])
#
data_df = data_df.astype(str)
item_df = item_df.astype(str)
# id
item_dict = { item_df.loc[x, 'mid']: item_df.loc[x, 'mtitle'] for x in range(len(item_df)) }
1.1ユーザーベースの共同フィルタリングアルゴリズム:
#
# user-based
user_based_sim_option = {'name': 'pearson_baseline', 'user_based': True}
# item-based
item_based_sim_option = {'name': 'pearson_baseline', 'user_based': False}
# n , , 10 , 。
def get_similar_users_recommendations(uid, n=10):
# ,
trainset = data.build_full_trainset()
#
algo = KNNBaseline(sim_option = user_based_sim_option)
#
algo.fit(trainset)
# id id
inner_id = algo.trainset.to_inner_uid(uid)
# get_neighbors 10
neighbors = algo.get_neighbors(inner_id, k=10)
neighbors_uid = ( algo.trainset.to_raw_uid(x) for x in neighbors )
recommendations = set()
# 5
for user in neighbors_uid:
if len(recommendations) > n:
break
item = data_df[data_df['user']==user]
item = item[item['rating']=='5']['item']
for i in item:
recommendations.add(item_dict[i])
print('
recommendations for user %s:')
for i, j in enumerate(list(recommendations)):
if i >= 10:
break
print(j)
テスト、idが1のユーザーに10本の映画を推薦します:
get_similar_users_recommendations('1', 10)
出力結果は次のとおりです:
1.2物品に基づく協同フィルタリングアルゴリズム:
# n , 。
def get_similar_items(iid, n = 10):
trainset = data.build_full_trainset()
algo = KNNBaseline(sim_option = item_based_sim_option)
algo.fit(trainset)
inner_id = algo.trainset.to_inner_iid(iid)
# get_neighbors n
neighbors = algo.get_neighbors(inner_id, k=n)
neighbors_iid = ( algo.trainset.to_raw_iid(x) for x in neighbors )
recommendations = [ item_dict[x] for x in neighbors_iid ]
print('
ten movies most similar to the %s:' % item_dict[iid])
for i in recommendations:
print(i)
idが2の映画(GoldenEye(1995))に最も類似度の高い10本の映画を与えた.
get_similar_items('2')
推奨結果:
2.隠語的意味に基づく方法(行列分解):SVD.
# SVD , , n 。
def get_recommendations_dict(n = 10):
trainset = data.build_full_trainset()
# ,
testset = trainset.build_anti_testset()
# SVD
algo = SVD()
algo.fit(trainset)
#
predictions = algo.test(testset)
#
print("RMSE: %s" % accuracy.rmse(predictions))
#
user_recommendations = collections.defaultdict(list)
for uid, iid, r_ui, est, details in predictions:
user_recommendations[uid].append((iid, est))
for uid, user_ratings in user_recommendations.items():
user_ratings.sort(key = lambda x: x[1], reverse=True)
user_recommendations[uid] = user_ratings[:n]
return user_recommendations
# 10
user_recommendations = get_recommendations_dict(10)
#
def rec_for_user(uid):
print("recommendations for user %s:" % uid)
#[ item_dict[x[0]] for x in user_recommendations[uid] ]
for i in user_recommendations[uid]:
print(item_dict[i[0]])
idが1のユーザーに10本の映画を推薦します.
rec_for_user('1')
出力結果は次のとおりです:
補足:GridSearchCVの使用
from surprise import SVD
from surprise import Dataset
from surprise.model_selection import GridSearchCV
# Use movielens-100K
data = Dataset.load_builtin('ml-100k')
param_grid = {'n_epochs': [5, 10], 'lr_all': [0.002, 0.005],
'reg_all': [0.4, 0.6]}
gs = GridSearchCV(SVD, param_grid, measures=['rmse', 'mae'], cv=3)
gs.fit(data)
# best RMSE score
print(gs.best_score['rmse'])
# combination of parameters that gave the best RMSE score
print(gs.best_params['rmse'])
出力結果0.961300130118{‘n_epochs’:10,‘lr_all’:0.005,‘reg_all’:0.4}