如何在协同过滤中使用SVD?


30

我对在协作过滤中使用SVD感到有些困惑。假设我有一个社交图,并且从边缘构建了一个邻接矩阵,然后使用SVD(让我们忘记正则化,学习率,稀疏性优化等),如何使用此SVD来改进我的建议?

假设我的社交图对应于instagram,而我的任务是仅基于社交图来推荐服务中的用户。我首先要建立一个邻接矩阵,取SVD,,选择前特征值,然后呢?A (m×m)A=UsVk

我大概会创建一组新的矩阵: 那么该怎么办?

Unewm×ksnewk×kVnewk×m

我在网上浏览过,大多数链接都专注于计算SVD,但是没有人告诉您如何使用它。所以我该怎么做?


1
这可能会回答您的问题:datascience.stackexchange.com/a/16523
avli

Answers:


7

但是,使用纯香草SVD可能会在重新创建原始矩阵时遇到问题,更不用说预测缺失项的值了。该区域的有用经验法则是计算每部电影的平均评分,并为每个用户/电影组合减去此平均值,即从每个用户中减去电影偏差。然后建议您运行SVD,当然,您必须将这些偏差值记录在某处,以便重新创建额定值或预测未知值。我已经阅读了Simon Funk在SVD上的帖子以获取建议-他在Netflix竞争期间发明了增量SVD方法。

http://sifter.org/~simon/journal/20061211.html

我想在SVD之前降低矩阵A的含义是有意义的,因为SVD的近亲PCA也以类似的方式工作。在增量计算方面,Funk告诉我,如果不贬低,则第一梯度方向将主导其余的计算。我亲眼目睹了这一点,基本上没有贬低的事情是行不通的。


24

我想提出不同意见:

缺失的边缘作为缺失的价值

在协作过滤问题中,不存在的连接(用户没有对项目评分,人没有与人成为好友)通常被视为要预测的缺失值,而不是零。也就是说,如果用户尚未对项目评分,我们想猜测一下如果他项目评分,他可能会对其进行评分。如果人没有与,我们想猜测他与他交朋友的可能性。这些建议基于重构的值。ijxyijxy

当您使用社交图的SVD时(例如,通过插入svd()),基本上是在所有那些缺失的点上归零。在协作过滤的用户项目评分设置中,这很成问题。如果我有办法可靠地填写缺失的条目,则完全不需要使用SVD。我只是根据填写的内容给出建议。如果我没有办法做到这一点,那么在执行SVD之前我不应该填充它们。*

缺少值的SVD

当然,该svd()函数不知道如何处理缺少的值。那么,您到底应该怎么做?好吧,有一种方法可以将问题重新构成为

“找到最接近原始矩阵的秩为的矩阵”k

那确实是您要解决的问题,并且您不会用svd()它来解决它。一种对我有用的方法(在Netflix奖金数据上)是:

  • 尝试使用简单模型来拟合条目,例如。这实际上做得很好。X^i,j=μ+αi+βj

  • 给每个用户分配一个向量,向每个项目分配一个向量。(在您的情况下,每个人都有一个左右向量)。您最终将以点积预测残差:ikuijkvjkuimvjm

  • 使用某种算法来找到使原始矩阵距离最小的向量。举例来说,使用这种

祝你好运!

*:Tenali推荐的基本上是最近的邻居。您尝试查找相似的用户并提出建议。不幸的是,稀疏性问题(约99%的矩阵缺少值)使得使用余弦距离或jaccard相似度或其他方法很难找到最近的邻居。因此,他建议对矩阵进行SVD​​处理(在缺失值处插入零),首先将用户压缩到较小的特征空间中,然后再进行比较。做SVD最近邻居很好,但是我仍然建议以正确的方式做SVD(我的意思是……我的方式)。无需进行无意义的价值估算!


这实际上是我一直在寻找的回复,很想听到:)非常感谢!
维沙尔2012年

奇怪的是,这个问题问到:“我看过网络,大多数链接都专注于计算SVD,但是没人告诉您如何处理SVD。那我该怎么办?” 或就此而言,标题说:“如何在协作过滤中使用SVD?”
TenaliRaman 2012年

