简介
本章主要介绍深度学习出现之前的几种经典算法,包括协同、矩阵分解和Logistic Regression等。这些类别的算法,在深度学习出来之前有着广泛的应用。而且,对于一般数据集的情况,这类方式也是简单易用,可解释性强。
协同过滤 Collaborative Filter
协同过滤算法是最早提出的推荐的算法类型,其核心的思想是,对于需要预测的向量x的数据,我们选取和x相似的top K个向量,来预测x的值。
举个例子,我们有一个矩阵,行表示用户user,列表示商品item,元素的取值是0、1 or -1,-1表示不喜欢,0表表示没投票,1表示喜欢。之后,给出一个用户u,预测u对商品i是否是喜欢。
比如,下面的矩阵给出了一个简单的情况:
| user \ item | item0 | item1 | item2 | item3 |
|---|
| user0 | 0 | 1 | 1 | 0 |
| user1 | 1 | 0 | 1 | -1 |
| user2 | 0 | -1 | 0 | 1 |
实际应用中,user和item的维度会很高。
假设我们现在有一个新的用户u,总共有n种商品,m个已经知道对商品评价的用户,而且也知道用户u对部分商品的评价,现在我们想知道u对于商品k的评价。
首先,我们需要定义函数sim(i,j),表示向量i和j的相似度。数学上,有很多方式,给出几个例子:
余弦相似度:
sim(i,j)=cos(i,j)=∥i∥∥j∥i⋅j
欧几里得距离:
sim(x,y)i=1∑N(xi−yi)2
还有其他的方式,比如皮尔逊相关系数等,这里不再一一列举。
算法步骤:
- 计算用户u和用户矩阵中,所有用户U的相似度
- 计算出u和所有用户的相似程度,并选择出top K个最相似的
- 根据加权公式,计算出Ru,p,Ru,p表示用户u对于商品p的喜好程度
喜好程度的计算方法为
Ru,p=∑s∈Ssim(u,s)∑s∈S(sim(u,s)⋅Rs,p)
其中,S 表示top K个和u相似的的用户集,Rs,p表示用户s对于商品p的喜好程度。
上面提到的CF算法,是基于用户的,因此又称为UserCF。
如果用户数量远远大于商品数量的话,我们可以用商品向量来计算,思路是一样的,不过此时的计算方式是基于商品item的,即商品对于用户的映射关系。这种方式我们成为ItemCF
UserCF更适合于新闻推荐、发现热点和热点追踪等,因为该方法基于用户之间的相似度来计算的。
ItemCF更适合于稳定商品的情况,比如电视剧推荐等。
CF算法的不足之处在于,我们计算的时候,只考虑了单一维度的情况,比如好友的喜好,无法执行根据其他特征来计算推荐
矩阵分解
矩阵分解算法,就是为了解决CF中提到的特征不足的问题。矩阵分解的核心思想如下,为每个用户和商品创建一个k维的隐向量;那么用户u对于商品p的喜好程度就是
ru,p=ku⋅kp
其中,ku表示用户u的隐向量,kp表示商品p的隐向量。
原来的User-Item矩阵:
R=UV
其中,R∈Rm×n表示原来的User_Item矩阵, U∈Rm×k表示用户矩阵,V∈Rk×n表示商品矩阵。
那么,R中的元素rui表示用户u对于商品i的评分,计算方式为:
r^ui=xuTyi
xuT表示用户u的行向量,yi表示商品i的列向量。
在矩阵维度很高的情况下,不适合使用奇异值分解,这里我们统一使用梯度下降的方式来求解。
明确我们的求解目标,R中不为零的数据是已知的用户数据,用户矩阵U和商品矩阵V是需要学习的出来的数据。定义我们的求解目标:
X,Yminrui=0∑(rui−r^ui)2=X,Yminrui=0∑(rui−xuTyi)2
为了防止求解过程中出现过拟合,我们需要加入正则化选项,因此最终的求解目标是:
X,Ymin⎩⎨⎧rui=0∑(rui−xuTyi)2+λ(u∑∥xu∥22+i∑∥yi∥22)⎭⎬⎫
其中,x和y互相独立。
这里需要单独说明一个地方,我们所有的向量都是列向量,上文提到的xu表示用户对于商品评价的列向量。我们使用xuT表示行向量,首先是从形态理解上,用户矩阵中,对于商品的评价,是按照行存储的;其次是为了向量内积,行向量于列向量的内积是个具体的数字。根据matrixcookbook手册 ,向量内积的求导的方式为:
x∂xTa=x∂aTx=a
根据梯度下降的迭代法则,我们需要分别对对xu和yi求偏导,并迭代跟新。xu的梯度函数为
∇xu=−2(rui−xuTyi)yi+2λxu
更新应该是朝着梯度的反方向,因此xu的梯度更新方式为
xu=xu−γ((rui−xuTyi)yi−λxu)
γ是学习速率。这里是对向量求导。
x和y是对称的,因此y的更新方式为:
yi=yi−γ((rui−xuTyi)xu−λyi)
如果新增用户了,我们一般不会重新训练整个数据集,这样复杂度太高了。正确方式应该是,利用用户的历史行为数据和已经训练好的物品矩阵,单独训练xu即可,此时不需要更新物品矩阵,只需要更新新增的用户的参数。
矩阵分解还有隐式分解的形式,基本流程一样,这里不再赘述。