Spark - 如何在生产中使用训练有素的推荐模型?

Spark - How to use the trained recommender model in production?

我正在使用 Spark 构建推荐系统原型。在学习了一些教程之后,我已经能够从我的数据中训练 MatrixFactorizationModel

但是Spark mllib训练出来的模型只是一个Serializable。我如何使用这个模型为真实用户做推荐?我的意思是,如果用户数据已增加,我如何将模型保存到某种数据库或更新它?

比如Mahout推荐库训练出来的模型可以存储到Redis之类的数据库中,以后我们可以查询推荐商品列表。但是我们如何在 Spark 中做类似的事情呢?有什么建议吗?

首先,您所指的 Mahout 中的 "model" 不是模型,而是预先计算的推荐列表。您也可以使用 Spark 执行此操作,为用户批量计算推荐,并将它们保存在您喜欢的任何地方。这与序列化模型无关。如果您不想进行实时更新或评分,您可以就此打住,像使用 Mahout 一样使用 Spark 进行批处理。

但我同意,在很多情况下,您确实希望将模型运送到其他地方并提供服务。如您所见,Spark 中的其他模型是 Serializable,但不是 MatrixFactorizationModel. (Yes, even though it's marked as such, it won't serialize.) Likewise, there is a standard serialization for predictive models called PMML,但它不包含因子矩阵模型的词汇表。

其实道理是一样的。许多预测模型(如 SVM 或逻辑回归模型)只是一小部分系数,而因式分解矩阵模型则非常庞大,包含两个可能具有数十亿个元素的矩阵。这就是为什么我认为 PMML 没有任何合理的编码。

同样,在 Spark 中,这意味着实际矩阵是 RDD,不能直接序列化。您可以将这些 RDD 保存到存储中,使用 Spark 在其他地方重新读取它们,然后以这种方式手动重新创建 MatrixFactorizationModel

但是您不能使用 Spark 提供或更新模型。为此,您实际上是在考虑编写一些代码来动态执行更新和计算推荐。

我不介意在这里建议 Oryx project, since its point is to manage exactly this aspect, particularly for ALS recommendation. In fact, the Oryx 2 项目基于 Spark,尽管处于 alpha 阶段,但已经包含完整的管道以序列化和提供 MatrixFactorizationModel 的输出。不知道能不能满足你的需求,但至少可以作为一个有趣的参考点。

另一种用Spark创建recs的方法是搜索引擎方法。这基本上是由 Solr 或 Elasticsearch 提供的同现推荐系统。将分解与共现进行比较超出了这个问题,所以我只描述后者。

您将交互(用户 ID、项目 ID)提供给 Mahout 的 spark-itemsimilarity。这会为交互数据中看到的每个项目生成一个相似项目列表。默认情况下,它会以 csv 格式出现,因此可以存储在任何地方。但是需要搜索引擎收录。

在任何情况下,当您想要获取使用用户历史记录作为查询的记录时,您都会得到一个有序的项目列表作为记录。

此方法的一个好处是可以为任意数量的用户操作计算指标。可以使用用户采取的与您要推荐的内容相关的任何操作。例如,如果你想推荐购买但你也记录产品视图。如果您将产品浏览与购买一样对待,您可能会得到更差的推荐(我试过)。但是,如果您计算购买指标和产品视图的另一个(实际上是交叉共现)指标,它们同样可以预测购买。这具有增加用于 recs 的数据的效果。可以对用户位置进行相同类型的操作,以将位置信息混合到购买记录中。

您还可以根据上下文来调整您的推荐。如果您在目录的 "electronics" 部分,您可能希望 recs 偏向于电子产品。将电子设备添加到针对项目的 "category" 元数据字段的查询中,并在查询中对其进行提升,并且您有偏见的建议。

由于所有指标的偏差和混合都发生在查询中,因此它使 recs 引擎可以轻松调整到多个上下文,同时仅维护通过搜索引擎进行的一个多字段查询。我们从 Solr 或 Elasticsearch 获得可扩展性。

分解或搜索方法的另一个好处是可以使用全新的用户和新的历史记录来创建推荐,而旧的 Mahout 推荐系统只能向工作时已知的用户和交互推荐 运行.

这里的描述:

您应该 运行 model.predictAll() 在减少的 RDD 集(用户,产品)对上,就像在 Mahout Hadoop 作业中一样,并存储结果以供在线使用...

https://github.com/apache/mahout/blob/master/mrlegacy/src/main/java/org/apache/mahout/cf/taste/hadoop/item/RecommenderJob.java

您可以使用函数 .save(sparkContext, outputFolder) 将模型保存到您选择的文件夹中。在实时给出建议时,您只需使用 MatrixFactorizationModel.load(sparkContext, modelFolder) 函数将其加载为 MatrixFactorizationModel 对象.

@Sean Owen的一个问题:MatrixFactorizationObject 是否包含因式分解矩阵:user-feature 和 item-feature 矩阵而不是 recommendations/predicted 评级。