兴趣度计算
前面学习了关联规则的相关知识,接下来我们来学习协同过滤。
什么是协同过滤呢?我们以一个简单的问题来了解一下:如果你现在想看个电影,但你不知道具体看哪部,你会怎么做?
大部分的人会问问周围的朋友,看看最近有什么好看的电影推荐。朋友有很多,每一个都去问吗?
不是,我们一般更倾向于从口味比较类似的朋友那里得到推荐。
协同过滤是利用集体智慧的一种方法,但又稍有不同,它保留了个体的特征。简单来说是利用兴趣相投的、拥有共同经验的群体的喜好来向用户进行推荐他感兴趣的东西。
从这里我们可以发现协同过滤的核心问题就是:如何找到用户的兴趣?如何找到兴趣相投的其他用户?
协同过滤算法是最早也是最著名的推荐方法,主要有两类:基于用户的协同过滤算法(user-based collaboratIve filtering),和基于物品的协同过滤算法(item-based collaborative filtering)。简单的说就是:人以类聚,物以群分。
总结来说,协同过滤推荐分为三步:
第一步:发现用户的偏好
第二步:找到相似的用户或物品
第三步:计算推荐
电影推荐案例
接下来我们就以一个案例来了解一下基于用户的系统过滤:
假设有A-G,7个人分别看了如图所示的电影并且给电影有如下评分(5分最高,没看过的不评分),我们目的是要向A用户推荐一部电影
首先我们来理一下思路:我们要基于A看过的电影,向A推荐他未看过的电影
协同过滤算法
协同过滤的整体思路只有两步,非常简单:寻找相似用户邻居,用相似邻居偏好来推荐物品
寻找相似用户,有很多种方法可以用来判断相似性,,其实是对于电影品味的相似,也就是说需要将A与其他几位用户做比较,判断是不是品味相似。
用我们刚刚讲过的协同过滤的三步来分析这个问题,首先我们根据用户A的评分发现,他偏爱像老炮儿这样性质的电影;然后我们要根据他的爱好找到类似用户?如何寻找类似用户呢?如何找到跟用户A一样偏爱老炮儿这种电影的用户呢?从数学的角度出发,我们是不是可以理解为计算两个用户之间的相似度,越相似,证明他们口味越接近。
那么问题来了,相似度计算方式很多,我们采用什么样的相似度计算方法呢?
通过相似度的计算算法找出相似用户、物品
常见的相似度计算算法有:欧几里德距离,余弦相似度,皮尔逊相关系数,杰卡德相似系数等
很多同学会说采用效果最好的相似度计算方法,那怎么知道那种相似度计算方法最好呢?这需要大家在学习和使用过程中去分辨。
欧式距离案例
这里我们使用“欧式距离”来作为相似度计算方法。把每一部电影看成N维空间中的一个维度,这样每个用户对于电影的评分相当于维度的坐标,那么每一个用户的所有评分,相当于就把用户固定在这个N维空间的一个点上,然后利用欧几里德距离计算N维空间两点的距离。距离越短说明品味越接近。
在本例中用户A只看过两部电影(《老炮儿》和《唐人街探案》),那我们只能通过这两部电影来判断用户A的品味了,也就是说我们要计算A和其他几位用户的欧式距离
变换方法为:相似性 = 1/(1+欧几里德距离),这个相似性会落在【0,1】区间内,1表示完全品味一样,0表示完全品味不一样。这时我们就可以找到哪些人的品味和A最为接近了,计算后如下:
相似性:B-0.27,C-0.28,D-0.27,E-0.50,F-0.25,G-0.47
可见,E的口味与A最为接近,其次是G
前面我们说过欧式距离越近,越相似。对相似度的衡量我们习惯用[0,1]表示,1表示完全一样,0表示完全不一样。
当相似度为1时,我们可以理解为此时欧式距离为0;当相似度为0时,我们可以理解为此时欧式距离为无穷大
因此,欧式距离要与相似性要做一个转换,变换方法为:相似性 = 1/(1+欧几里德距离)
通过计算我们的出用户A与其他用户的相似度分别为:
B:0.27,C:0.28,D:0.27,E:0.50,F:0.25,G:0.47
从这些数据中我们可以看出E用户与A用户最为相似,相似度为50%,其次是G用户,相似度为47%
计算推荐
接下来我们就要进行协同过滤推荐的第三步:计算推荐。
如何计算推荐呢?我们把用户的相似度看作一个电影评分的一个加权相似,对A未看过的电影计算其他电影的加权评分,从而判别用户A会感兴趣的电影。
我们将用户A与其他用户的相似度以及其他用户对A未看过的电影分别看作两个矩阵,计算其他电影的加权评分就是计算两个矩阵对应位置的数的乘积。
除了加权,还要做少量的计算:总分是每个电影加权评分的总和,总相似度是对这个电影有评分的人的相似性综合,推荐度是总分/总相似性,目的是排除看电影人数对于总分的影响
最后一行就是电影的推荐度(因为是根据品味相同的人打分加权算出的分,可以近似认为如果A看了这部电影,预期的评分会是多少)
有了电影的加权得分,通常做法还要设定一个阈值,如果超过了阈值再给用户推荐,要不怎么推荐都是烂片,如果这里我们设置阈值为4,那么最终推荐给A的电影就是《寻龙诀》。
如果我们把一开始的评分表的行列调换,其他过程都不变,那么就变成了把电影推荐给合适的受众。因此,要根据不同场景选择不同的思考维度。
基于用户协同过滤的缺点
基于用户的协同过滤算法,一般应用于用户较少,物品比较多,时效性比较强的场合,比如新闻推荐等
代码实操
完整代码下载:
机器学习-推荐系统(基于用户).ipynb-机器学习文档类资源-CSDN下载
主要代码展示
from collections import defaultdict critics = defaultdict(dict) for i in range(df.shape[0]): critics[str(df.iloc[i,0])][df.iloc[i,2]]=df.iloc[i,3] name=input("请输入你的学号:") n=int(input("请输入你要推荐的数目:")) result=getRecommendations(critics,name) X1=[] X2=[] X3=[] x1=0 x2=0 x3=0 for i in result: # print(df.iloc[df[df['产品名称']==i[1]].index[1],1]) if df.iloc[df[df['产品名称']==i[1]].index[0],1]=='酒店' and x1<n: X1.append(i) x1+=1 elif df.iloc[df[df['产品名称']==i[1]].index[0],1]=='餐饮' and x2<n: X2.append(i) x2+=1 elif df.iloc[df[df['产品名称']==i[1]].index[0],1]=='景区' and x3<n: X3.append(i) x3+=1 elif x1==n and x2==n and x3==n: break print("酒店推荐你选择这几家:") print(X1[:n]) print() print("餐饮推荐你选择这几家:") print(X2[:n]) print() print("景区推荐你选择这几家:") print(X3[:n])