将结合前述知识进行综合实战,以达到所学即所用。在推荐系统项目中,讲解了推荐系统基本原理以及实现推荐系统的架构思路,有其余相关研发经验基础的同窗能够结合以往的经验,实现本身的推荐系统。git
Apache Spark github
Apache Mahout 算法
SVDFeature(C++) apache
LibMF(C+ +,Lin Chih-Jen) bash
协同过滤一般用于推荐系统。这些技术旨在填写用户项关联矩阵的缺失条目。 spark.ml目前支持基于模型的协同过滤,其中用户和产品由一小组可用于预测缺失条目的潜在因素描述。 spark.ml使用交替最小二乘(ALS)算法来学习这些潜在因素。 spark.ml中的实现具备如下参数:dom
numBlocks 用户和项目将被分区为多个块的数量,以便并行化计算(默认为10)。机器学习
rank 模型中潜在因子的数量(默认为10)。性能
maxIter 要运行的最大迭代次数(默认为10)。学习
regParam 指定ALS中的正则化参数(默认为1.0)。
implicitPrefs 指定是使用显式反馈ALS变体仍是使用适用于隐式反馈数据的变量(默认为false,这意味着使用显式反馈)。
alpha 适用于ALS的隐式反馈变量的参数,其控制偏好观察中的基线置信度(默认为1.0)。 nonnegative指定是否对最小二乘使用非负约束(默认为false)。
注意:基于DataFrame的ALS API目前仅支持用户和项ID的整数。 user和item id列支持其余数字类型,但id必须在整数值范围内。
基于矩阵分解的协同过滤的标准方法将用户项矩阵中的条目视为用户对项目给出的显式偏好,例如,给予电影评级的用户。
在许多现实世界的用例中,一般只能访问隐式反馈(例如,观看,点击,购买,喜欢,分享等)。 spark.ml中用于处理此类数据的方法取自Collaborative Filtering for Implicit Feedback Datasets。本质上,这种方法不是试图直接对评级矩阵进行建模,而是将数据视为表示用户操做观察强度的数字(例如点击次数或某人花在观看电影上的累积持续时间)。而后,这些数字与观察到的用户偏好的置信水平相关,而不是与项目的明确评级相关。而后,该模型试图找到可用于预测用户对项目的预期偏好的潜在因素。
咱们经过用户在更新用户因素时产生的评级数或在更新产品因子时收到的产品评级数来缩小正则化参数regParam以解决每一个最小二乘问题。 这种方法被命名为“ALS-WR”,并在“Netflix奖的大规模并行协同过滤”一文中进行了讨论。 它使regParam较少依赖于数据集的规模,所以咱们能够将从采样子集中学习的最佳参数应用于完整数据集,并指望得到相似的性能。
在使用ALS模型进行预测时,一般会遇到测试数据集中的用户和/或项目,这些用户和/或项目在训练模型期间不存在。这一般发生在两种状况中:
可是,这在交叉验证期间是不合须要的,由于任何NaN预测值都将致使评估指标的NaN结果(例如,使用RegressionEvaluator时)。这使得模型选择不可能。
Spark容许用户将coldStartStrategy参数设置为“drop”,以便删除包含NaN值的预测的DataFrame中的任何行。而后将根据非NaN数据计算评估度量而且该评估度量将是有效的。如下示例说明了此参数的用法。
注意:目前支持的冷启动策略是“nan”(上面提到的默认行为)和“drop”。未来可能会支持进一步的战略。
在如下示例中,咱们从MovieLens数据集加载评级数据,每行包含用户,电影,评级和时间戳。 而后,咱们训练一个ALS模型,默认状况下,该模型假设评级是显式的(implicitPrefs为false)。 咱们经过测量评级预测的均方根偏差来评估推荐模型。
import org.apache.spark.ml.evaluation.RegressionEvaluator
import org.apache.spark.ml.recommendation.ALS
case class Rating(userId: Int, movieId: Int, rating: Float, timestamp: Long)
def parseRating(str: String): Rating = {
val fields = str.split("::")
assert(fields.size == 4)
Rating(fields(0).toInt, fields(1).toInt, fields(2).toFloat, fields(3).toLong)
}
val ratings = spark.read.textFile("data/mllib/als/sample_movielens_ratings.txt")
.map(parseRating)
.toDF()
val Array(training, test) = ratings.randomSplit(Array(0.8, 0.2))
// Build the recommendation model using ALS on the training data
val als = new ALS()
.setMaxIter(5)
.setRegParam(0.01)
.setUserCol("userId")
.setItemCol("movieId")
.setRatingCol("rating")
val model = als.fit(training)
// Evaluate the model by computing the RMSE on the test data
// Note we set cold start strategy to 'drop' to ensure we don't get NaN evaluation metrics model.setColdStartStrategy("drop") val predictions = model.transform(test) val evaluator = new RegressionEvaluator() .setMetricName("rmse") .setLabelCol("rating") .setPredictionCol("prediction") val rmse = evaluator.evaluate(predictions) println(s"Root-mean-square error = $rmse") // Generate top 10 movie recommendations for each user val userRecs = model.recommendForAllUsers(10) // Generate top 10 user recommendations for each movie val movieRecs = model.recommendForAllItems(10) // Generate top 10 movie recommendations for a specified set of users val users = ratings.select(als.getUserCol).distinct().limit(3) val userSubsetRecs = model.recommendForUserSubset(users, 10) // Generate top 10 user recommendations for a specified set of movies val movies = ratings.select(als.getItemCol).distinct().limit(3) val movieSubSetRecs = model.recommendForItemSubset(movies, 10) 复制代码
若是评级矩阵是从另外一个信息源派生的(即从其余信号推断出来),您能够将implicitPrefs设置为true以得到更好的结果:
val als = new ALS()
.setMaxIter(5)
.setRegParam(0.01)
.setImplicitPrefs(true)
.setUserCol("userId")
.setItemCol("movieId")
.setRatingCol("rating")
复制代码
数据集 tab分割
代码分割数据集
分割结果
MovieLens数据集由GroupLens研究组在 University of Minnesota — 明尼苏达大学(与咱们使用数据集无关)中组织的。 MovieLens是电影评分的集合,有各类大小。 数据集命名为1M,10M和20M,是由于它们包含1,10和20万个评分。 最大的数据集使用约14万用户的数据,并覆盖27,000部电影。 除了评分以外,MovieLens数据还包含相似“Western”的流派信息和用户应用的标签,如“over the top”和“Arnold Schwarzenegger”。 这些流派标记和标签在构建内容向量方面是有用的。内容向量对项目的信息进行编码,例如颜色,形状,流派或真正的任何其余属性 - 能够是用于基于内容的推荐算法的任何形式。
MovieLens的数据在过去20年中已经由大学的学生以及互联网上的人们进行收集了。 MovieLens有一个网站,您能够注册,贡献本身的评分,并接收由GroupLens组实施的几个推荐者算法这里之一的推荐内容。
用户ID
所推电影