MovieLens个性化电影推荐系统实战(三):个性化电影推荐(推荐算法)

发布时间:2024-12-07 06:53

个性化推荐算法:Amazon Kindle Unlimited,Kobo的推荐系统 #生活乐趣# #阅读乐趣# #电子书推荐#

一、前言

        在拥有了上篇文章得出的聚类结果后,本文章将构建推荐系统,为用户个性化推荐电影.

        本系列文章使用MovieLens数据集进行机器学习综合实战。本文主要记录的是用户个性化电影推荐。由于平台有点鸡肋,不能显示运行代码块的结果,大家可以在评论区留言或私信我获取有结果显示的源码。文章和代码均是小编原创,为小编的期末实训项目。仅供大家参考,请勿全篇抄袭本文!!

数据集链接:https://files.grouplens.org/datasets/movielens/ml-1m.zip

文章目录:

MovieLens个性化电影推荐系统实战(一):数据探索(数据预处理、数据可视化)_movielens数据集下载-CSDN博客

MovieLens个性化电影推荐系统实战(二):用户群体划分(聚类)-CSDN博客

资料:

MovieLens个性化电影推荐系统实战——系列文章资料-CSDN博客

文章资源,百度网盘永久有效:

链接: https://pan.baidu.com/s/1P45bvnp6ezE-0J06Wjx2sQ?pwd=csdn 提取码: csdn 复制这段内容后打开百度网盘手机App,操作更方便哦

二、协同过滤算法

        协同过滤(CF)简单来说就是根据已有数据来推测未知的数据的一种算法。在推荐系统中协同过滤算法一般是指在海量用户中发掘一小部分和你品味比较类似的,在协同过滤中,这些用户成为你的邻居,从而基于这些邻居的信息为你推荐商品。基于启发式的协同过滤算法可以分为基于用户的协同过滤算法和基于物品的协同过滤算法。

        协同过滤算法核心步骤:收集用户偏好;找到相似的用户或物品;计算并推荐。

        在协同过滤中,一个重要的环节就是如何选择合适的相似度计算方法,常用的相似度计算方法包括皮尔逊相关系数等。

        另一个重要的环节就是计算用户对未评分商品的预测分值。

三、矩阵分解算法

        矩阵分解算法,同时兼具了协同过滤,隐语义分析和有监督学习的特性,加上矩阵分解的易实现性和高拓展性,成为推荐领域非常经典的算法。

        说到矩阵分解,往往最先想到的是解析几何中奇异值分解(SVD)这一概念。实际上,推荐系统中最初的矩阵分解算法也正是源于此。我们可以对用户-项目矩阵A直接进行矩阵分解。

        然后通过选取用品序列中前k大的奇异值,就可以对原先较大的矩阵A进行压缩。要预测用户对物品的评分时,便可以直接从矩阵A中相对应的元素得到。其中,矩阵A存储用户对物品的评分。

四、用户个性化推荐

1、基于近邻的协同过滤算法

        使用surprise库中的四种基于近邻的模型,分别为KNN基础版(KNNBasic)、KNN均值(KNNWithMeans)、KNN中心化(KNNWithZScore)、KNN基准线(KNNBaseline)。使用网格搜索这四种模型的最佳超参数,然后进行模型的对比。

        四种模型网格搜索的超参数:k为邻域数量;name为相似度计算方法的名称;user_based为基于用户或基于电影进行相似度计算。

        实验结果如下表所示:

近邻的模型实验结果

模型

RMSE1

RMSE2

FCP

MAE

KNNBasic

0.907

0.899

0.602

0.692

KNNWithMeans

0.890

0.884

0.655

0.674

KNNWithZScore

0.893

0.888

0.658

0.670

KNNBaseline

0.863

0.856

0.669

0.655

        实验结果中的RMSE1为模型网格搜索或随机搜索出的最低RMSE,RMSE2是模型在测试集上的RMSE。

        根据实验结果最优模型为KNNBaseline,各项评估指标都要优于其他模型。其搜索出的最优k为50,最优似度计算方法为msd,基于电影进行相似度计算。

