构建推荐系统的一种推荐方法:协同过滤。利用他人的喜好进行推荐,也就是说,是大家一起产生的推荐。
其工作原理是:如果要推荐一本书给你,我会在网站上找一个跟你类似的用户,然后将他喜欢的书推荐给你。
那么,如何找到相似的用户呢?
由于简书不支持公式的编辑和现实,包含计算公式的版本可以这里观看。
曼哈顿距离
对于二维模型,每个用户可以用(x,y)的点表示,两个用户之间的距离可以表示为:
|x1 - x2| + |y1 - y2|
def manhattan(rating1, rating2):
"""计算曼哈顿距离。rating1和rating2参数中存储的数据格式均为
{'The Strokes': 3.0, 'Slightly Stoopid': 2.5}"""
distance = 0
for key in rating1:
if key in rating2:
distance += abs(rating1[key] - rating2[key])
return distance
欧几里德距离:
对于二维模型,两个用户之间的距离表示为两个点之间的直线距离。可以利用勾股定理进行计算。
从二维到N维:
优势:
- 曼哈顿距离 和 欧几里德距离的计算速度较快;
劣势: - 1.在数据不完整的情况下,计算结果的准确性不好。
- 2.不同的用户评分标准不同,会导致“分数膨胀”问题。
前面提到的计算两个用户之间的距离,只考虑了二维的情况,即每个用户只对两件物品进行了评价。实际情况中一个用户评价的物品个数远不止2,需要将用户距离的计算扩展到基于N件物品的情况,即从二维到N维。
在N维的情况下,上面提到的距离计算方法同样适用。
Minkowski 距离:
这种方法是曼哈顿距离 和 欧几里德距离的一般化形式。r = 1 就是曼哈顿距离 ,* r = 2* 则对应着欧几里德距离。
def minkowski(rating1, rating2, r):
distance = 0
for key in rating1:
if key in rating2:
distance += pow(abs(rating1[key] - rating2[key]), r)
return pow(distance, 1.0 / r)
皮尔森相关系数:
用一条直线进行拟合。皮尔逊相关系数用于衡量两个变量之间的相关性,它的值在-1至1之间,1表示完全吻合,-1表示完全相悖。
from math import sqrt
def pearson(rating1, rating2):
sum_xy = 0
sum_x = 0
sum_y = 0
sum_x2 = 0
sum_y2 = 0
n = 0
for key in rating1:
if key in rating2:
n += 1
x = rating1[key]
y = rating2[key]
sum_xy += x * y
sum_x += x
sum_y += y
sum_x2 += pow(x, 2)
sum_y2 += pow(y, 2)
# 计算分母
denominator = sqrt(sum_x2 - pow(sum_x, 2) / n) * sqrt(sum_y2 - pow(sum_y, 2) / n)
if denominator == 0:
return 0
else:
return (sum_xy - (sum_x * sum_y) / n) / denominator
余弦相似度
将数据以向量的形式保存,通过余弦函数计算两个向量之间的相似度。
cos(x,y) = (x . y) / (||x|| × ||y||)
向量的基础知识可以参考这里。
余弦相似度的范围从1到-1,1表示完全匹配,-1表示完全相悖。
距离算法的选择
- 如果数据存在“分数膨胀”问题,就使用皮尔森相关系数。
- 如果数据比较“密集”,变量之间基本都存在公有值,且这些距离数据是非常重要的,那就使用欧几里得或曼哈顿距离。
- 如果数据是稀疏的,则使用余弦相似度。
K最邻近算法
如果我们只依靠最相似的一个 用户来做推荐,如果这个用户有些特殊的偏好,就会直接反映在推荐内容里。解决方法之一是找寻多个相似的用户,这里就要用到K最邻近算法了。
在协同过滤中可以使用K最邻近算法来找出K个最相似的用户,以此作为推荐的基础。不同的应用有不同的K值,需要做一些实验来调校。
网友评论