4.1 KiB
10.2 基于矩阵分解的协同过滤算法思想
假设现在需要为用户推荐他可能喜欢的电影,如果你是这个项目的设计者,你会以什么样的依据来对不同的用户推荐他可能喜欢的电影呢?
嗯,你可能会认为,如果我有不同用户对不同电影的评分,或者好评率等一些可以量化的数值,那么我只要找到用户对所有电影中评分最高那部电影,然后推荐给他就行了。
是的,没错!其实很多推荐系统就是这样实现的。也就是说,如果有下面这样的表格,我想你应该会像 2 号用户推荐 3 号电影。
y | 电影1 | 电影2 | 电影3 | 电影4 | 电影5 |
---|---|---|---|---|---|
用户1 | 5 | 5 | 4 | 1 | 1 |
用户2 | 4 | 4 | 5 | 3 | 2 |
用户3 | 1 | 3 | 1 | 5 | 5 |
用户4 | 1 | 1 | 3 | 4 | 2 |
但是我们的用户,不可能所有电影都看过,也就是说,在实际场景中,我们的表格中会有很多缺失值,在这里假设用0
来代表缺失值,就如下表一样:
y | 电影1 | 电影2 | 电影3 | 电影4 | 电影5 |
---|---|---|---|---|---|
用户1 | 5 | 5 | 0 | 1 | 1 |
用户2 | 5 | 0 | 4 | 1 | 1 |
用户3 | 1 | 0 | 1 | 5 | 5 |
用户4 | 1 | 1 | 0 | 4 | 0 |
所以我们希望能够有一种算法,它能预测目标用户对物品的评分,进而根据评分高低,将分高的物品推荐给用户。
基于矩阵分解的协同过滤算法正好能解决这个问题。假设现有的表格如下所示:
y | 电影1 | 电影2 | 电影3 | 电影4 | 电影5 |
---|---|---|---|---|---|
用户1 | 5 | 5 | 0 | 1 | 1 |
用户2 | 5 | 0 | 4 | 1 | 1 |
用户3 | 1 | 0 | 1 | 5 | 5 |
用户4 | 1 | 1 | 0 | 4 | 0 |
我们认为,有很多因素会影响到用户给电影评分,如电影内容:感情戏,恐怖元素,动作成分,推理悬疑等等。假设我们现在想预测用户2
对电影2
的评分,用户2
他很喜欢看动作片与推理悬疑,不喜欢看感情戏与恐怖的元素,而电影2只有少量的感情戏与恐怖元素,大部分都是动作与推理的剧情,则用户2
对电影2
评分可能很高,比如5
分。
基于上面的设想,我们只要知道所有用户对电影内容各种元素喜欢程度与所有电影内容的成分,就能预测出所有用户对所有电影的评分了。 若只考虑两种元素则用户喜好表与电影内容表如下:
用户喜好表x
:
x | 因素1 | 因素2 |
---|---|---|
用户1 | 5 | 0 |
用户2 | 5 | 0 |
用户3 | 0 | 5 |
用户4 | 0 | 5 |
值越大代表用户越喜欢某种元素。
电影内容表:w
:
w | 电影1 | 电影2 | 电影3 | 电影4 | 电影5 |
---|---|---|---|---|---|
因素1 | 0.9 | 1.0 | 0.99 | 0.1 | 0 |
因素2 | 0 | 0.01 | 0 | 1.0 | 0.9 |
值越大代表电影中某元素内容越多。
用户2
对电影2
评分为:$5\times 1.0 +0\times 0.01 = 5.0
$
对于所有用户,我们可以将矩阵x
与矩阵w
相乘,得到所有用户对所有电影的预测评分如下表:
xw | 电影1 | 电影2 | 电影3 | 电影4 | 电影5 |
---|---|---|---|---|---|
用户1 | 4.5 | 5.0 | 4.95 | 0.5 | 0 |
用户2 | 4.5 | 5.0 | 4.95 | 0.5 | 0 |
用户3 | 0 | 0.05 | 0 | 5 | 4.5 |
用户4 | 0 | 0.05 | 0 | 5 | 4.5 |
假设电影评分表y
(为m
行n
列的矩阵),我们考虑d
种元素,则电影评分表可以分解为用户喜好表x
(为m
行d
列的矩阵),与电影内容表w
(为d
行n
列的矩阵)。其中d
为超参数,大小由我们自己定。
基于矩阵分解的协同过滤算法思想为:一个用户评分矩阵可以分解为一个用户喜好矩阵与内容矩阵,我们只要能找出正确的用户喜好矩阵参数与内容矩阵参数(即表内的值),就能对用户评分进行预测,再根据预测结果对用户进行推荐。
所以不难看出,基于矩阵分解的协同过滤算法的流程如下:
- 随机初始矩阵值
- 构造损失函数,求得矩阵参数梯度
- 进行梯度下降,更新矩阵参数值
- 喜好矩阵与内容矩阵相乘得到预测评分
- 根据预测评分进行推荐