2、矩阵分解模型

        使用surprise库中的两种矩阵分解模型,分别为SVD和非负矩阵分解(NMF)。使用随机搜索这两种模型的最佳参数,然后进行模型的对比[11]。

        SVD模型随机搜索的超参数:n_factors为矩阵分解中的因子数;n_epochs为训练模型的迭代次数;lr_all为学习率。

        NMF模型随机搜索的超参数:n_factors;n_epochs;reg_pu为用户特征矩阵的正则化参数;reg_qi为物品特征矩阵的正则化参数。

        实验结果如下表所示:

近邻的模型实验结果

模型

RMSE1

RMSE2

FCP

MAE

SVD

0.873

0.868

0.671

0.667

NMF

1.034

1.028

0.667

0.778

        实验结果表明SVD模型要优于NMF模型。实验中SVD最优因子数为100,最优迭代次数为60,最优学习率为0.05。

3、其他模型

        使用surprise库中的其他三种模型,以增加模型的对比目标,找到最好的推荐模型。分别为共轭梯度(CoClustering)、SlopeOne和BaselineOnly。由于CoClustering和SlopeOne无法进行网格搜索和随机搜索,所有只对BaselineOnly进行网格搜索。

        BaselineOnly网格搜索的超参数:method为基线算法的方法;reg为正则化参数;n_epochs为迭代次数。

        实验结果如下表所示:

近邻的模型实验结果

模型

RMSE1

RMSE2

FCP

MAE

CoClustering

\

0.937

0.643

0.726

SlopeOne

\

0.898

0.658

0.686

BaselineOnly

0.866

0.860

0.678

0.661

        实验结果表明,BaselineOnly模型比其他模型更好。其搜索出的最佳method为als,最佳正则化参数为5,最佳迭代次数为40。

4、用户个性化推荐电影

        综上实验结果,KNNBaseline、BaselineOnly和SVD模型的效果相比于其他模型较好。使用这些模型进一步训练以达到个性化推荐的效果。

        首先需要按照基于影评的用户群体划分结果,拆分训练集和测试集,且均为6个部分,即同簇用户的评分信息成为一个数据集。然后使用KNNBaseline、BaselineOnly和SVD模型分别对训练集的6个部分进行网格搜索或随机搜索得到每部分数据集的最优模型以及最佳超参数。得到三个模型在各个用户群体的训练集上的最低RMSE的结果如下表所示:

各用户群体最佳模型的RMSE

用户群体

KNNBaseline

BaselineOnly

SVD

1

0.978

0.962

0.982

2

0.802

0.808

0.828

3

0.891

0.901

0.908

4

0.839

0.851

0.845

5

0.901

0.898

0.896

6

0.951

0.958

0.970

        用户群体1的训练集使用BaselineOnly模型训练的结果较好,RMSE为0.962,该模型的最佳method为als,最佳正则化参数为5,最佳迭代次数为40。

        用户群体2、用户群体3、用户群体4和用户群体6的训练集使用KNNBaseline模型训练的结果较好,RMSE分别为0.802、0.891、0.839以及0.951,其搜索出的最优k均为50,最优似度计算方法均为msd,均为基于电影进行相似度计算。

        用户群体5的训练集使用SVD模型训练的结果较好,RMSE为0.901,该模型的最优因子数为400,最优迭代次数为60,最优学习率为0.1。

        使用测试集进行模型的评估,得到的评估结果如下表所示:

各用户群体最佳模型评估结果

用户群体

RMSE

FCP

MAE

1

0.968

0.593

0.750

2

0.811

0.633

0.618

3

0.869

0.610

0.654

4

0.870

0.594

0.687

5

0.890

0.658

0.692

6

0.935

0.619

0.731

        实验结果表明,每个用户群体的推荐模型性能是有差异的,会造成不同群体的用户的个性化推荐效果存在差异。

        设计一个程序,输入用户id,判断该用户属于哪个用户群体,再调用该群体的推荐模型,最后为给用户个性化推荐。

        示例输入用户id为17,判断该用户属于用户群体3,为该用户推荐的5部电影如下表所示:

