您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 管理学资料 > python简单推荐系统(含完整代码)
似乎咱的产品七,八年前就想做个推荐系统的,就是类似根据用户的喜好,自动的找到用户喜欢的电影或者节目,给用户做推荐。可是这么多年过去了,不知道是领导忘记了还是怎么了,连个影子还没见到。而市场上各种产品的都有了推荐系统了。比如常见的各种购物网站京东,亚马逊,淘宝之类的商品推荐,视频网站优酷的的类似影片推荐,豆瓣音乐的音乐推荐……一个好的推荐系统推荐的精度必然很高,能够真的发现用户的潜在需求或喜好,提高购物网詀的销量,让视频网站发现用户喜欢的收费电影…可是要实现一个高精度的推荐系统不是那么容易的,netflix曾经悬赏高额奖金寻找能给其推荐系统的精确度提高10%的人,可见各个公司对推荐系统的重视和一个好的推荐系统确实能带来经济效益。下面咱以电影电视的推荐系统为例,一步一步的来实现一个简单的推荐系统吧,由于比较简单,整个推荐系统源码不到100行,大概70-80行吧,应该很容易掌握。为了快速开发原型,咱采用Python代码来演示1.推荐系统的第一步,需要想办法收集信息不同的业务,不同的推荐系统需要收集的信息不一样针对咱要做的电影推荐,自然是每个用户对自己看过的电影的评价了,如下图所示:KaiZhou对Friends打分是4分,对BedtimeStories打分是3分,没有对RoboCop打分ShuaiGe没有对Friends打分,对BedtimeStories打分是3.5分……为简单,咱将此数据存成csv文件,形成一个二维的矩阵,假设存在D:\train.csv,数据如下:Name,Friends,BedtimeStories,DawnofthePlanetoftheApes,RoboCop,Fargo,CougarTownKaiZhou,4,3,5,,1,2ShuaiGe,,3.5,3,4,2.5,4.5MeiNv,3,4,2,3,2,3xiaoxianrou,2.5,3.5,3,3.5,2.5,3fengzhi,3,4,,5,3.5,3meinv,,4.5,,4,1,mincat,3,3.5,1.5,5,3.5,3alex,2.5,3,,3.5,,4先从csv文件中加载二维矩阵,代码如下:defload_matrix():matrix={}f=open(d:\\train.csv)columns=f.readline().split(',')forlineinf:scores=line.split(',')foriinrange(len(scores))[1:]:matrix[(scores[0],columns[i])]=scores[i].strip(\n)returnmatrixmatrix=load_matrix()printmatrix:,matrixload_matrix()解析csv文件,返回一个dictionary,该dictionary以(行名,列名)为索引数据有了,下面咱就正式开始干活了,推荐系统要干些什么呢?咱以电影推荐来说,推荐系统需要解决的几个主要问题:1)判断两个电影,两个观影人之间的相似度2)找到和某影片最相似的影片,或找到和某观影人有同样兴趣的人3)找到某观影人可能喜欢的电影,或找到对某影片感兴趣的人2.推荐系统的基础,判断相似度针对咱的电影推荐来说,就是判断两个电影,两个观影人之间的相似度。2.1欧几里德距离计算相似度最简单的,最容易理解的就是欧几里德距离.那么,什么是欧几里德距离,怎么用呢?请对比评价数据,看下图:咱用两个电影Fargo和CougrTown来取例图中X轴代表电影Fargo,Y轴代表电影CougrTown,KaiZhou给电影Fargo打1分,CougrTown打2分,画到图上同理,咱可以将ShuaiGe和MeiNv的数据点都画到图上很明显,咱可以看出KaiZhou与MeiNv离得近,与ShuaiGe离得远,所以说KaiZhou与MeiNv的兴趣更相近.用数学式子表达出来就是:KaiZhou与MeiNv的距离的平方:(2–1)^2+(3–2)^2=2KaiZhou与ShuaiGe的距离的平方:(2.5–1)^2+(4.5–2)^2=8.528.5,所以KaiZhou与MeiNv比ShuaiGe兴趣更近.这就是利用欧几里得距离来判断相似度两个用户对所有电影的评价相似度的和,就是两用户的相似度2.2归一化处理为了方便比较处理后的数据,一般还需要对计算出来的结果进行归一化处理。数据标准化(归一化)处理是数据挖掘的一项基础工作,不同评价指标往往具有不同的量纲和量纲单位,这样的情况会影响到数据分析的结果,为了消除指标之间的量纲影响,需要进行数据标准化处理,以解决数据指标之间的可比性。原始数据经过数据标准化处理后,各指标处于同一数量级,适合进行综合对比评价。上面的介绍太学术化了吧,不容易懂,我的理解:归一化化就是要把你需要处理的数据经过处理后(通过某种算法)限制在你需要的一定范围内。简单的说,我们希望,处理后的数据取值范围在0-1之间.在数学上有很多归一化处理的方法常用的有1)min-max标准化(Min-MaxNormalization)也称为离差标准化,是对原始数据的线性变换,使结果值映射到[0–1]之间。2)Z-score标准化方法这种方法给予原始数据的均值(mean)和标准差(standarddeviation)进行数据的标准化。经过处理的数据符合标准正态分布,即均值为0,标准差为1咱可以根据需要选择,不过,针对咱这系统采用的是欧几里德距离,咱可以用下面的更简单的公式:假设计算出来的欧几里德距离为:n1/(1+n)当距离为0,归一化后的值为:1距离越大,归一化后的值越接近0有了上面的基础知识之后,下面的代码就水到渠成了defsim_distance(matrix,row1,row2):columns=set(map(lambdal:l[1],matrix.keys()))si=filter(lambdal:matrix.has_key((row1,l))andmatrix[(row1,l)]!=andmatrix.has_key((row2,l))andmatrix[(row2,l)]!=,columns)iflen(si)==0:return0sum_of_distance=sum([pow(float(matrix[(row1,column)])-float(matrix[(row2,column)]),2)forcolumninsi])return1/(1+sqrt(sum_of_distance))printsim_distance(matrix,KaiZhou,ShuaiGe)3)找到和和某观影人有同样兴趣的人,某影片最相似的影片a.有了上面的代码,找到和某用户有同样兴趣的人,就非常简单了。只要将某用户和其它所有用户的相似度计算出来,排下序就行了。deftop_matches(matrix,row,similarity=sim_distance):rows=set(map(lambdal:l[0],matrix.keys()))scores=[(similarity(matrix,row,r),r)forrinrowsifr!=row]scores.sort()scores.reverse()returnscoresperson=KaiZhouprinttopmatchfor:,personprinttop_matches(matrix,person)b.找到和某影片相似的影片,这个需要稍微变化下。咱的输入数据是以用户为行数据,影片为列数据,只要改成以影片为行数据,用户为列数据,一样的调用。所以需要一个函数,将矩阵转置deftransform(matrix):rows=set(map(lambdal:l[0],matrix.keys()))columns=set(map(lambdal:l[1],matrix.keys()))transform_matrix={}forrowinrows:forcolumnincolumns:transform_matrix[(column,row)]=matrix[(row,column)]returntransform_matrix找到和Friends相似的影片:trans_matrix=transform(matrix)printtrans:,trans_matrixfilm=Friendsprinttopmatchfor:,filmprinttop_matches(trans_matrix,film)4.找到某观影人可能喜欢的电影,找到对某影片感兴趣的人最理想的是找到两个相似度一样的人,可以认为某个人喜欢的电影,另外那个也喜欢。但是这样有它的缺点,比较好的办法是把所有人的数据都用上,方法如下:1.先计算所有人和KaiZhou的相似度2.对于KaiZhou没有看过,没有评分,而其它人有评分的的影片,将其评分与相似度相乘,得到的值再除以相似度之和3.排序咱先以给KaiZhou推荐影片为例来说明,DawnofthePlanetoftheApes和RoboCop这两部影片KaiZhou都没有看,我们该推荐他看哪部呢?假设我们计算出来KaiZhou与其它人的相似度如下:[(0.3333333333333333,‘MeiNv’),(0.29429805508554946,‘xiaoxianrou’),(0.2857142857142857,‘alex’),(0.2553967929896867,‘mincat’),(0.252650308587072,‘ShuaiGe’),(0.2474401533514073,‘fengzhi’)]即KaiZhou与MeiNv相似度为0.3333333333333333,与xiaoxiaorou相似度为0.29429805508554946,其它类似…那么计算DawnofthePlanetoftheApes对KaiZhou的推荐值过程如下:1.找到ShuaiGe对DawnofthePlanetoftheApes的评价值乘以ShuaiGe与KaiZhou的相似度:3*0.2526503085870722.找到MeiNv对DawnofthePlanetoftheApes的评价值乘以其与KaiZhou的相似度:2*0.33333333333333333.找到xiaoxianrou对DawnofthePlanetoftheApes的评价值乘以其与KaiZhou的相似度:3*0.294298055085549464.fengzhi没有对DawnofthePlanetoftheApes评价,不用计算5.找到mincat对DawnofthePlanetoftheApes的评价值乘以其与KaiZhou的相似度:1.5*0.25539679298968676.alex没有对DawnofthePlanetoftheApes评价,不用计算7.将1,2,3,5步的计算结果相加得到:3*0.252650308587072+2*0.3333333333333333+3*0.29429805508554946+1.5*0.2553967929896867=2.69060694716906128.将1,2,3,5步的参与计算的人的相似度相加:0.252650308587072+0.3333333333333333+0.29429805508554946+0.2553967929896867=1.13567848999564169.将第7步结果除以第8步的结果,就是DawnofthePlanet对KaiZhou的推荐值:2.6906069471690612/1.1356784899956416=2.369162549851047同样的方法,计算出来RoboCop对KaiZhou的推荐值为:3.9277923180363326所以RoboCop应该对KaiZhou的吸引力比DawnofthePlanetoftheApes更大.代
本文标题:python简单推荐系统(含完整代码)
链接地址:https://www.777doc.com/doc-6245476 .html