一、简介:

推荐系统是最常见的数据分析应用之一,包含淘宝、豆瓣、今日头条都是利用推荐系统来推荐用户内容。推荐算法的方式分为两种,一种是根据用户推荐,一种是根据商品推荐,根据用户推荐主要是找出和这个用户兴趣相近的其他用户,再推荐其他用户也喜欢的东西给这个用户,而根据商品推荐则是根据喜欢这个商品的人也喜欢哪些商品区进行推荐,现在很多是基于这两种算法去进行混合应用。本文会用python演示第一种算法,目标是对用户推荐电影。

二、获取数据:

在movielens上,有许多的用户对电影评价数据,可以至(https://grouplens.org/datasets/movielens/)进行下载,下载完后打开资料夹,有个叫u.data的资料夹,打开会看到以下的数据

第一列代表用户ID,第二列代表电影的ID,第三列代表评分(1-5分),第四列是时间戳

三、数据预处理

拿到了原始数据后,我们会发现几个问题,就是1、我根本不需要时间戳。2、同一个用户的评价散落在不连续好几行,不好进行分析。这个时候我们就需要进行数据的预处理,首先观察这份数据发现由于每个用户评价的电影都不相同,可能在200部里随机挑了5-10部来评分,所以如果用表格来显示的话会有很多的空格,这个时候KV型数据储存方式就很好用,利用一个键(key)对应一个值(value),这个时候就可以利用python的字典(dict),他可以记录键值对应。举例来说,我用户ID为‘941’的用户,对电影ID为‘763’的评价是3分,那我只需要储存【941】【763】=3这样就可以了,并把user合并,让界面更美观,如下图

可以看到我把用户ID为‘941’评价的电影都列了出来,后面还跟了评分值,这样我后面在做分析的时候读取数据就比较方便了,下面是数据读取到处理的代码

def load_data():
f = open('u.data')
user_list={}
for line in f:
(user,movie,rating,ts) = line.split('\t')
user_list.setdefault(user,{})
user_list[user][movie] = float(rating)
return user_list

user_list就是我们建立用来分析的名单

三、算法:

这边是使用最简单的欧几里得距离算法,简单来说就是将两人对同一部电影的评价相减平方再开根号,比如A看了蝙蝠侠给了5分,B看了给了5分,但C看了给分,AB距离是0, AC距离是2,可以得知A和B的喜好比较相近,当然现在推荐系统算法很多,这边只是挑了一个比较简单的算法,下面是算法的代码

def calculate():
list = load_data()
user_diff = {}
for movies in list['']:
for people in list.keys():
user_diff.setdefault(people,{})
for item in list[people].keys():
if item == movies:
diff = sqrt(pow(list[''][movies] - list[people][item],2))
user_diff[people][item] = diff
return user_diff

这边挑了其中一位ID为7的用户,我的任务是帮他找出他可能会感兴趣的电影,所以先计算所有用户跟7的距离,由于7跟其他用户都看了不同的电影,所以要先找出共同看过的电影再将所有电影的距离列出来。

接下来再把所有电影的距离取平均值,由于我们想知道的是相似度,相似度与平均值成反比,所以我们将距离倒过来就是相似度,另外为了让相似度这个数介于0~1,所以用了1/(1+距离)这个算法,以下为代码

def people_rating():
user_diff = calculate()
rating = {}
for people in user_diff.keys():
rating.setdefault(people,{})
a = 0
b = 0
for score in user_diff[people].values():
a+=score
b+=1
rating[people] = float(1/(1+(a/b)))
return rating

可以看到虽然代码有点丑,不过还是可以跑出个结果,下面就是结果,可以看到跟所有用户的相似度,可以看到跟ID为12的用户相似度为0.58, 跟ID为258的用户相似度为0.333

现在就是要从这里面找出几个相似度比较高的用户,也很简单,利用sort排个序,再选出前五个,下面为代码

def top_list():
list = people_rating()
items = list.items()
top = [[v[1],v[0]] for v in items]
top.sort(reverse=True)
print(top[0:5])

下面为结果

可以看到第一名就是他自己,然后547和384也和他非常契合,不过45名的相似度就下降的非常的快,现在我们来检视547跟384的菜单吧

我们先来验证一下547跟384跟我们7号用户的相似度为什么这么高,下面代码可以找出547跟7号用户共同看过的电影跟评分

list = load_data()
for k,v in list[''].items():
for kk,vv in list[''].items():
if k == kk:
print(k,v,kk,vv)

跑出来的结果如下

原来他们只共同看了三部电影,给的评分还一样,所以距离才为0

再用同样方法来看384跟7号

可以看到他们也是刚好看了3部一样的电影,给的分数也是一样,有趣的事他们三个都看了ID为258的电影,也都给了4分

接下来就是最后一步了,我们要找出547和384看过但7号没看过的电影,再从里面找出评分高的推荐给7号,下面为代码

def find_rec():
rec_list = top_list()
first = rec_list[1][1]
second = rec_list[2][1]
all_list = load_data()
for k,v in all_list[first].items():
if k not in all_list[''].keys() and v == 5:
print (k) for k,v in all_list[second].items():
if k not in all_list[''].keys() and v == 5:
print (k)

最后跑出来的结果为

以上为547跟384的推荐名单,可以看到316/302/313都是两人共同推荐,代表这三部片应该是很好看,所以如果要推荐给7号用户的话可以选择这三片来推荐。

四、总结

在演练的过程里面我们可以看出这个算法的许多缺点,例如最高分的其实是因为他们共同看过的电影少,分数又刚好相同,很难说明这就是有共同的兴趣,然后相似度的落差太大,前两名都是1,三四名就掉到了0.75,可见三四名应该是与7号共同看过4部电影,但有其中一部的评分差了一分,导致分数骤降,而大部分的用户都集中在0.3-0,5之间,分数曲线极度不平滑。虽然有这些缺点,但这些算出来的推荐结果还是有代表了一定的意义,至少可以代表是与7号用户品味相似的人给出的高分电影,而7号尚未给过评分。

用python做推荐系统(一)的更多相关文章

  1. 用python做推荐系统(二)

    一.简介 继上一篇基于用户的推荐算法,这一篇是要基于商品的,基于用户的好处是可以根据用户的评价记录找出跟他兴趣相似的用户,再推荐这些用户也喜欢的电影,但是万一这个用户是新用户呢?或是他还没有对任何电影 ...

  2. What exactly can you do with Python? Here are Python’s 3 main applications._你能用Python做什么?下面是Python的3个主要应用程序。

    原文链接 Github地址 一.陈述 1,我到底能用Python做什么? 我观察注意到Python三个主要流行的应用: 网站开发: 数据科学——包括机器学习,数据分析和数据可视化: 做脚本语言. 二. ...

  3. 使用python做科学计算

    这里总结一个guide,主要针对刚开始做数据挖掘和数据分析的同学 说道统计分析工具你一定想到像excel,spss,sas,matlab以及R语言.R语言是这里面比较火的,它的强项是强大的绘图功能以及 ...

  4. 12岁的少年教你用Python做小游戏

    首页 资讯 文章 频道 资源 小组 相亲 登录 注册       首页 最新文章 经典回顾 开发 设计 IT技术 职场 业界 极客 创业 访谈 在国外 - 导航条 - 首页 最新文章 经典回顾 开发 ...

  5. [原创博文] 用Python做统计分析 (Scipy.stats的文档)

    [转自] 用Python做统计分析 (Scipy.stats的文档) 对scipy.stats的详细介绍: 这个文档说了以下内容,对python如何做统计分析感兴趣的人可以看看,毕竟Python的库也 ...

  6. 这几天有django和python做了一个多用户博客系统(可选择模板)

    这几天有django和python做了一个多用户博客系统(可选择模板) 没完成,先分享下 断断续续2周时间吧,用django做了一个多用户博客系统,现在还没有做完,做分享下,以后等完善了再慢慢说 做的 ...

  7. 用python做中文自然语言预处理

    这篇博客根据中文自然语言预处理的步骤分成几个板块.以做LDA实验为例,在处理数据之前,会写一个类似于实验报告的东西,用来指导做实验,OK,举例: 一,实验数据预处理(python,结巴分词)1.对于爬 ...

  8. 《用Python做HTTP接口测试》学习感悟

    机缘巧合之下,报名参加了阿奎老师发布在"好班长"的课程<用Python做HTTP接口测试>,报名费:15rmb,不到一杯咖啡钱,目前为止的状态:坚定不移的跟下去,自学+ ...

  9. 使用Python做简单的字符串匹配

    由于需要在半结构化的文本数据中提取一些特定格式的字段.数据辅助挖掘分析工作,以往都是使用Matlab工具进行结构化数据处理的建模,matlab擅长矩阵处理.结构化数据的计算,Python具有与matl ...

随机推荐

  1. day5_python之环境变量设置

    1.设置环境变量 import os,sys print(os.path.abspath(__file__)) #当前py文件的绝对路径 print(os.path.dirname(os.path.a ...

  2. iptables 过滤条件(Matches)

    iptables可让你设置多种过滤条件,但是某些条件需要核心有提供相关功能才行.Iptables本身內建一般性的Internet Protocol (IP) 过滤条件,也就是說,即时沒载入任何扩充模组 ...

  3. jqLite

    一.关于DOM导航的jqLite方法 children() 返回一组子元素.这个方法的jqLite实现不支持jQuery所提供的选择器特性 eq(index) 从一个元素集合中返回指定索引下的元素 f ...

  4. H3C 以太网集线器

  5. 【原生JS】图片预加载之有序预加载

    <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8& ...

  6. 5 分钟入门 Google 最强NLP模型:BERT

    BERT (Bidirectional Encoder Representations from Transformers) 10月11日,Google AI Language 发布了论文 BERT: ...

  7. 2009年NOIP普及组复赛题解

    题目涉及算法: 多项式输出:模拟: 分数线划定:模拟.排序: 细胞分裂:质因数分解: 道路游戏:动态规划. 多项式输出 题目链接:https://www.luogu.org/problem/P1067 ...

  8. 机器学习-RBF高斯核函数处理

     机器学习-RBF高斯核函数处理 SVM高斯核函数-RBF优化 重要了解数学的部分: 协方差矩阵,高斯核函数公式. 个人建议具体的求法还是看下面的核心代码吧,更好理解,反正就我个人而言,烦躁的公式,还 ...

  9. mybatis PageHelper分页插件 和 LRU算法缓存读取数据

    分页: PageHelper的优点是,分页和Mapper.xml完全解耦.实现方式是以插件的形式,对Mybatis执行的流程进行了强化,添加了总数count和limit查询.属于物理分页. 一.首先注 ...

  10. Codeforces Round #187 (Div. 1 + Div. 2)

    A. Sereja and Bottles 模拟. B. Sereja and Array 维护全局增量\(Y\),对于操作1(即\(a_{v_i}=x\))操作,改为\(a_{v_i}=x-Y\). ...