最简单的方法,就是根据一些相似的信息进行推荐, 比如A,B两个用户最近行为一致, 那么就根据A给 B推荐商品。 “浏览过X 的用户同样浏览过Y”, 这是基于相似度的推荐系统常用的方法。
对于这类算法,最重要的是找到合适的相似度函数。 常用的有用户点击次数, 购买记录。 但是即使如此, 在多大程度上, 两个用户才算相似呢? 应该使用绝对点击数量,还是应该先做 normalization? 是否需要引入时序信息 ?
这类以数据中相似度为基础的推荐算法, 我们称其为基于记录的推荐系统 (memory-based recommender systems )。 之所以用这个名字,是因为他们只使用了记录数据, 就像人的记忆一样, 而没有使用模型生成的 Embedding Featrue 。
定义相似度函数
我们用下面的标记, 来表示一个相似度函数:
我们看一个例子, 假设有4个商品, 我们记录每个商品, 和购买过他们的用户ID
基于这个数据,我们可以很简单的把两个商品的相似度定义为,购买过这两个商品用户ID的交集:
那么,我们可以得到如下一些结论
商品1,2 很流行, 但是它们的用户重合度不高。 商品3,4 比较小众,但是购买它们的用户重合度很高。但是,(1, 2) 的相似度绝对值依然大于商品(3, 4)。 如果我们直接用上面的函数进行推荐,我么就会大量的推荐流行商品, 而很少推荐小众商量, 这并不是我们想要的。
这个小例子想说明的是:相似度函数有时候并不能直观感受来定义, 不同的场景下,不同的定义都有一些潜在的假设。 对于上面的例子,我们需要对数据进行正规化(normalization)处理。
Jaccard 相似度
对于上面的例子,我们首先想到, 再计算相似度的时候, 需要考虑物品本身的流行度。 这就引出 Jaccard 相似度 (Jaccard Similarity)。
[题外话] 书里给力一个例子,但是由于这个概念过于简单, 这里就不详细解释了
余弦相似度 Cosine Similarity
余弦相似度参考了几何中角度的概念。 在使用余弦相似度之前, 需要把用户或者物品表示成向量的形式,假设 用户 1,2 分别被表示成向量 和 那么, Cosine Similarity 就可以定义为:
如果 和 很相似, 那么 Cosine Similarity 就接近于1, 反之,就接近于 0. 特别的,如果 Cosine Similarity 是负数就说明二者相反, 如果是-1就说明他们完全相反 (完全相同的另一种表述)。 所以, 余弦相似度有个很好的性质:取值范围 [-1, 1]。 从它的值上, 就可以很好的判断出二者的关系。
Pearson Similarity
考虑一种情况, 用户 给物品 的评分分布是 3,5 和 5, 3。 那么 Jaccard_Sim(1,2) = 1, 因为 Jaccard similarity 不考虑具体评分值, 只考虑是否有评分。 Cosine_Sim(1,2) 分数也会比较高, 因为 3 和 5 分数相差不大 (上图左边的情况)。 但是, 如果考虑到, 在Amazon 上 (用户评分值为0-5), 5 的评分一般代表很正面, 而3的评分实际已经是负面的了(0~2 很少见, 除非东西是在太烂了), 那么 Cosine_Sim(1,2) 就显得不是那么合适了。
在这个时候,如果可以减去均值, 那么我们就会得到相对正确的答案。 比如,这个例子, 如果减去均值,那么 给物品 的评分就变成了 -1,1 和 1, -1。 这是完全相反的两个评价。 Pearson Similarity 就是这么做的:
仔细看的话, 其实 Pearson Similarity 就是在 Cosine Similarity 的基础上, 减去各自的均值。
注意 Null Value :
在处理数据的时候, 有时候会把 Null Value 当成0, 而在推荐算法中, 会遇到大量用户和物品之间没有交互的情况, 如果把这个情况当成 0 , 那么就会大大影响 Pearson Similarity 的有效性。 比如上面的例子, 把 Null Value 设置为均值会更好, 另外一个处理方式是, 在计算 Pearson Similarity 时, 只考虑用户和商品之间有交互的情况:
我们选择只考虑有交互的值项来定义 Pearson 相似度有点武断。 是选择所有项目来判断还是只选择有交互的项目来判断, 需要根据实际情况来定。 这些相似性函数仅仅是启发式的——这两个选项都不应该被认为更“正确”,而是应该在特定情况下选择适合我们直觉(或产生最令人满意的结果)的定义。
有时候 Person 相似性效果不好, 可能是因为用户对一个商品的评价因素, 无法用到其他商品上。 比如, 用户对一个清洁刷子给了好评,仅仅是因为这个刷子性价比高, 而不是因为这个用户特别喜欢清洁用品 (每个人都要用到, 但是并不代表每个人都会喜欢)。 这种情况下, 用是否购买为标准的 Jaccard Similarity 表现可能会更好。
最后,这些相似性度量一般不会直接用于推荐(即,简单用他们去找最相似的项目)。在实践中,它们可能是指导更复杂算法的一部分。例如,为了向用户推荐商品,我们可能首先找到相似的用户,然后推荐其中许多用户喜欢的商品,而不是简单地直接依赖商品与商品的相似性。
使用相似度做排序预测
这里讲的是, 如何利用相似度, 把给用户推荐的商品排序。 想象一下, 你上了JD, 系统给你推荐了100个商品, 这些商品有的位置显眼,有的偏。 假设这些位置有排名, 商家有需要有个排序规则, 对推荐给你的商品进行排序。这里探讨如何利用商品相似度, 来给用户推荐的商品进行排序。 第五章用的基于 model 的方法, 会直接给出rate。
其中一个方法如下:
其中:
- 用户 对买过新商品(没有购买/评价)的商品的评价预测。
- 用户买过的所有商品。
- : 商品 的相似度。
- : 用户 对商品 的评价
这个方法很直观, 利用用户已有的评价,相似的商品,有相似的评价。类似的, 我们也可以给出基于用户相似度的方法
- 用户 对买过新商品(没有购买/评价)的商品的评价预测。
- 所有购买过相关商品的用户。
- : 用户 的相似度
- : 用户 对商品 的评价
我们也可以减去均值, 也许这会提高结果的准确度: