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

推荐系统的相关知识我们已在前文中提到,在这篇文章中,我们会介绍如何用Python来搭建一个简单的推荐系统。

本文使用的数据集是MovieLens数据集,该数据集由明尼苏达大学的Grouplens研究小组整理。它包含1,10和2亿个评级。 Movielens还有一个网站,我们可以注册,撰写评论并获得电影推荐。接下来我们就开始实战演练。

在这篇文章中,我们会使用Movielens构建一个基于item的简易的推荐系统。在开始前,第一件事就是导入pandas和numPy。

import pandas as pd import numpy as np import warnings warnings.filterwarnings(‘ignore‘)

接下来,我们使用pandas read_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之间。

现在我们再创建一个dataframe,其中包含每部电影的平均评分和评分数量。之后,这些评分将用来计算电影之间的相关性。相关性是一种统计指标,表示两个或多个变量一起波动的程度。相关系数越高,电影越为相似。

以下例子将使用Pearson相关系数 (Pearson correlation coefficient),该数字介于-1和1之间,1表示正线性相关,-1表示负相关, 0表示没有线性相关。也就是说,具有零相关性的电影完全不相似。

我们会使用pandas groupby 功能来创建dataframe。按照标题对数据集进行分组,并计算其平均值获得每部电影的平均评分。

ratings = pd.DataFrame(df.groupby(‘title‘)[‘rating‘].mean()) ratings.head()

接下来我们创建number_of_ratings列,这样就能看到每部电影的评分数量。完成这步操作后,就可以看到电影的平均评分与电影获得的评分数量之间的关系。五星级电影很有可能只被一个人评价,而这种五星电影在统计上是不正确的。

因此,在构建推荐系统时,我们需要设置阈值。我们可以使用pandas groupby功能来创建新列,然后按标题栏分组,使用计数函数计算每部电影的评分。之后,便可以使用head()函数查看新的dataframe。

rating [‘number_of_ratings‘] = df.groupby(‘title‘)[‘rating‘].count() ratings.head()

接下来我们使用pandas绘制功能来绘制直方图,显示评级的分布:

import matplotlib.pyplot as plt %matplotlib inline ratings[‘rating‘].hist(bins=50)

可以看到,大多数电影的评分都在2.5-4之间。通过类似的方法还可以将number_of_ratings列可视化。

ratings[‘number_of_ratings‘].hist(bins=60)

从上面的直方图中可以清楚地看出,多数电影的评分都很低,评分最高的电影是一些非常有名的电影。

现在让我们再来看一下电影评级与评分数量之间的关系。我们可以使用seaborn绘制散点图,然后使用jointplot()函数执行此操作。

import seaborn as sns sns.jointplot(x=‘rating‘, y=‘number_of_ratings‘, data=ratings)

从图中我们可以看出,电影平均评分与评分数量之间呈正相关关系,电影获得的评分数量越多,其平均评分越高。

创建基于item的简易推荐系统

接下来我们会快速创建一个基于item的简单的推荐系统。

首先,我们需要将数据集转换为矩阵,电影标题为列,user_id为索引,评级为值。完成这一步,我们将得到一个dataframe,其中列是电影标题,行是用户ID。每列代表所有用户对电影的所有评级。评级为NAN表示用户未对这部电影评分。

我们可以用该矩阵来计算单个电影的评级与矩阵中其余电影的相关性,该矩阵可以通过pandas pivot_table实现。

movie_matrix = df.pivot_table(index =‘user_id‘,columns =‘title‘,values =‘rating‘) movie_matrix.head()

接下来让我们找到评分数量最多的电影,并选择其中的两部电影。然后使用pandas sort_values并将升序设置为false,以便显示评分最多的电影。然后使用head()函数来查看评分数目最多的前十部电影。

ratings.sort_values(‘number_of_ratings‘, ascending=False).head(10)

假设一个用户曾看过Air Force One(1997)和Contact(1997),我们想根据这两条观看记录向该用户推荐其他类似的电影,那么这一点可以通过计算这两部电影的评级与数据集中其他电影的评级之间的相关性来实现。第一步是创建一个dataframe,其中包含来自movie_matrix的这些电影的评级。

