阅读 1812

推荐基础-协同过滤总结

1.概述

随着信息的暴增,人们所面临的一个挑战就是如何从提供的大量商品或信息中快速简单地找到他们最需要的东西。为了解决这一问题而提出来的“推荐系统”应运而生。最开始推荐系统只是简单的协同过滤策略,但是随着系统的发展,演化出来召回-排序-重排复杂的结构。召回处在这个系统的前置位,决定了排序的天花板。本文讲了最常见的协同过滤方法。 协同过滤基于“集体智慧”的思想,该方法认为,人们倾向某种人群共性的部分。例如,你想看一部电影,但不知道看哪部,大部分人都会问问周围的人,并倾向与选择平时与自己爱好口味比较类似的人的推荐。协同过滤优点在于,该方法对领域不敏感,即不需要对推荐事务很了解也可以,同时效果往往也比基于内容的方法好。但协同过滤会产生“冷启动”困难的问题。 下文主要讲常用的几种协同过滤算法。

2. 算法

2.1 邻域CF

2.1 原理

基于邻域的协同过滤算法是推荐最常见的算法之一。优点是:实现成本低,不容易出错,计算速度快,效果不错,能推荐长尾的物品。缺点是尾部点击少的user和item容易出现badcase。 最近邻方法”包括“基于物品的协同过滤”和“基于用户的协同过滤”。“基于物品的协同过滤”-Item based 是指寻找与物品a相似的其他物品,当用户观看了物品a 时, 给用户推荐相似的其他物品。“基于用户的协同过滤”-User based 是指寻找与用户A相似的其他用户B,C,D, 如果用户A和用户B观看喜好相似,由于用户A和用户B很相似,那么认为用户B看过的其他物品b也很有可能被A所喜欢。以Koren的图为例说明user-based方法, Joe喜欢左边的三部电影a,b,c,为Joe推荐电影时,找到与他相似的用户A,B,C,这三个人都看过电影1,拯救大兵瑞恩,因此,这部电影是最先推荐的。

2.2 计算方法

以item-base的方法举例,说明如何计算item-item的相似度。 假设user A观看或点击了item a,b(以下统称点击),同样,user B点击了item b, item d,user C点击了item a, item b , item c。

item a item b item c item d
user A 1 1
user B 1 1
user C 1 1 1

将该点击序列展开,得到矩阵

通过矩阵的余弦相似度求item-item, 或者user-user的相似度。在本例中,就是item a 与item b的相似度即为 向量(1,1,0,0)与向量(0,1,0,1)的余弦相似度。这类方法运算简单,速度快,适合在spark上并行处理。

2.3 结论

  • 会存在一些“非用户点击”,即机器爬虫等,特点是点击量过高,需要去掉。
  • 在物品中,尽管我们希望每个物品都至少推给用户一次,对长尾有很好的作用,但是在某些情况下,对于点击特别少的,默认质量不高,也可以去掉。
  • 在计算时,不要真正展开成向量,而是分别计算item a 出现的次数,item b出现的次数,以及itam a 和itam b共同出现的次数,就可以了。因此该方法很适合并行。
  • 基于物品和用户的协同过滤根据不同场景来选择。比如,在亚马逊购物网站,用户的数量远远高于物品的数量,且用户的喜好变换很大,在不同的时期购买的东西不相同,相似性不稳定,而物品数量相对用户较小,且物品与物品之间的相似性较稳定,因此更常用item-based。

2.OCF(order-cf)

2.1 原理

Item-CF是拿到全量信息后,计算item与item的相似度,对所有点击的item同等对待,没有考虑到点击的顺序。OCF则考虑了点击序列的前后顺序。例如,在新闻场景中,点击了文章A之后点击的文章B相对于文章A之前点击的文章C,文章B与文章A更相关。

2.2 计算方法

s(i,j)=\frac{\sum_N{order(i,j)}}{click(i)·click(j)}
符号 意义
i,j item
order(i,j) 在某一个transaction中,j在i之后点击记为1,否则记为0
click(i) i被点击的总次数
N transaction的总次数

2.3 ocf的改进

上面的方法默认了在文章A后点击的全部都是同等重要的。但是往往用户的兴趣会随着时间漂移,如在点击浏览文章a之后,立刻点击的文章b比点了10篇文章后再点击的文章c可能会更相似。因为随着文章的增多,用户的兴趣可能被不断转移。基于以上假设,因此提出基于位置假说的oicf,公式如下:

s(i,j)=\frac{\sum_{N,p}\alpha_p·{order(i,j)}}{click(i)·click(j)}

