通过ALS获得错误的建议

sem*_*teu 5 recommendation-engine machine-learning collaborative-filtering apache-spark apache-spark-mllib

我写了一个火花程序来提出建议。然后,我使用了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)
Run Code Online (Sandbox Code Playgroud)

第一列包含用户,第二列包含用户评分的项目,第三列包含评分。

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

myModel = ALS.trainImplicit(trainData, 3, 5, 0.01, 1.0)
Run Code Online (Sandbox Code Playgroud)

我尝试使用以下说明为u1检索一些建议:

recommendations = myModel.recommendProducts(idUser, 2)
Run Code Online (Sandbox Code Playgroud)

其中,idUser包含受影响的用户u1的ID。 作为建议,我获得:

(u1, m1, 1.0536233346170754)
(u1, m4, 0.8540954252858661)
(u1, m3, 0.09069877419040584)
(u1, m2, -0.1345521479521654)
Run Code Online (Sandbox Code Playgroud)

如您所见,前两行显示推荐的项目是u1已经评级的项目(m1和m4)。无论我选择获得推荐的用户是什么,我总是会得到相同的行为(推荐的第一个项目是用户已经评分的项目)。

我觉得很奇怪!哪里有问题吗?

Joã*_*ida 4

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

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

您需要做的是保留每个用户评分的产品列表,并在提出推荐时对其进行过滤。

编辑:

我深入研究了源代码和文档,以确定我所说的内容。

ALS.recommendProducts在 MatrixFactorizationModel类中实现(源代码)。您可以看到,模型在提出推荐时并不关心用户是否已经对该项目进行了评分。

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

我无法访问《使用 Spark 进行高级分析》这本书,因此我无法对其中的解释和示例发表评论。

文件: