slope one 协同过滤:
1.详细算法过程:
顾客 | 项目 A | 项目 B | 项目 C |
---|---|---|---|
John | 5 | 3 | 2 |
Mark | 3 | 4 | 未评分 |
Lucy | 未评分 | 2 | 5 |
dis(A-B)代表A的评分平均比B高出的值
so:
dis(A-B)=((5-3)+(3-4))/2=0.5
dis(A-C)=(5-2)/1=3
w(A,B)代表A的评分向量和B的评分向量的元素取与交集,有评分数据时元素值true,未评分时false。
so:
w(A,B)=2
w(A,C)=1
预测Lucy对A的评分ans。
Lucy->B=2,Lucy->C=5.
so:
Lucy -> A
= { [ Lucy -> B + dis(A-B) ] * w(A,B)+[ Lucy->C+dis(A-C) ]*w(A,C) } / (w(A,B)+w(A,C))
= { [ 2 + 0.5] * 2+[5+3]*1} / (2+1)
= 4.33
2.时间复杂度分析:
假设count(user)=N,count(item)=M。
则size(评分矩阵)=N*M
从1中可以看出,要计算某个user(Lucy)对某个item(A)的评分时,我们关键是要得到 dis(A-i)的数据。i =B,C,……
计算一次 dis(A-B)的时间复杂度=O(N)
因为i有M-1个取值。所以计算一次dis(A-i),i=B,C……的时间复杂度O(M*N)。
所以计算所有的i,j=A,B,C…… dis(i-j)的时间复杂度O(N*M^2)。一般情况下 N>>M。
但是dis可以离线O(M*N)计算。
离线计算出一个数组 dis_array[i][j] 供在线代码O(1)耗时的调用即可。
同理可得w也可以离线计算得 w_array[A][B] 供在线代码O(1)耗时调用。
值得注意的是对于求dis的O(N*M^2)其实是保守估计,因为往往评分矩阵式稀疏矩阵,可以进行一些分解来降低时间复杂度。
3.slopeone的优劣:
slopeone是一个非常简单甚至是种傻瓜算法。
但是换句话说,实用的算法往往都是最简单的。
爱因斯坦的质能方程
E=mc^2,多么简单的一个公式却是爱因斯坦最著名的公式,不仅是相对论的巨大支撑,甚至是宇宙学说的根基。
言归正传,因为slopeone计算item的dis时只考虑了有共同评分时的项。
可以修正在协同过滤时候计算item相关度用线性回归计算时过度拟合的问题。