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


Posted in Python onMay 10, 2019

什么是推荐系统

维基百科这样解释道:推荐系统属于资讯过滤的一种应用。推荐系统能够将可能受喜好的资讯或实物(例如:电影、电视节目、音乐、书籍、新闻、图片、网页)推荐给使用者。

本质上是根据用户的一些行为数据有针对性的推荐用户更可能感兴趣的内容。比如在网易云音乐听歌,听得越多,它就会推荐越多符合你喜好的音乐。

推荐系统是如何工作的呢?有一种思路如下:

用户 A 听了 收藏了 a,b,c 三首歌。用户 B 收藏了 a, b 两首歌,这时候推荐系统就把 c 推荐给用户 B。因为算法判断用户 A,B 对音乐的品味有极大可能一致。

推荐算法分类

最常见的推荐算法分为基于内容推荐以及协同过滤。协同过滤又可以分为基于用户的协同过滤和基于物品的协同过滤
基于内容推荐是直接判断所推荐内容本身的相关性,比如文章推荐,算法判断某篇文章和用户历史阅读文章的相关性进行推荐。

基于用户的协同过滤就是文章开头举的例子。

基于物品的协同过滤:

假设用户 A,B,C 都收藏了音乐 a,b。然后用户 D 收藏了音乐 a,那么这时候就推荐音乐 b 给他。

动手打造自己的推荐系统

这一次我们要做的是一个简单的电影推荐,虽然离工业应用还差十万八千里,但是非常适合新手一窥推荐系统的内部原理。数据集包含两个文件:ratings.csv 和 movies.csv。

# 载入数据
import pandas as pd
import numpy as np
df = pd.read_csv('data/ratings.csv')
df.head()

ratings.csv 包含四个维度的数据:

  • userId:打分用户的 ID
  • movieId: 被打分电影的 ID
  • rating: 用户给电影的打分,处于[1,5]
  • timestamp: 电影被打分的时间

要推荐电影还需要有电影的名字,电影名字保存在 movies.csv 中:

movies = pd.read_csv('data/movies.csv')
movies.head()

将 ratings.csv 和 movies.csv 的数据根据 movieId 合并。

df = pd.merge(df, movie_title, on='movieId')
df.head()

我们这次要做的推荐系统的核心思路是:

  • 根据所有用户评分判断所有电影与用户 a 已观看的某部电影 A 的相似度
  • 给用户 a 推荐相似度高且评分高的电影

所以我们要先有所有用户对所有电影的评分的列联表:

movie_matrix = df.pivot_table(index = 'userId', columns = 'title' ,values = 'rating')
movie_matrix.head()

假设用户 A 观看的电影是 air_force_one (1997),则计算列联表中所有电影与 air_force_one (1997) 的相关性。

AFO_user_rating = movie_matrix['Air Force One (1997)']
simliar_to_air_force_one = movie_matrix.corrwith(AFO_user_rating)

这样我们就得到了所有电影与 air_force_one (1997)的相关性。

但是,直接对这个相关性进行排序并推荐最相关的电影有一个及其严重的问题:

ratings = pd.DataFrame(df.groupby('title')['rating'].mean())#计算电影平均得分
ratings['number_of_ratings'] = df.groupby('title')['rating'].count()
import matplotlib.pyplot as plt
%matplotlib inline
ratings['number_of_ratings'].hist(bins = 60);

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

上图是电影被评分次数的直方图,可以看到大量的电影评分次数不足10次。评分次数太少的电影很容易就被判断为高相关性。所以我们要将这部分的评分删掉。

corr_AFO = pd.DataFrame(similar_to_air_force_one, columns = ['Correlation'])
corr_AFO.dropna(inplace = True)
corr_contact = corr_contact.join(ratings['number_of_ratings'],how = 'left',lsuffix='_left', rsuffix='_right')
corr_AFO[corr_AFO['number_of_ratings']>100].sort_values(by = 'Correlation',ascending = False).head()