其实就是给每个位置赋予不同的权重,越靠近原文章的点击权重越大。

3. SCF

3.1 原理

该方法来自阿里的文章《基于图结构的实时推荐算法SWING的工程实现》。 假设如下图所示

user集合为[a,b,c,d,e],item集合为[s,r,p,q,w,z,t,x],要计算和s相似的item。user和item可以看做是二部图,在这个二部图里是没有三角形的,但是有很多“秋千”状的swing角形结构,比如(a,r,b)构成一个swing,(a,p,c)也构成一个swing。这个swing结构带来的信息比(e,w)这种边结构带来的信息更多。例如,多个用户在点击了r的同时,都只点了p,那么r和p就一定是强关联的。如果,两个user pair之间和很多item构成swing,那么这些item上每个节点分到的权重就越低。

3.2 计算

s(i,j)=\sum_{u{\in}U_i{\bigcap}U_j}\sum_{v{\in}U_i{\bigcap}U_j}\frac{1}{\alpha+|I_u{\bigcap}I_v|}
符号 意义
i,j item
u,v user
\alpha 参数
U_i 点击过i的user集合
U_j 点击过j的user集合

SCF更多的利用了user的collective intelligence

3.3 结论

由公式可以看到,如果同时点击i,j的人越多,s(i,j)越大。低俗的文章很多用户去点,就很容易排到前面,因此SCF很容易出热门、低俗。可以通过其他手段来控制和解决。 一个user点击的item,一天最多也就是几百左右,在计算的时候,问题不大。但是一个item会被上百万甚至上千万用户点击,这些用户会做一个两两pair去计算,因此会产生大量的时间消耗。这里需要一些优化。优化的关键是组合(u1, u2)。

  1. 广播Map(item, userList)和Map(user, itemList);
  2. 将RDD(u1, i1)->RDD(u1, itemList) -> RDD((i1, i2), u) -> RDD((i1, i2), (u1, u2)) -> 计算每一对(i1, i2) score -> 按照key(i1, i2)加和
  3. 另外一个改进是可以只计算(userA, userB),因为score(A,B)=score(B,A) ,所有保存的时候写入(userA, userB, score)和(userB, userA, score)

4. FM 矩阵分解

不同于前面的简单计算,矩阵分解属于模型方法,需要优化求解。

4.1 原理 矩阵变换

矩阵变换的本质是一个函数,与普通函数不同的是矩阵变换接收一个向量,并输出一个向量。也就是一个向量运动变成另外一个向量,原来的单位向量移动到了新的位置。举例存在一个向量\vec v 变换前 \vec v =\left[ \begin{matrix} -1\\ 2 \end{matrix} \right]= -1 \vec i+ 2\vec j 变换后 Transformed \vec v = -1 Transformed\vec i + 2Transformed\vec j 假设Transformed \vec i =  \left[ \begin{matrix} 3\\ 1 \end{matrix} \right]Transformed \vec j =  \left[ \begin{matrix} 1\\ 2 \end{matrix} \right], 得到Transformed\vec v=-1\left[ \begin{matrix} 3\\ 1 \end{matrix} \right]+2\left[ \begin{matrix} 1\\ 2 \end{matrix} \right] = \left[ \begin{matrix} -1\\ 3 \end{matrix} \right] 也就是如果得到变换后\vec i\vec j的位置,也就是确定了新的坐标参考系,就可以得到该空间任意向量\vec v的位置。把这两个向量写到一起,就是矩阵乘法

M * \vec v = \left[ \begin{matrix} 3 & 1\\ 1 & 2  \end{matrix} \right] * \left[ \begin{matrix} -1\\ 2 \end{matrix} \right]

用图表示就是:

注意到这里变化后的Transformed\vec iTranformed\vec j不仅在原来的\vec i\vec j方向发生了拉伸,还有旋转。如果矩阵M=\left[ \begin{matrix} 2 & 0\\ 0 & 4  \end{matrix} \right]M * \vec v = \left[ \begin{matrix} 4 & 1\\ 2 & 3  \end{matrix} \right] * \left[ \begin{matrix} -1\\ 2 \end{matrix} \right] = \left[ \begin{matrix} -2\\ 4 \end{matrix} \right],相当于仅仅拉伸了向量\vec v

