有一个网站,允许用户对她看过的电影打分。一个可能的结果是:
用户1:{电影1=5;电影2=3;电影3=4}
用户2:
用户3:
省略其他用户。
现在网站向一个用户Jack推荐电影,最直接的方式是,找出与Jack品味最接近的人,也就需要把所有用户按照他们与jack的相似度排序。
怎么计算相似度呢?
第一种方式是向量距离,也就是常用的(x1-x2)^2+(y1-y2)^2开根号。
第二种方式是pearson相关系数,利用的是斜率,比如jack喜欢打高分(A:5,B:4)tom喜欢打低分(A:3,B:2),那么还是认为jack和tom是类似的,虽然向量距离相差很远。
----------------------------------------------------------------------------
这样你就找到了与jack类似的人,比如
u1:0.9
u2:0.8
u3:0.2
那么你是否应该直接依赖u1呢,看她推荐的,如果他给某个电影打了高分,而jack又没看过,就推荐?
这样做有两个问题:
1. u1看的电影可能很少,找不到jack没看过的电影;
2. u1可能有独特的口味,对一步烂片可能打高分;
怎么避免这种情况呢,我们还需要对所有电影打分,不过不同用户打分的权重不一样,和我们相似度高的权重高,否则权重低,这样我们就能给所有电影打分,然后推荐分数高的电影给Jack。这样我们就能给某个用户推荐最好的电影。
-----------------------------------------------------------------------------
但是怎么根据一步电影推荐另一部电影呢?可能这个用户什么电影都没看过,但正在浏览一步电影,我们向他推荐类似的电影?
这种情况下,我们需要做一个transform,把之前的数据变成movie:(user1:points)*的格式。然后我们就需要找出电影之间的相似度:
movie1:0.9
movie2:0.8
movie3:0.7
当用户在浏览电影时,系统就会根据相识度列出哪些类似的电影。
----------------------------------------------------------------------------
对于大型购物网站来说,有上千万的商品,一个用户通常只买其中的很小一部分。
user1 {prod1, prod2, prod3….}
如果要计算user和其他user的相似度,计算量非常的巨大。而且每个用户都需要计算一次,实时推荐就比较困难了。
这个时候我们就需要利用基于item的过滤方式。通过获得item:(user:grade)*的数据,利用pearson系数计算出各个item之间的相似度。更重要的是这个item之间的相似度变化比较缓慢,不必频繁的更新。
但是如果只是利用这个相似度,给所有人的推荐就完全一样了,这也不够个性化。怎样才能做出个性化的推荐呢?
假设item的相似度词典是这样的:
item11 | item12 | item13 | item14 | |
item1 | .9 | 0.8 | 0.7 | .6 |
item2 | .8 | .7 | 0.6 | .5 |
用户给item1和item2打了分的,但是对item1x没打分,怎么根据item1和item2的分推算出item1x的分呢?答案就是
item1的分 * item1与它的相似度+ item2的分* item2与它的相似度
这样就能对item1x进行排序,推荐出用户最喜欢的产品。
--------------------------------------------------------------------------
所以推荐的方法大概有两种,基于item的推荐,以及基于user的推荐。当user和item是很稠密的时候用user的,很稀疏的时候用item的。
计算相似度的两种方法,欧氏距离或pearson相似度,是上述推荐的基础,是衡量item或者user类似程度的手段。