这样我们就得到了一个与 air_force_one (1997) 高相关的电影列表。但是高相关有可能评分低(概率低),再从列表里挑几部平均得分高的电影推荐就好了。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
python根据时间生成mongodb的ObjectId的方法
Mar 13 Python
Python基于回溯法子集树模板解决旅行商问题(TSP)实例
Sep 05 Python
Python数据结构与算法之图的广度优先与深度优先搜索算法示例
Dec 14 Python
Python类的继承和多态代码详解
Dec 27 Python
JavaScript实现一维数组转化为二维数组
Apr 17 Python
python实现图片文件批量重命名
Mar 23 Python
详解利用django中间件django.middleware.csrf.CsrfViewMiddleware防止csrf攻击
Oct 09 Python
python 将list转成字符串,中间用符号分隔的方法
Oct 23 Python
对python 合并 累加两个dict的实例详解
Jan 21 Python
python opencv将图片转为灰度图的方法示例
Jul 31 Python
pymysql模块的使用(增删改查)详解
Sep 09 Python
jupyter 中文乱码设置编码格式 避免控制台输出的解决
Apr 20 Python
Python和Java的语法对比分析语法简洁上python的确完美胜出
May 10 #Python
Python3列表内置方法大全及示例代码小结
May 10 #Python
详解python 爬取12306验证码
May 10 #Python
详解用python写一个抽奖程序
May 10 #Python
python实现小球弹跳效果
May 10 #Python
基于python实现百度翻译功能
May 09 #Python
python使用time、datetime返回工作日列表实例代码
May 09 #Python
You might like
PHP5中使用DOM控制XML实现代码
2010/05/07 PHP
php 下载保存文件保存到本地的两种实现方法
2013/08/12 PHP
PHP中的替代语法介绍
2015/01/09 PHP
php使用Image Magick将PDF文件转换为JPG文件的方法
2015/04/01 PHP
php判断是否连接上网络的方法实例详解
2016/12/14 PHP
[原创]PHP实现字节数Byte转换为KB、MB、GB、TB的方法
2017/08/31 PHP
PHP unlink与rmdir删除目录及目录下所有文件实例代码
2018/02/07 PHP
jQuery Ajax请求状态管理器打包
2012/05/03 Javascript
js/jquery获取浏览器窗口可视区域高度和宽度以及滚动条高度实现代码
2012/12/17 Javascript
jquery prop的使用介绍及与attr的区别
2013/12/19 Javascript
jQuery判断checkbox(复选框)是否被选中以及全选、反选实现代码
2014/02/21 Javascript
Javascript 学习笔记之 对象篇(二) : 原型对象
2014/06/24 Javascript
JS选项卡动态替换banner图片路径的方法
2015/05/11 Javascript
javascript日期格式化方法小结
2015/12/17 Javascript
很不错的两款Bootstrap Icon图标选择组件
2016/01/28 Javascript
jQuery simpleModal插件的使用介绍
2016/08/30 Javascript
ajax与json 获取数据并在前台使用简单实例
2017/01/19 Javascript
10 种最常见的 Javascript 错误(频率最高)
2018/02/08 Javascript
Angular PWA使用的Demo示例
2019/01/31 Javascript
使vue实现jQuery调用的两种方法
2019/05/12 jQuery
jQuery实现图片下载代码
2019/07/18 jQuery
JS浮点数运算结果不精确的Bug解决
2019/08/01 Javascript
javascript 使用sleep函数的常见方法详解
2020/04/26 Javascript
JavaScript实现简易计算器小功能
2020/10/22 Javascript
Vue+Element-U实现分页显示效果
2020/11/15 Javascript
vue使用element-ui实现表单验证
2020/12/13 Vue.js
[10:14]2018DOTA2国际邀请赛寻真——paiN Gaming不仅为自己而战
2018/08/14 DOTA
python基础教程之简单入门说明(变量和控制语言使用方法)
2014/03/25 Python
python 获取等间隔的数组实例
2019/07/04 Python
python配置文件写入过程详解
2019/10/19 Python
消防应急演练方案
2014/02/12 职场文书
学校体育节班级口号
2015/12/25 职场文书
银行求职信范文
2019/05/13 职场文书
2019旅游导游工作总结
2019/06/27 职场文书
自制短波长线天线频率预选器 - 成功消除B2K之流的镜像
2021/04/22 无线电
Android开发实现极为简单的QQ登录页面
2022/04/24 Java/Android