个性化推荐电影表单Top5

电影名

预测评分

Serenity

4.500

Psycho

4.498

In the Mood For Love  

4.489

Gladiator

4.488

Eternal Sunshine of the Spotless Mind

4.458

五、关键代码

        由于实验的代码太乱,小编为大家整理出来以下几个部分的代码

1、数据集导入、数据集划分

from surprise import Reader, Dataset

from surprise.model_selection import train_test_split,GridSearchCV,RandomizedSearchCV

reader = Reader(line_format='user item rating', sep=',')

data = Dataset.load_from_file('ratings1.csv', reader=reader)

trainset, testset = train_test_split(data, test_size=0.2)

2、根据用户群体划分数据集

        注意这里需要上篇文章的聚类结果。

clustering_df=pd.DataFrame(columns=['user_id','label'])

clustering_df['user_id']=avg_ratings_by_genre.index.values

clustering_df['label']=labels

cluster_dict = clustering_df.groupby('label')['user_id'].apply(list).to_dict()

cluster_train=dict()

for cluster,id_ls in cluster_dict.items():

user_ratings = []

for user_id in id_ls:

user_inner_id = trainset.to_inner_uid(str(user_id))

user_rating = trainset.ur[user_inner_id]

user_ratings.extend([(trainset.to_raw_uid(user_inner_id), trainset.to_raw_iid(item_inner_id), rating)

for (item_inner_id, rating) in user_rating])

df = pd.DataFrame(user_ratings, columns=['user_id', 'item_id', 'rating'])

reader = Reader(rating_scale=(0.5, 5))

new_data = Dataset.load_from_df(df, reader)

cluster_train[cluster]=new_data

        测试集划分数据集的代码:

cluster_test=dict()

for cluster,id_ls in cluster_dict.items():

ids=list(map(str,id_ls))

target_user_data = [data for data in testset if data[0] in ids]

cluster_test[cluster]=target_user_data

3、寻找最优模型

        每个用户群体都需要经过三个模型的训练,也就是说,这里一共训练了18次。

best_KBL_dict=dict()

param_grid = {'k': [30,40,50], 'sim_options': {'name': ['msd', 'cosine', 'pearson'], 'user_based': [True, False]}}

for cluster,id_ls in cluster_dict.items():

best_model_info=dict()

grid_search = GridSearchCV(KNNBaseline, param_grid, measures=['rmse'], cv=5)

grid_search.fit(cluster_train[cluster])

best_model_info['best_aglo']=grid_search.best_estimator['rmse']

best_model_info['best_params']=grid_search.best_params['rmse']

best_model_info['score']=grid_search.best_score['rmse']

best_KBL_dict[cluster]=best_model_info

best_SVD_dict=dict()

param_grid = {'n_factors': [100,200,300,400],'n_epochs':[30,40,50,60],'lr_all': [0.001,0.005,0.01,0.05,0.1]}

for cluster,id_ls in cluster_dict.items():

best_model_info=dict()

grid_search = RandomizedSearchCV(SVD, param_grid, measures=['rmse'], cv=5,n_iter=3,random_state=42)

grid_search.fit(cluster_train[cluster])

best_model_info['best_aglo']=grid_search.best_estimator['rmse']

best_model_info['best_params']=grid_search.best_params['rmse']

best_model_info['score']=grid_search.best_score['rmse']

best_SVD_dict[cluster]=best_model_info

from surprise import BaselineOnly

best_BO_dict=dict()

param_grid = {'bsl_options': {'method': ['als', 'sgd'],

'reg_u': [5,10,15],

'reg_i': [5,10,15],

'n_epochs': [20,30,40]}}

for cluster,id_ls in cluster_dict.items():

best_model_info=dict()

grid_search = GridSearchCV(BaselineOnly, param_grid, measures=['rmse'], cv=5)

grid_search.fit(cluster_train[cluster])

best_model_info['best_aglo']=grid_search.best_estimator['rmse']

best_model_info['best_params']=grid_search.best_params['rmse']