反过来说也就是,对于某一个矩阵,大部分向量都会偏移,但是存在某些向量只会拉伸,不会偏移,这类向量就叫这个矩阵的特征向量,拉伸的大小就叫该向量对应的特征值。求该特征向量和特征值的过程就叫矩阵分解,就是将一个矩阵分解为A=Q\Sigma Q^{-1},其中Q的每一列是矩阵A的一个特征向量,表示矩阵使哪些向量只发生拉伸; \Sigma是一个对角矩阵,对角线上的元素对应特征向量对应的特征值,表示对应的特征向量拉伸情况如何。假设一个向量v是方阵A的特征向量,那么A\vec v=\lambda\vec v\lambda为特征向量\vec v对应的特征值,一个矩阵的一组特征向量是一组正交向量。解这个方程就可以得到\vec v\lambda。我们想描述一个变换时,希望只描述其主要变换方向,即其变化最大的方向。而对于矩阵分解,Q对应的列向量是主要的变化方向,当\Sigma按照从大到小顺序排列时,越大的特征值对应的特征向量对应的变化越大。当矩阵是高维时,我们求该矩阵的top-k的特征值也就对应了该矩阵最主要的k个变换,也就是这个矩阵最主要的特征,就可以用这k个特征来近似这个矩阵。但是,特征值分解只对于方阵适用,但是实际应用中很多都不是方阵,因此提出了奇异值分解(SVD)。 奇异值分解适应于普通矩阵,用代数表示即A=U\Sigma V^T, U成为左奇异矩阵,右边称右奇异矩阵,中间是奇异值。用图形表示就是
。k<<n且k<<m, 因此分解后的矩阵远远小于原来的矩阵。k越接近n,两边其结果越接近A。至于怎么解 SVD,目前都是难题。SVD的进一步简化就是A\approx UV^T,为了得到该等式近似解,有了ALS算法。

4.2 基础模型

基础的矩阵分解模型为\hat{r}_ {ui}=q^T_ip_u,其中\hat r_{ui}为用户u对item i的评分,q^T_i为item的向量,p_u为用户u 的向量。优化目标为:

min_{p^*, q^*}\Sigma_{(u,i)\in k}(r_{ui}-q^T_ip_u)^2+\lambda (||q_i||^2+||p_u||^2)

k为已知r_{ui}的(u,i)集合。 因为q 和 p都不知道,因此该等式不是凸函数,其求解方法为ALS(Alternating least squares).每次固定其中的一个,比如p,然后这个最优化问题等价于二次优化问题,用SGD求关于p最优解,然后再固定p,求关于q的最优化问题,如此迭代。

4.3 考虑偏差

由于每个用户的消费习惯不同,有用户偏向给每个电影的评分更高,有的用户偏低,因此在基础模型上,叠加了偏差。

b_{ui}=\mu + b_i + b_u
\hat r_{ui}=\mu + b_i + b_u + q^T_ip_u

优化目标为:

min_{p^*, q^*,b^*}\Sigma_{(u,i)\in k}(r_{ui}-\mu-b_u-b_i-q^T_ip_u)^2+\lambda (||q_i||^2+||p_u||^2+b^2_u+b^2_i)

\mu为全部item的平均值。举例来说,预测Joe对Titanic的评分,所有电影的平均得分是3.7,Titanic是一部好电影,比普通电影得分高0.7,Joe是一个谨慎的用户,评分比其他用户要低0.3左右,因此最终的得分为3.9(3.7+0.5-0.3)。

4.4 隐式反馈场景

上述矩阵分解最常用的场景是显示反馈,而我们现在需要做的是隐式反馈。显示反馈是指用户明确的知道自己的态度,例如给电影评分等。隐式反馈并不能直接反应用户的态度,例如点击数据、浏览数据,用户的一次点击并不以为这用户喜欢这个物品或者喜欢这篇新闻。隐式反馈和显示反馈很不相同,隐式反馈更稠密,更稳定;而显示反馈更稀疏。 隐式反馈更真实,数据更容易获得;显示反馈更能说明用户的态度。隐式数据的处理方法不同于显示数据。当前对于这两类数据有两种方法: point wise(预测对点的偏好) 和pair wise(对两个item的排序)。对隐式数据而言,优化方法变成了(与原文保持一致,p,q 分别改成了x,y):

min_{x^*, y^*}\Sigma_{(u,i)\in k}c_{ui}(p_{ui}-x^T_uy_i)^2+\lambda (||x_u||^2+||y_i||^2)
p_{ui}=
\begin{cases}
1 \ \ r_{ui}>0 \\
0 \ \ r_{ui}=0, c_{ui}=1+\alpha r_{ui}
\end{cases}

参考文献:

Matrix factorization techniques for recommender systems

Collaborative Filtering for Implicit Feedback Datasets

文章分类
人工智能
文章标签