使用ALS推荐算法得到错误的推荐结果。

5

我编写了一个Spark程序来进行推荐。然后我使用了ALS.recommendation库。我用一个名为trainData的数据集进行了小型测试:

(u1, m1, 1)
(u1, m4, 1)
(u2, m2, 1)
(u2, m3, 1)
(u3, m1, 1)
(u3, m3, 1)
(u3, m4, 1)
(u4, m3, 1)
(u4, m4, 1)
(u5, m2, 1)
(u5, m4, 1)

第一列包含用户,第二列包含用户评分的物品,第三列包含评分。

在我的scala代码中,我使用以下方式训练了模型:

myModel = ALS.trainImplicit(trainData, 3, 5, 0.01, 1.0)

我尝试使用以下指令检索u1的一些建议:

recommendations = myModel.recommendProducts(idUser, 2)

其中 idUser 包含分配给用户u1的 ID。 根据我的建议,我得到:

(u1, m1, 1.0536233346170754)
(u1, m4, 0.8540954252858661)
(u1, m3, 0.09069877419040584)
(u1, m2, -0.1345521479521654)

如您所见,前两行显示推荐的物品是用户u1已经评价过的(m1和m4)。 不论我选择哪个用户来获得推荐,我总是得到相同的结果(首先推荐的是用户已经评价过的物品)。
我觉得这很奇怪!有什么问题吗?
1个回答

4
我认为使用recommendProducts的预期行为就是这样。当你训练ALS等矩阵分解算法时,你试图找到一个评分,将每个用户与每个物品联系起来。
ALS基于用户已经评过分的物品来完成这项工作,因此当你为给定的用户查找推荐时,模型会最确定已经看到的评分,所以它大多数情况下会推荐已经评过分的产品。
你需要做的是保留每个用户评分的产品列表,并在进行推荐时对其进行过滤。
编辑:
我深入研究了源代码和文档,以确保我说的话是正确的。 ALS.recommendProducts是在类MatrixFactorizationModel(源代码)中实现的。你可以在那里看到,在进行推荐时,模型并不关心用户是否已经对该物品评分。
你应该注意,如果你使用隐式评分,那么你肯定希望推荐用户已经隐式评价过的产品:想象一下,如果你的隐式评分是在线商店中产品的页面浏览量,你希望的是用户购买该产品。
我没有接触过那本书《Spark高级分析》,所以我无法评论那里的解释和示例。
文档:

我不同意你的答案,因为你所描述的预期行为与书籍《使用Spark进行高级分析》中提出的解释和示例不符。 - semteu
我更新了我的答案,加入了来自源代码和文档的信息。 - João Almeida

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接