我对在协作过滤中使用SVD感到有些困惑。假设我有一个社交图,并且从边缘构建了一个邻接矩阵,然后使用SVD(让我们忘记正则化,学习率,稀疏性优化等),如何使用此SVD来改进我的建议?
假设我的社交图对应于instagram,而我的任务是仅基于社交图来推荐服务中的用户。我首先要建立一个邻接矩阵,取SVD,,选择前特征值,然后呢?
我大概会创建一组新的矩阵: 那么该怎么办?
我在网上浏览过,大多数链接都专注于计算SVD,但是没有人告诉您如何使用它。所以我该怎么做?
我对在协作过滤中使用SVD感到有些困惑。假设我有一个社交图,并且从边缘构建了一个邻接矩阵,然后使用SVD(让我们忘记正则化,学习率,稀疏性优化等),如何使用此SVD来改进我的建议?
假设我的社交图对应于instagram,而我的任务是仅基于社交图来推荐服务中的用户。我首先要建立一个邻接矩阵,取SVD,,选择前特征值,然后呢?
我大概会创建一组新的矩阵: 那么该怎么办?
我在网上浏览过,大多数链接都专注于计算SVD,但是没有人告诉您如何使用它。所以我该怎么做?
Answers:
但是,使用纯香草SVD可能会在重新创建原始矩阵时遇到问题,更不用说预测缺失项的值了。该区域的有用经验法则是计算每部电影的平均评分,并为每个用户/电影组合减去此平均值,即从每个用户中减去电影偏差。然后建议您运行SVD,当然,您必须将这些偏差值记录在某处,以便重新创建额定值或预测未知值。我已经阅读了Simon Funk在SVD上的帖子以获取建议-他在Netflix竞争期间发明了增量SVD方法。
http://sifter.org/~simon/journal/20061211.html
我想在SVD之前降低矩阵A的含义是有意义的,因为SVD的近亲PCA也以类似的方式工作。在增量计算方面,Funk告诉我,如果不贬低,则第一梯度方向将主导其余的计算。我亲眼目睹了这一点,基本上没有贬低的事情是行不通的。
我想提出不同意见:
在协作过滤问题中,不存在的连接(用户没有对项目评分,人没有与人成为好友)通常被视为要预测的缺失值,而不是零。也就是说,如果用户尚未对项目评分,我们想猜测一下如果他对项目评分,他可能会对其进行评分。如果人没有与,我们想猜测他想与他交朋友的可能性。这些建议基于重构的值。
当您使用社交图的SVD时(例如,通过插入svd()
),基本上是在所有那些缺失的点上归零。在协作过滤的用户项目评分设置中,这很成问题。如果我有办法可靠地填写缺失的条目,则完全不需要使用SVD。我只是根据填写的内容给出建议。如果我没有办法做到这一点,那么在执行SVD之前我不应该填充它们。*
当然,该svd()
函数不知道如何处理缺少的值。那么,您到底应该怎么做?好吧,有一种方法可以将问题重新构成为
“找到最接近原始矩阵的秩为的矩阵”
那确实是您要解决的问题,并且您不会用svd()
它来解决它。一种对我有用的方法(在Netflix奖金数据上)是:
尝试使用简单模型来拟合条目,例如。这实际上做得很好。
给每个用户分配一个向量,向每个项目分配一个向量。(在您的情况下,每个人都有一个左右向量)。您最终将以点积预测残差:
使用某种算法来找到使原始矩阵距离最小的向量。举例来说,使用这种纸
祝你好运!
*:Tenali推荐的基本上是最近的邻居。您尝试查找相似的用户并提出建议。不幸的是,稀疏性问题(约99%的矩阵缺少值)使得使用余弦距离或jaccard相似度或其他方法很难找到最近的邻居。因此,他建议对矩阵进行SVD处理(在缺失值处插入零),首先将用户压缩到较小的特征空间中,然后再进行比较。做SVD最近邻居很好,但是我仍然建议以正确的方式做SVD(我的意思是……我的方式)。无需进行无意义的价值估算!
没有人告诉您如何使用它的原因是因为,如果您知道SVD的功能,那么使用它就很明显了:-)。
由于您的行和列是同一集合,因此我将通过不同的矩阵A对此进行说明。让矩阵A成为行是用户,列是用户喜欢的项目。请注意,此矩阵不必是对称的,但是在您的情况下,我想它实际上是对称的。想到SVD的一种方法如下:SVD找到隐藏的特征空间,用户和他们喜欢的项在其中具有紧密对齐的特征向量。
因此,当我们计算,矩阵表示与隐藏特征空间中的用户相对应的特征向量,而矩阵表示与隐藏特征空间中的项目相对应的特征向量。U V
现在,如果我给您两个来自相同特征空间的向量,并要求您查找它们是否相似,那么您想到的最简单的方法是什么?点产品。
因此,如果我想看到用户喜欢项目,那么我所要做的就是取中第个条目和V中第个条目的点积。当然,点积绝不是您唯一的选择可以适用,您可以想到的任何相似性度量都适用。Ĵ 我ù Ĵ
这是为那些想实际实施稀疏SVD建议或检查源代码以了解细节的人员,尝试回答问题的“如何”部分。您可以使用现成的FOSS软件对稀疏SVD进行建模。例如,vowpal wabbit
,libFM
,或redsvd
。
vowpal wabbit
有3种“类似于SVD”算法的实现(每种方法都可以通过3个命令行选项之一进行选择)。严格来说,这些应该称为“近似,迭代,矩阵分解”,而不是纯“经典的” SVD”,但它们与SVD密切相关。您可以将它们视为稀疏(大部分情况下,计算效率很高的近似SVD分解)零)矩阵。
这是使用Netflix风格电影推荐的完整且有效的食谱vowpal wabbit
,它的“低排名二次方”(--lrq
)选项最适合我:
数据集格式文件ratings.vw
(按用户和电影对每一行进行评级):
5 |user 1 |movie 37
3 |user 2 |movie 1019
4 |user 1 |movie 25
1 |user 3 |movie 238
...
其中第一个数字是评分(1到5星),后跟被评分的用户ID和被评分的电影ID。
测试数据的格式相同,但可以(可选)省略“评级”列:
|user 1 |movie 234
|user 12 |movie 1019
...
可选地,因为要评估/测试预测,我们需要评级来与预测进行比较。如果我们省略评分,vowpal wabbit
则仍会预测评分,但无法估算预测误差(数据中的预测值与实际值)。
为了进行训练,我们要求在用户与他们喜欢(或不喜欢)的电影之间vowpal wabbit
找到一组N
潜在的交互因素。您可能会认为这是在查找共同的主题,其中相似的用户以相似的方式对电影的子集进行评分,并使用这些共同的主题来预测用户如何评估他尚未评分的电影。
vw
我们需要使用的选项和参数:
--lrq <x><y><N>
发现“低阶二次方”潜在因子。<x><y>
:“ um”表示跨越数据集中的u [sers]和m [ovie]命名空间。请注意,该--lrq
选项仅在每个命名空间中使用第一个字母。<N>
:N=14
以下是我们要查找的潜在因素的数量-f model_filename
:将最终模型写入 model_filename
因此,一个简单的完整培训命令将是:
vw --lrq um14 -d ratings.vw -f ratings.model
有了ratings.model
模型文件后,我们可以使用它来预测新数据集上的其他评分more_ratings.vw
:
vw -i ratings.model -d more_ratings.vw -p more_ratings.predicted
预测将被写入文件more_ratings.predicted
。
demo/movielens
在vowpalwabbit
源代码树中使用时,在对ml-1m.ratings.train.vw
具有14个潜在因子(意味着SVD中间矩阵是14x14行x列矩阵)的100万用户/电影评级进行训练之后,我得到了约0.693 MAE(平均绝对误差)。测试设置ml-1m.ratings.test.vw
。0.69 MAE有多好?对于可能的预测的整个范围,包括未评级的(0)情况[0至5],0.69的误差约为整个范围的13.8%(0.69 / 5.0),即大约86.2%的精度(1-0.138)。
您可以vowpal wabbit
在github上的源代码树中找到示例和具有类似数据集(movielens)的完整演示,其中包括文档:
笔记:
movielens
演示使用我省略了(为简单起见)从我的例子几个选项:尤其是--loss_function quantile
,--adaptive
和--invariant
--lrq
实现vw
要比快得多--rank
,尤其是在存储和加载模型时。学分:
--rank
大众选项由杰克·霍夫曼(Jake Hofman)实现--lrq
大众(带有可选的辍学选项)由保罗·米诺罗(Paul Minero)实现