AFO_user_rating = movie_matrix[‘Air Force One (1997)‘] contact_user_rating = movie_matrix[‘Contact (1997)‘]

Dataframe可以显示user_id和这两部电影的评分。

AFO_user_rating.head() contact_user_rating.head()

使用pandas corwith功能计算两个dataframe之间的相关性。有了这一步,就能够获得每部电影的评级与Air Force One电影的评级之间的相关性。

similar_to_air_force_one = movie_matrix.corrwith(AFO_user_rating)

可以看到,Air Force One电影和Till There Was You(1997)之间的相关性是0.867。这表明这两部电影之间有很强的相似性。

similar_to_air_force_one.head()

还可以计算Contact(1997)的评级与其他电影评级之间的相关性,步骤同上:

similar_to_contact = movie_matrix.corrwith(contact_user_rating)

可以从中发现,Contact(1997)和Till There Was You(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(inplace=True) corr_AFO.head()

上面这两个dataframe分别展示了与Contact(1997)和Air Force One(1997)电影最相似的电影。然而,问题出现了,有些电影的实际质量非常低,但可能因为一两位用户给他们5星评级而被推荐。

这个问题可以通过设置评级数量的阈值来解决。从早期的直方图中看到,评级数量从100开始急剧下降。因此可以将此设置为阈值,但是也可以考虑其他合适的值。为此,我们需要将两个dataframe与rating datframe中的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()

现在,我们就能得到与Air Force One(1997)最相似的电影,并把这些电影限制在至少有100条评论的电影中,然后可以按相关列对它们进行排序并查看前10个。

corr_AFO [corr_AFO [‘number_of_ratings‘]> 100] .sort_values(by =‘correlation‘,ascending = False).head(10)

我们注意到Air Force One(1997)与自身相关性最高,这并不奇怪。下一部与Air Force One(1997)最相似的电影是Hunt for Red October,相关系数为0.554。

显然,通过更改评论数量的阈值,我们可以按之前的方式得到不同的结果。限制评级数量可以让我们获得更好的结果。

现在重复上边的步骤,可以看到与Contact(1997)电影最相关的电影:

corr_contact [corr_contact [‘number_of_ratings‘]> 100] .sort_values(by =‘Correlation‘,ascending = False).head(10)

Contact(1997)最相似的电影是Philadelphia(1993),相关系数为0.446,有137个评级。所以,如果有人喜欢Contact(1997),我们可以向他们推荐上述电影。

以上是构建推荐系统的一种非常简单的方法,但并不符合行业标准。后续的话我们可以通过构建基于存储器的协同过滤系统来改进该系统。在这种情况下,将数据划分为训练集和测试集,使用诸如余弦相似性来计算电影之间的相似性;或者构建基于模型的协作过滤系统,然后使用Root Mean Squared Error(RMSE)等技术评估模型。

Github: mwitiderrick/simple-recommender-

文章来源:How to build a Simple Recommender System in Python

(以上内容由第四范式先荐整理发布)

原文地址:https://blog.51cto.com/13945147/2427200

时间: 2024-10-30 22:58:02

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

如何用python写一个简单的find命令

对一个运维来说可能会经常去查找目录下的一些文件是否存在,最常用的就是find命令,它不仅可以查找文件也可以查找目录,find命令用法 查找文件 [[email protected] opt]# find /usr/ -type f -name df /usr/bin/df 查找目录 [[email protected] opt]# find /usr/ -type d -name python /usr/share/gcc-4.8.2/python 现在就讲一些如何用python实现这个简单功能

如何用python写一个简单的12306抢票软件

所谓抢票实际上是在开始放票的一瞬间第一个发出请求并点击预订.作为程序员的我们,完全可以让程序来做这件事.我花了几个小时写了一个demo.用到的工具集有:Python3.6, Selenium, chromdriver. 程序本身就是流程性的东西,没有什么可介绍的.代码如下 #coding=utf-8 from selenium import webdriver from time import sleep import traceback TICKET_URI = 'https://kyfw.1

【译】使用python创建一个简单的restful风格的webservice应用

这是一个如何使用python快速构建简单restful风格webservice的应用教程. 1.分析rest路由规则 rest风格的服务通常使用web.py来创建服务器端脚本,一般情况下包含两个url路径: 一个是为了查询所有用户,一个是为了查询单个用户. 例如下面的url: http://localhost:8080/users http://localhost:8080/users/{id} 2.搭建web.py环境 首先你应该安装web.py模块到你的python环境下.如果你之前没有的话

【龙书笔记】用Python实现一个简单数学表达式从中缀到后缀语法的翻译器(采用递归下降分析法)

上篇笔记介绍了语法分析相关的一些基础概念,本篇笔记根据龙书第2.5节的内容实现一个针对简单表达式的后缀式语法翻译器Demo. 备注:原书中的demo是java实例,我给出的将是逻辑一致的Python版本的实现. 在简单后缀翻译器代码实现之前,还需要介绍几个基本概念. 1. 自顶向下分析法(top-down parsing) 顾名思义,top-down分析法的思路是推导产生式时,以产生式开始符号作为root节点,从上至下依次构建其子节点,最终构造出语法分析树.在具体实现时,它会把输入字符串从左到右

不到100行代码实现一个简单的推荐系统

似乎咱的产品七,八年前就想做个推荐系统的,就是类似根据用户的喜好,自动的找到用户喜欢的电影或者节目,给用户做推荐.可是这么多年过去了,不知道是领导忘记了还是怎么了,连个影子还没见到. 而市场上各种产品的都有了推荐系统了.比如常见的各种购物网站京东,亚马逊,淘宝之类的商品推荐,视频网站优酷的的类似影片推荐,豆瓣音乐的音乐推荐...... 一个好的推荐系统推荐的精度必然很高,能够真的发现用户的潜在需求或喜好,提高购物网詀的销量,让视频网站发现用户喜欢的收费电影... 可是要实现一个高精度的推荐系统不

用nodejs搭建一个简单的服务器

使用nodejs搭建一个简单的服务器 nodejs优点:性能高(读写文件) 数据操作能力强 官网:www.nodejs.org 验证是否安装成功:cmd命令行中输入node -v 如果显示版本号表示安装成功 [常用命令] 切换盘符 d:进入文件夹 cd nodejs返回上一级目录 cd..清屏 cls展示目录 dir复制文件名 选中右键--复制历史操作 上箭头 执行文件 node 文件名(在文件文件夹目录中)停止命令行 ctrl+c nodejs可以使用的ECMAScript.读写文件.数据库操

python中一个简单的webserver

python中一个简单的webserver 2013-02-24 15:37:49 分类: Python/Ruby 支持多线程的webserver 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #!/usr/bin/python from SocketServer import ThreadingMixIn from BaseHTTPServer import HTTPServer,BaseHTTPRequestHandler cla

【Python】一个简单的例子

问题描述: Python基础篇 参考资料: (1)http://www.cnblogs.com/octobershiner/archive/2012/12/04/2801670.html (2)http://www.cnblogs.com/itech/archive/2010/06/20/1760345.html 例子: 求解Fibonacci glb_var.py gl_count=1 path.py # coding:utf-8 ''' Created on 2014-4-28 @autho

学生成绩管理后台第二项任务:初步建模,搭建一个简单的网站

负责人:程琳茹 合伙人:李玉婷 签约员工:闫玉荣 前言:学生成绩管理后台,看起来是一个简单的项目,但是对于我们今后的发展很重要,建设一个管理后台有很多方法,这里我们主要使用Rstudio,在之后的文章中,会详细给出我们小组完成项目的过程与遇到的问题,欢迎大家借鉴,此外,同学们要积极参与讨论. 项目步骤:1.熟悉与安装Rstudio,并且配置好R内部环境. 2.建立好文件所存放的位置与确保文档可以正常使用. 3.搭建一个简单的网站,分别分为server.R端口与ui.R端口. 4.搭建好网站后,插