ALS算法是2008年以来,用的比较多的协同过滤算法。它已经集成到Spark的Mllib库中,使用起来比较方便。
1 矩阵分解
用户对物品的打分行为可以表示成一个评分矩阵A(m*n),表示m个用户对n各物品的打分情况。如下图所示。
u\v | v1 | v2 | v3 | … |
---|---|---|---|---|
u1 | 5 | 4 | 3 | … |
u2 | ? | 5 | ? | … |
u3 | 4 | ? | 2 | … |
… | … | … | … |
其中, A(i,j) 表示用户 useri 对物品 itemj 的打分。但是,用户不会对所有物品打分,图中?表示用户没有打分的情况,所以这个矩阵A很多元素都是空的,我们称其为“缺失值(missing value)”。在推荐系统中,我们希望得到用户对所有物品的打分情况,如果用户没有对一个物品打分,那么就需要预测用户是否会对物品打分,以及会打多少分。这就是所谓的“矩阵补全(填空)”。一个m×n的打分矩阵,A 可以用两个小矩阵U(m×k)和V(n×k)的乘积来近似:A≈ UVT ,k≪m,n。这样我们就把整个系统的自由度从O(mn)下降到O((m+n)∙k)。举个例子,我喜欢看略带黑色幽默的警匪电影,那么大家根据这个描述就知道我大概会喜欢昆汀的《低俗小说》、《落水狗》和韦家辉的《一个字头的诞生》。这些电影都符合我对自己喜好的描述,也就是说他们在这个抽象的低维空间的投影和我的喜好相似。再抽象一些,把人们的喜好和电影的特征都投到这个低维空间,一个人的喜好映射到了一个低维向量 ui ,一个电影的特征变成了纬度相同的向量 vj ,那么这个人和这个电影的相似度就可以表述成这两个向量之间的内积。我们把打分理解成相似度,那么“打分矩阵A(m*n)”就可以由“用户喜好特征矩阵U(m*k)”和“产品特征矩阵V(n*k)”
u\F | f1 | f2 | f3 |
---|---|---|---|
u1 | ? | ? | ? |
u2 | ? | ? | ? |
u3 | ? | ? | ? |
… | … | … | … |
u\F | f1 | f2 | f3 |
---|---|---|---|
v1 | ? | ? | ? |
v2 | ? | ? | ? |
v3 | ? | ? | ? |
v4 | ? | ? | ? |
v5 | ? | ? | ? |
… | … | … | … |
2 交替最小二乘(ALS)
算法的思想就是:对目标函数,先随机生成然后固定它求解,再固定求解,这样交替进行下去,直到取得最优解min(C)。因为每步迭代都会降低误差,并且误差是有下界的,所以 ALS 一定会收敛。但由于问题是非凸的,ALS 并不保证会收敛到全局最优解。但在实际应用中,ALS 对初始点不是很敏感,是否全局最优解造成的影响并不大。
我们使用用户喜好特征矩阵U(m∗k)中的第i个用户的特征向量 ui ,和产品特征矩阵V(n∗k)第j个产品的特征向量 vj 来预测打分矩阵A(m∗n)中的 a(ij) 。我们可以得出一下的矩阵分解模型的损失函数为:
有了损失函数之后,下面就开始介绍优化方法。通常的优化方法分为两种:交叉最小二乘法(alternative least squares)和随机梯度下降法(stochastic gradient descent)。Spark使用的是交叉最小二乘法(ALS)来最优化损失函数。
算法执行步骤:
• 先随机生成一个。一般取全局均值。
• 固定,即认为是已知的常量,来求解:
由于上式中只有 vj 一个未知变量,因此C的最优化问题转化为最小二乘问题,用最小二乘法求解 vj 的最优解:
固定j,j∈(1,2,…,n),则:等式两边关于为 vj 求导得: