当前位置: 首页 > 后端技术 > Python

如何用Python搭建一个简单的推荐系统?

时间:2023-03-25 21:57:32 Python

推荐系统相关知识在上一篇文章中已经提到,本文将介绍如何使用Python搭建一个简单的推荐系统。本文使用的数据集是MovieLens数据集,由明尼苏达大学的Grouplens研究组整理而成。它包含1、10和2亿个评级。Movielens还有一个网站,我们可以在上面注册、写评论和获得电影推荐。接下来我们就要开始实战演练了。在本文中,我们将使用Movielens构建一个简单的基于项目的推荐系统。在开始之前,首先要导入pandas和numPy。importpandasaspdimportnumpyasnpimportwarningswarnings.filterwarnings('ignore')接下来,我们使用pandasread_csv()加载数据集。数据集以制表符分隔,因此我们将t传递给sep参数。然后,使用names参数传入列名。df=pd.read_csv('u.data',sep='\t',names=['user_id','item_id','rating','titmestamp'])接下来,检查表头并检查正在处理的内容处理过的数据。df.head()如果我们能看到电影的标题而不仅仅是ID就好了。然后加载电影片名并将其与该数据集合并。movie_titles=pd.read_csv('Movie_Titles')movie_titles.head()由于item_id列是相同的,我们可以在这一列上合并这些数据集。df=pd.merge(df,movie_titles,on='item_id')df.head()数据集中的每一列代表:?user_id-评价电影的用户的ID。?item_id-电影的ID。?rating-用户为电影提供的评分,介于1和5之间。?timestamp-电影被评分的时间。?title-电影标题。可以使用describe或info命令获取数据集的简要描述。如果您想真正了解您正在使用的数据集,这一点非常重要。df.describe()可以看到数据集共有100003条记录,电影的平均评分在3.52-5之间。现在让我们创建另一个数据框,其中包含每部电影的平均评分和评分数量。然后使用这些评级来计算电影之间的相关性。相关性是一种统计量度,表示两个或多个变量一起波动的程度。相关系数越高,电影越相似。以下示例将使用Pearson相关系数,它是一个介于-1和1之间的数字,其中1表示正线性相关,-1表示负相关,0表示无线性相关。也就是说,零相关的电影根本不相似。我们将使用pandasgroupby函数来创建数据框。按标题对数据集进行分组并取平均值以获得每部电影的平均评分。ratings=pd.DataFrame(df.groupby('title')['rating'].mean())ratings.head()接下来我们创建number_of_ratings列,这样我们就可以看到每部电影的评分数。完成此操作后,您将能够看到电影的平均评分与电影收到的评分数量之间的关系。很有可能一部5星电影只会被一个人打分,而那种5星电影在统计上是不正确的。因此,在构建推荐系统时,我们需要设置一个阈值。我们可以使用pandasgroupby函数创建一个新列,然后按标题列分组,并使用count函数计算每部电影的评分。之后,可以使用head()函数查看新数据框。rating['number_of_ratings']=df.groupby('title')['rating'].count()ratings.head()接下来我们使用pandasplot函数绘制显示评分分布的直方图:importmatplotlib.pyplot作为plt%matplotlibinlineratings['rating'].hist(bins=50)你可以看到大多数电影的评分在2.5-4之间。number_of_ratings列也可以用类似的方式可视化。ratings['number_of_ratings'].hist(bins=60)从上面的直方图中可以清楚地看出,大多数电影的收视率都很低,而收视率最高的电影是一些非常有名的电影。现在让我们再来看看电影评分和评分数量之间的关系。我们可以使用seaborn绘制散点图,然后使用jointplot()函数来执行此操作。importseabornassnssns.jointplot(x='rating',y='number_of_ratings',data=ratings)从图中我们可以看出,电影平均评分与评分次数呈正相关关系,越多ratingsthemoviegets越多,平均评分越高。创建一个简单的基于项目的推荐系统接下来,我们将快速创建一个简单的基于项目的推荐系统。首先,我们需要将数据集转换为一个矩阵,其中电影标题为列,user_id为索引,评分为值。在这一步之后,我们将有一个数据框,其中列是电影标题,行是用户ID。每列代表所有用户对电影的所有评分。NAN的评级意味着用户尚未对电影进行评级。我们可以使用这个矩阵来计算单个电影的评分与矩阵中其余电影的相关性,这可以用pandaspivot_table来实现。movie_matrix=df.pivot_table(index='user_id',columns='title',values='rating')movie_matrix.head()接下来让我们找到评分最高的电影并选择其中两部。然后使用pandassort_values将ascending设置为false,以便显示评分最高的电影。然后使用head()函数查看评分最高的前十部电影。ratings.sort_values('number_of_ratings',ascending=False).head(10)假设用户看过空军一号(1997)和接触者(1997),我们想根据这两个观看情况向用户推荐其他类似的记录电影,这可以通过计算这两部电影的评分与数据集中其他电影的评分之间的相关性来完成。第一步是创建一个数据框,其中包含来自movie_matrix的这些电影的评分。AFO_user_rating=movie_matrix['空军一号(1997)']contact_user_rating=movie_matrix['Contact(1997)']Dataframe可以显示这两部电影的user_id和评分。AFO_user_rating.head()contact_user_rating.head()使用pandascorwith函数计算两个数据帧之间的相关性。通过这一步,可以获得每部电影的评分与空军一号电影的评分之间的相关性。similar_to_air_force_one=movie_matrix.corrwith(AFO_user_rating)可以看出,空军一号电影与TillThereWasYou(1997)的相关性为0.867。这表明两部电影之间有很强的相似性。similar_to_air_force_one.head()也可以计算Contact(1997)和其他电影评分的相关性,步骤同上:similar_to_contact=movie_matrix.corrwith(contact_user_rating)可以从Contact(1997)和TillThere中查到WasYou(1997)存在非常强的相关性(0.904)。similar_to_contact.head()如前所述,并非所有用户都对所有电影进行了评分,因此,此矩阵中存在很多缺失值。为了让结果看起来更有吸引力,去掉这些空值,并将相关结果转换成一个dataframe。corr_contact=pd.DataFrame(similar_to_contact,columns=['Correlation'])corr_contact.dropna(inplace=True)corr_contact.head()corr_AFO=pd.DataFrame(similar_to_air_force_one,columns=['correlation'])corr_AFO.dropna(就地=True)corr_AFO.head()上面的两个数据框分别显示了与Contact(1997)和AirForceOne(1997)最相似的电影。然而,问题来了,有些电影实际上质量很差,但可能会被推荐,因为一两个用户给了他们5星评级。这个问题可以通过设置评分数量的阈值来解决。从早期的直方图中可以看出,评分数从100开始急剧下降。因此可以将其设置为阈值,但也可以考虑其他合适的值。为此,我们需要将两个数据帧与评级数据帧中的number_of_ratings列连接起来。corr_AFO=corr_AFO.join(ratings['number_of_ratings'])corr_contact=corr_contact.join(ratings['number_of_ratings'])corr_AFO.head()corr_contact.head()现在,我们可以得到最相似的电影,并将它们限制为至少有100条评论的电影,然后您可以按相关列对它们进行排序并查看前10名。corr_AFO[corr_AFO['number_of_ratings']>100].sort_values(by='correlation',ascending=False).head(10)我们注意到空军一号(1997)与自身的相关性最高,这并不奇怪。下一个与空军一号(1997)最相似的电影是追捕红色十月,相关系数为0.554。显然,通过改变评论数量的阈值,我们可以得到和以前不同的结果。限制评级的数量可以让我们取得更好的结果。现在重复上述步骤以查看与Contact(1997)电影最相关的电影:corr_contact[corr_contact['number_of_ratings']>100].sort_values(by='Correlation',ascending=False).head(10)和The与Contact(1997)最相似的电影是Philadelphia(1993),相关系数为0.446,评分为137。所以,如果有人喜欢接触(1997),我们可以向他们推荐以上电影。以上是构建推荐系统的一种非常简单的方法,但是不符合行业标准。未来,我们可以通过构建基于内存的协同过滤系统来改进系统。在这种情况下,将数据分为训练集和测试集,使用如余弦相似度来计算电影之间的相似度;或者构建一个基于模型的协同过滤系统,然后使用均方根误差(RMSE)等技术对模型进行评估。Github:mwitiderrick/simple-recommender-文章来源:HowtobuildaSimpleRecommenderSysteminPython(以上内容为第四范式优先推荐)