ALS.recommendation 得到错误的推荐

Get wrong recommendation with ALS.recommendation

我写了一个 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 包含影响用户的 ID u1 作为建议,我获得:

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

可以看到,前两行显示推荐的项目是u1已经评价过的项目(m1和m4)。 无论我 select 获得推荐的用户是什么,我总是得到相同的行为(推荐的第一个项目是用户已经评价的项目)。

我觉得很奇怪!有什么问题吗?

我认为这是使用 recommendProducts 的预期行为,当您训练 ALS 等矩阵分解算法时,您会尝试找到将每个用户与每个项目相关联的评分。

ALS 根据用户已经评分的项目执行此操作,因此当您为给定用户查找推荐时,该模型将最确定它已经看到的评分,因此大多数时候它会推荐已评级的产品。

您需要做的是保留每个用户评价的产品列表,并在提出建议时过滤它们。

编辑:

我深入研究了源代码和文档以确保我在说什么。

ALS.recommendProducts是在classMatrixFactorizationModel (source code)中实现的。您可以在那里看到,模型在提出建议时并不关心用户是否已经对该项目进行了评分。

并且您应该注意,如果您使用隐式评级,那么您肯定希望推荐已经被用户隐式评级的产品: 想象一下这样一种情况,您的隐含评级是您的产品在在线商店中的页面浏览量,而您想要的是用户购买该产品。

我无法访问那本书 Advanced analytics with Spark 所以我无法对那里的解释和示例发表评论。

文档: