Spark ALS:为新用户推荐

数据挖掘 阿帕奇火花 推荐系统 pyspark
2021-10-06 04:29:17

问题

如何在 Spark 训练的 ALS 模型中预测新用户的评分?(新 = 在训练期间未出现)

问题

我在这里关注官方 Spark ALS 教程:

http://ampcamp.berkeley.edu/big-data-mini-course/movie-recommendation-with-mllib.html

我能够用一个不错的 MSE 建立一个好的推荐器,但我正在努力解决如何将新数据输入到模型中。该教程在训练之前更改了第一个用户的评分,但这确实是一个 hack。他们给出以下提示:

9.2. 增强矩阵因子:

在本教程中,我们将您的评分添加到训练集中。为您获得建议的更好方法是首先训练矩阵分解模型,然后使用您的评分来扩充模型。如果你觉得这听起来很有趣,你可以看看 MatrixFactorizationModel 的实现,看看如何为新用户和新电影更新模型。

但是,实施对我一点帮助都没有。理想情况下,我正在寻找类似的东西:

predictions = model.predictAllNew(newinput)

但不存在这样的方法。我可以去修改原始的 RDD,但我认为这需要我重新训练模型,所以这也不是一个理想的解决方案。肯定有更优雅的方式吗?

我现在在哪里:

我想我需要找到新向量的潜在表示。根据原始论文,我们可以这样计算:

X=(C+λ一世)-1Cp()

但是当我使用论文中的值进行计算时,它与模型中的值不匹配。我修复了 alpha 和正则化参数,但我认为 MLLIB 实现有不同C执行。在这里定义(见第 1304 行),但不擅长 Scala,这对我来说很难逆向工程......

我目前的尝试:

V = model.productFeatures().map(lambda x: (x[1])).collect() #product latent matrix Y

Cui =  alpha * np.abs(newinput)
Cui =  (1. + Cui) / (Cui)
Cui[np.where(newinput == 0)] = 0
Cui = np.diag(Cui)

lambdaI = len(np.where(newinput!=0)) * regularization_parameter * np.eye(np.shape(V)[1]) #
term   = np.dot(np.dot(Vt,Cui),V)+lambdaI
term   = np.dot(np.linalg.inv(term),Vt)
term   = np.dot(term,Cui)
term   = np.dot(term,newinput)
latentinput = term

但这不匹配。

1个回答

这里有很多问题。首先,对于没有数据的真正新用户,没有办法使用推荐模型。如果您实际上没有关于用户的信息,那么您唯一能做的就是提供一些默认建议。

当然,一旦你有任何数据,并且你可以重建模型以包含用户,你就可以提出建议。你可以在 Spark 中做到这一点,但你已经知道了。如果您需要在运行时添加有关新用户的信息,这将花费太长时间。您想要的技术称为“折叠”,用于在给定用户与之交互的项目的情况下(大约)确定新的用户向量是什么。这只是一些线性代数,并且确实遵循您给出的方程式。

我挖出了一张旧幻灯片,可能会有所帮助:

ALS 折叠式

“Cu”并没有什么不同。我添加了一个“扩展”来处理负输入的情况,但对于正输入也是如此。

这是折叠的实现,尽管我认为它太密集而没有多大价值:

https://github.com/OryxProject/oryx/blob/2c01d496f93f2825a076eb7fe492aa39a5290aa6/app/oryx-app-common/src/main/java/com/cloudera/oryx/app/als/ALSUtils.java#L74

计算用户-项目交互隐含的新用户向量是相当容易的线性代数。我发现的棘手部分是决定它的重量。

希望这是朝着正确方向的推动。