best_model_info['score']=grid_search.best_score['rmse']

best_BO_dict[cluster]=best_model_info

         找到各个用户群体最佳推荐模型。

cluster_aglo=[]

def find_best_aglo(model_lsit,clu):

best_score=1000

for model_dict in model_lsit:

if best_score>model_dict[clu]['score']:

best_score=model_dict[clu]['score']

best_model=model_dict[clu]

cluster_aglo.append(best_model)

return cluster_aglo

for cluster,id_ls in cluster_dict.items():

find_best_aglo([best_BO_dict,best_KBL_dict,best_SVD_dict],cluster)

4、编写推荐程序

        利用上面得到的各个用户群体的最优推荐模型,构建推荐系统。

data = data.build_full_trainset()

movies=pd.read_csv("movies.csv")

movies=dict(zip(list(map(str,movies['movie_id'].values.tolist())),movies['title'].values.tolist()))

def recommendation_movie(uid):

for cluster,id_ls in cluster_dict.items():

if uid in id_ls:

uid_cluster=cluster

break

else:

return 'user no in clusters'

model=cluster_aglo[uid_cluster]['best_aglo']

test_set = data.build_anti_testset()

test_set = [item for item in test_set if item[0] == str(uid)]

predictions = model.test(test_set)

top_predictions = sorted(predictions, key=lambda x: x.est, reverse=True)

top_movies = top_predictions[:5]

top_movies_rating=[]

for item in top_movies:

top_movies_rating.append([item.iid,item.est])

print("The user {} is in cluster {}".format(uid,uid_cluster+1))

print("Top 5 recommended movies for user", uid)

for movie_id, rating in top_movies_rating:

print(movies[movie_id], "estimated rating:", rating)

使用示例:

recommendation_movie(17)

其结果为:

        推荐程序对用户进行判断属于哪个用户群体之中,再使用该用户群体的推荐模型对目标用户进行电影推荐。

六、总结

        各群体的电影推荐模型的实验结果都不是很好,RMSE均在0.8到0.9左右,表示预测值与真实值有0.8到0.9左右的误差,可以考虑进一步优化推荐算法,以提高预测准确性,增加用户满意度。这里的预测值为用户可能会为推荐电影打的评分,真实值为用户看过推荐电影后,为推荐电影打的评分。

        导致RMSE较高的原因,数据分布不均衡可能性较大。例如,用户群体1的用户较少,从而导致用户群体1的数据较少,模型训练的效果就会变差,导致用户群体1的RMSE较高。也有用户与电影之间的交互数据非常稀疏的情况,即大多数用户与某个电影之间没有交互行为。应该收集更多用户与电影的交互数据,以减少数据稀疏性问题。除了用户电影交互数据外,可以考虑使用其他特征,如用户属性、电影信息等,来提高电影推荐系统的准确性。在实际情况中,可以使用电影评分预测区间来代替具体的评分预测值。

        根据模型的原理,其符合个性化的推荐,能根据用户的历史行为和偏好进行个性化推荐。需要通过用户反馈和调研来收集用户对推荐结果的满意度,了解用户对推荐结果的实际感受和评价,以改进模型。

        本系列的文章到这里就结束了,感谢大家的支持,希望大家给一个宝贵的点赞和收藏!!

        感谢大家对小编的一路陪伴!!你们的点赞和收藏就是小编创作的动力!!

        我们一起期待后续更精彩的文章!!

网址:MovieLens个性化电影推荐系统实战(三):个性化电影推荐(推荐算法) https://www.yuejiaxmz.com/news/view/403238

相关内容

[推荐系统]个性化推荐的十大挑战
Python推荐系统实战:构建个性化推荐系统
推荐系统的个性化推荐:满足用户的个性需求
推荐系统:个性化推荐的算法与实践
推荐系统与个性化推荐
个性化推荐的十大挑战
推荐系统详解——个性化推荐与非个性化推荐
推荐系统的魅力:个性化推荐算法的发展趋势
推荐系统与个性化服务
个性化推荐系统对提高转化率的影响研究

随便看看