我在此处看到了一些关于机器学习的问题,因此我想发布一个相关的问题:
假设我有一个数据集,其中运动员参加10公里和20公里的越野跑比赛,即每场比赛都有其独特的难度。
用户的完成时间在每场比赛中几乎呈逆正态分布。
这个问题可以写成一个矩阵:
Comp1 Comp2 Comp3User1 20min ?? 10minUser2 25min 20min 12minUser3 30min 25min ??User4 30min ?? ??
我想完成上述大小为1000×20且稀疏度为8%的矩阵。
由于我可以为每个用户(能力)计算参数,为每场比赛(分布的mu和lambda)计算参数,而且比赛之间的相关性非常高,应该有非常简单的方法来完成这个矩阵。
我可以利用排名User1 < User2 < User3 和 Item3 << Item2 < Item1
你能给我一些提示,告诉我可以使用哪些方法吗?
回答:
你敏锐地观察到这是一个矩阵补全问题,这已经让你接近解决方案了。我将把你的直觉具体化,即用户的能力和比赛的难度结合起来决定比赛的时间,然后介绍几种算法。
模型
设向量u表示用户的速度,因此u_i是用户i的速度。设向量v表示比赛的难度,因此v_j是比赛j的难度。此外,当可用时,设t_ij为用户i在比赛j上的时间,并定义y_ij = 1/t_ij,即用户i在比赛j上的速度。
由于你说时间是逆高斯分布的,一个合理的观察模型是
y_ij = u_i * v_j + e_ij,
其中e_ij是一个均值为零的高斯随机变量。
为了拟合这个模型,我们寻找向量u和v,使得在观察到的速度中预测误差最小化:
f(u,v) = sum_ij (u_i * v_j – y_ij)^2
算法1:缺失值奇异值分解
这是经典的Hebbian算法。它通过梯度下降来最小化上述成本函数。f对u和v的梯度是
df/du_i = sum_j (u_i * v_j - y_ij) v_jdf/dv_j = sum_i (u_i * v_j - y_ij) u_i
将这些梯度代入共轭梯度求解器或BFGS优化器中,如MATLAB的fmin_unc
或scipy的optimize.fmin_ncg
或optimize.fmin_bfgs
。除非你愿意实现一个非常好的线搜索算法,否则不要自己编写梯度下降算法。
算法2:带有迹范数惩罚的矩阵分解
最近,已经提出了对这个问题的简单凸松弛。由此产生的算法同样简单易于编写,并且似乎效果很好。例如,查看Collaborative Filtering in a Non-Uniform World:Learning with the Weighted Trace Norm。这些方法最小化f(m) = sum_ij (m_ij – y_ij)^2 + ||m||_*,其中||.||_*
是矩阵m的所谓的核范数。实现最终将再次计算关于u和v的梯度,并依赖于非线性优化器。