是的,我的回答总结了如何在协作过滤中使用它。
笨拙的乔·皮特2012年

1
+1,据我了解,您不是使用SVD计算低秩矩阵,而是使用迭代方法来最小化平方误差,对吗?但是,如果我确实想使用SVD,那么在进行矩阵分解之前,我应该用一些值填充缺少的条目,对吗?
牛油果

1
因此,当他们说使用svd时,是不是要使用进行矩阵分解?他们之所以说svd,是因为此迭代解决方案的结果或基本思想类似于svd?svd()
牛油果

14

没有人告诉您如何使用它的原因是因为,如果您知道SVD的功能,那么使用它就很明显了:-)。

由于您的行和列是同一集合,因此我将通过不同的矩阵A对此进行说明。让矩阵A成为行是用户,列是用户喜欢的项目。请注意,此矩阵不必是对称的,但是在您的情况下,我想它实际上是对称的。想到SVD的一种方法如下:SVD找到隐藏的特征空间,用户和他们喜欢的项在其中具有紧密对齐的特征向量。

因此,当我们计算,矩阵表示与隐藏特征空间中的用户相对应的特征向量,而矩阵表示与隐藏特征空间中的项目相对应的特征向量。U VA=U×s×VUV

现在,如果我给您两个来自相同特征空间的向量,并要求您查找它们是否相似,那么您想到的最简单的方法是什么?点产品。

因此,如果我想看到用户喜欢项目,那么我所要做的就是取中第个条目和V中第个条目的点积。当然,点积绝不是您唯一的选择可以适用,您可以想到的任何相似性度量都适用。Ĵ ù ĴijiUj


两个问题:1)在运行SVD之前,您是否用零填充缺失的值(用户i未审查项目j)?2)您如何计算新用户是否喜欢项目j?
B_Miner

1
@B_Miner您好,抱歉延迟回复。答案:1)是的,是的,我们通常在运行SVD之前用零填充缺失值。但是,我通常建议用非零等级填充它-例如,您可以用用户到目前为止给出的平均等级填充缺失值。2)基于SVD的方法仅适用于已知用户和已知项目。它不能处理新用户或新项目。而且,如果有新用户加入,我们怎么可能在这个框架中对他一无所知。
TenaliRaman

1
@B_Miner如果您想使用新的用户/项目,我们必须假设我们可以访问某些用户功能和项目功能。然后,您可以使用更复杂的模型,例如PDLF(预测离散潜在因子模型)。这将允许您处理新的用户/项目,因为它可以与已知的功能空间一起使用。
TenaliRaman

@TenaliRaman不知道您是否会看到这个,但是这里有。因此,我一直在使用主题模型(LDA)根据用户已阅读的文档为用户(实际用户)构建功能。我只是对主题向量进行平均,以获得“用户主题向量”。我想对SVD(或可能是ALS)做类似的事情。假设我使用已知的用户项数据计算SVD,然后有新的用户“访问”多个已知项。在这种情况下,项目向量是已知的,但用户向量是未知的。我可以使用项目向量来计算用户向量,还是需要使用所有数据再次计算SVD?
thecity2

很好的答案tenali。对理解这个概念非常有帮助
Nihal

3

这是为那些想实际实施稀疏SVD建议或检查源代码以了解细节的人员,尝试回答问题的“如何”部分。您可以使用现成的FOSS软件对稀疏SVD进行建模。例如,vowpal wabbitlibFM,或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/movielensvowpalwabbit源代码树中使用时,在对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)实现
  • vowpal wabbit(aka vw)是John Langford的聪明孩子

1

我会说这个名字SVD是误导性的。实际上,SVD推荐系统中的方法并不直接使用SVD因式分解。相反,它使用随机梯度下降来训练偏差和因子向量。

推荐系统的SVDSVD++算法的详细信息可以在章节5.3.15.3.2本书中找到Francesco Ricci, Lior Rokach, Bracha Shapira, and Paul B. Kantor. Recommender Systems Handbook. 1st edition, 2010

在Python中,有一个完善的程序包实现了名为的这些算法surprise。在其文档中,他们还提到了这些算法的详细信息。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.