协作过滤通常用于推荐系统。这些技术旨在填补用户-项目关联矩阵中丢失的条目。spark.mllib 目前支持基于模型的协同过滤,其中用户和项目通过一小组潜在因素来描述,可用于预测缺失的条目。spark.mllib 使用 ALS(交替最小二乘法)算法来学习这些潜在因素。spark.mllib 中的实现具有以下参数:
基于矩阵分解的协同过滤的标准方法是将用户-项目关联矩阵中的元素视为用户对项目的显式偏好,例如用户对电影的评分。在现实世界中的许多用例中,通常只能接触到隐式的反馈(例如浏览,点击,购买,喜欢,分享等)。在 spark.mllib 中使用基于隐式反馈数据集的协同过滤的方法来处理这些数据。实际上,这种方法不是直接对数据矩阵进行建模,而是将数据视为代表用户行为意愿强度的数字(例如点击的次数或某人累积观看电影的时间)。然后,这些数字与观察到的用户偏好的置信水平相关,而不是给予项目的明确评级。 然后,该模型尝试找到可用于预测用户对项目的预期偏好的潜在因素。
自 V1.1 起,我们通过用户在更新用户因素中产生的评分,或产品在更新产品因素中收到的评分来求解每个最小二乘问题的规则化参数 lambda 。 这种方法被命名为“ ALS-WR ”(加权正则化交替最小二乘法),并在论文“ Large-Scale Parallel Collaborative Filtering for the Netflix Prize ”中进行了讨论。 它使 lambda 对数据集的规模依赖较少,因此我们可以将从采样子集学到的最佳参数应用于完整数据集,并期望能有相似的表现。
在以下示例中,我们加载评估数据。 每行由用户,产品和评级组成。 我们使用默认的 ALS.train() 方法,该方法假设评级是显式的。 我们通过测量评级预测的均方误差来评估推荐模型。
有关API的更多详细信息,请参阅 ALS Scala 文档。
import org.apache.spark.mllib.recommendation.ALS import org.apache.spark.mllib.recommendation.MatrixFactorizationModel import org.apache.spark.mllib.recommendation.Rating // Load and parse the data val data = sc.textFile("data/mllib/als/test.data") val ratings = data.map(_.split(',') match { case Array(user, item, rate) => Rating(user.toInt, item.toInt, rate.toDouble) }) // Build the recommendation model using ALS val rank = 10 val numIterations = 10 val model = ALS.train(ratings, rank, numIterations, 0.01) // Evaluate the model on rating data val usersProducts = ratings.map { case Rating(user, product, rate) => (user, product) } val predictions = model.predict(usersProducts).map { case Rating(user, product, rate) => ((user, product), rate) } val ratesAndPreds = ratings.map { case Rating(user, product, rate) => ((user, product), rate) }.join(predictions) val MSE = ratesAndPreds.map { case ((user, product), (r1, r2)) => val err = (r1 - r2) err * err }.mean() println("Mean Squared Error = " + MSE) // Save and load model model.save(sc, "target/tmp/myCollaborativeFilter") val sameModel = MatrixFactorizationModel.load(sc, "target/tmp/myCollaborativeFilter")
可以在 Spark repo 中的“examples/src/main/scala/org/apache/spark/examples/mllib/RecommendationExample.scala”中查找完整的示例代码。
如果评分矩阵是来自于另一个信息来源(即从其他信号推断出来),您可以使用 implicitPrefs 方法 以获得更好的结果:
val alpha = 0.01 val lambda = 0.01 val model = ALS.trainImplicit(ratings, rank, numIterations, lambda, alpha)
为了运行上述应用程序,请按照“Spark快速入门指南”的“自包含应用程序”部分中提供的说明进行操作。 确保将spark-mllib作为依赖并包含在您的构建文件中。