前言:
今天朋友们对“协同过滤推荐算法python代码”大约比较珍视,同学们都需要知道一些“协同过滤推荐算法python代码”的相关知识。那么小编在网络上收集了一些关于“协同过滤推荐算法python代码””的相关知识,希望咱们能喜欢,咱们快快来学习一下吧!一、需求描述
在某个电影点评平台上,收集到用户对电影的评分数据,即user, item, rating
现在需要在用户的浏览界面上展示推荐电影列表,要求每个用户的推荐列表要体现个性化
二、数据读取
本次实战的电影点评数据,来自surprise的内置数据集,可以直接从surprise平台上下载,字段为:users items, ratings, timestamps。
三、数据拆分
数据拆分的方式至少有三种,这里选择最常用的“训练集-测试集”拆分方法。
四、选择模型算法
为了输出推荐列表,求最近邻的协同过滤是最常用的模型算法,这里考虑相对成熟的KNN模型。KNN模型有四种算法,这个阶段需要先从中选出最佳算法:
算法函数:surprise.prediction_algorithms.knns.KNNBasic()
参数:
k=40: 需要考虑的近邻数。过小则敏感度高,但可能过拟合;过大则稳定性强,但不够敏感,且计算量大——需要调参
min_k=1: 合并时需要考虑的最低近邻数
sim_options={}: 相似度计算中的一些选项,dict格式
"name"="MSD": 用于计算相似度的方法——需要调参
msd: 欧氏距离; cosine: 余弦相似度; pearson: 皮尔森系数; pearson_baseline: 减去基线分值后的皮尔森系数
"user_based"=True: 是计算User还是Item的相似度——根据业务进行选择
"min_support": 要求计算相似度时User/Item数量的最低阈值,当|Iuv|<min_support时,sim(u,v)=0,默认为0——需要调参
比如:要计算用户A和用户B的相似度,要求二者至少评分了3部电影(min_support=3),否者二者相似度默认为0
"shrinkage"=100: pearson_baseline方式时使用的参数
verbose=True: 是否给出详细输出
算法函数:surprise.prediction_algorithms.knns.KNNWithMeans(k=40, min_k=1, sim_options={}, verbose=True, **kwargs)
算法函数:surprise.prediction_algorithms.knns.KNNWithZScore(k=40, min_k=1, sim_options={}, verbose=True, **kwargs)
算法函数:surprise.prediction_algorithms.knns.KNNBaseline(k=40, min_k=1, sim_options={}, bsl_options={}, verbose=True, **kwargs)
有区别的参数:
bsl_options={}: KNNBaseline的一些选项,dict格式
"reg_i": item的正则化参数,默认为10
"reg_u": user的正则化参数,默认为15
"n_epochs": ALS(Alternating Least Squares)的迭代次数,默认为10
根据业务特征选择UserCF/ItemCF:
1、电影喜好,通常是比较个性化的,每种电影都可能有人喜欢,所以电影评分人数通常会呈现出长尾分布
2、电影观看,相对于电视剧、小说,属于时长比较短的事务,所以同一个用户更愿意尝试不同类型的电影,喜好更多变
基于上述特征,电影推荐的协同过滤算法倾向于选择ItemCF
计算精确率和召回率
自定义函数precision_recall_at_k
精确率:系统推荐的样本中实际命中的比例,即TP/(TP+FP)
召回率:实际命中的样本中被推荐给用户的比例,即TP/(TP+FN)
比较四种算法的效果评估指标
结果解析:
准确率(accuracy)是残差,越小越好
精确率(precisions)、召回率(recalls),越大越好
KNNBasic的准确率最大,召回率最小,虽然精确率最大,综合来看基本可以视为效果最差
KNNBaseline的准确率最小,精确率第二,召回率略低(召回率的重要度一般最小),综合来看基本可以视为效果最好
基于效果评价指标,选择KNNBaseline
五、模型调参
所谓模型调参,是指在前面选定的模型基础上,对模型内的参数作不同选项的测算,以选出最优的参数值
调参函数:surprise.model_selection.search.GridSearchCV()
参数:
algo_class: 需要进行调参的算法类,这次我们选择了KNNBaseline
param_grid: 调参字典
measures=["rmse", "mae"]: 模型效果评价指标,比较可惜,这个函数只提供了准确率(accuracy)的评估指标
cv=None: 数据集的拆分方式,这个函数的调参采用网格搜索交叉验证,所以默认使用KFold(n_splits=5)
refit=False: 是否使用全部数据重新拟合筛选出的最佳模型
return_train_measures=False: 是否同时计算训练集的效果评价指标
n_jobs=1, pre_dispatch=u'2*n_jobs', joblib_verbose=0
子函数:
.fit(data): 使用指定的数据进行参数搜索
.predict(*args): 使用得到的最佳模型进行预测,只在refit非False时有效
.test(testset, verbose=False): 使用得到的最佳模型进行验证,前面已经有交叉验证的,这里其实没必要
.best_estimator: 以dict形式给出,评价指标为key(measures)的,各种评价指标下的最佳模型
.best_score: 以dict形式给出,各种评价指标下的最佳评分
.best_params: 以dict形式给出,各种评价指标下的最佳模型参数设定
.best_index: 以dict形式给出,各种评价指标下的最佳模型所对应的索引值
.cv_results: 以dict形式给出,所有KFold()拆分的数据集的评价结果,可直接导入pandas数据框中,以作后续的进一步分析
六、将模型结果应用于推荐
使用情景(一):用户在前端输入一部电影名称,系统返回并展示10部相似的推荐电影
1、准备ID-Name的对应字典,即输入推荐电影的iid,会输出对应的电影名称
2、求相似的推荐电影
在最佳模型里得出top_n电影id,此时的id是inner_id(即模型训练时的id)
需要转化成raw_id(即u.item中的id),才能映射中字典中的电影名称
trainset提供了to_inner_uid(), to_inner_iid(), to_raw_uid(), to_raw_iid()函数用于inner_id和raw_id相互转
使用情景(二):有过评分行为的用户点开推荐界面,系统返回并展示10部符合用户个性化偏好的推荐电影
1、计算每个用户的电影评分预估值,并按降序排列
2、用户登录,系统获得用户ID,并返回对应的TOP_N item
3、对照电影名称字典,映射出Top_N的电影名称