下面是章节协同过滤的目录(其他内容参见全文目录)
协同过滤
协同过滤(Collaborative filtering)是推荐系统的一个常用算法。这个技术的目的在于填充user-item矩阵中的缺失项。MLlib当前支持基于模型的协同过滤,在这种方法中,用户和产品通过一个小的潜在因素(latent factors)集合来描述,这个潜在因素集合可以预测缺失项。MLlib使用交替最小二乘法alternating least squares (ALS) 来学习这些潜在因素。MLlib的实现有下列参数:
- numBlocks 并行计算的块数量。(默认值为-1,表示自动配置)
- rank 模型中潜在因素的数量。
- iterations 迭代次数。
- lambda ALS中的正则化参数。
- implicitPrefs 制定是否使用显示反馈ALS变体(或者说是对隐式反馈数据的一种适应)
- alpha 应用于隐式数据的ALS变体,它控制的是观察到偏好的基本置信度。
显式反馈 VS隐式反馈
基于矩阵分解的协同过滤,其标准做法是将user-time矩阵中的条目看做用户对该条目的显式偏好。
在现实世界中,通常只能使用隐式的反馈(例如,查看、点击、购买、喜欢、分享等等)。MLlib中处理这种数据的方法来自 Collaborative Filtering for Implicit Feedback Datasets(针对隐式反馈的协同过滤)。这种方法将数据作为是否偏好及对应的置信度的组合来使用,而不是对评分矩阵直接建模。也就是说评分跟观察到的用户的偏好置信度相关,而不是作为对条目的显式评分。然后尝试找到潜在因素从而预测用户对某个条目的喜好。
正则化参数的扩展
从版本1.1开始,MLlib中对每个解决最小二乘问题的正则化参数lambda做了扩展:一个是在更新用户因素时用户产生的评分数量;另一个是在更新产品因素时产品被评分的数量。这个方法叫做ALS-WR(alternating-least-squares with weighted-λ -regularization),这篇论文有详细的介绍:Large-Scale Parallel Collaborative Filtering for the Netflix Prize。该算法减小了参数lambda对数据集规模的依赖。所以我们可以把一个从抽样子集上学习到的最好的参数应用到全部数据集上,并能预计得到一样好的效果。
示例
下面的例子中我们导入了评分数据(每行由用户、产品、评分构成)。并使用ALS.train()方法进行训练,该方法默认假设评分是显式的。最后通过评分预测的均方误差评估推荐效果。
from pyspark.mllib.recommendation import ALS, MatrixFactorizationModel, Rating
# Load and parse the data
data = sc.textFile("data/mllib/als/test.data")
ratings = data.map(lambda l: l.split(',')).map(lambda l: Rating(int(l[0]), int(l[1]), float(l[2])))
# Build the recommendation model using Alternating Least Squares
rank = 10
numIterations = 20
model = ALS.train(ratings, rank, numIterations)
# Evaluate the model on training data
testdata = ratings.map(lambda p: (p[0], p[1]))
predictions = model.predictAll(testdata).map(lambda r: ((r[0], r[1]), r[2]))
ratesAndPreds = ratings.map(lambda r: ((r[0], r[1]), r[2])).join(predictions)
MSE = ratesAndPreds.map(lambda r: (r[1][0] - r[1][1])**2).reduce(lambda x, y: x + y) / ratesAndPreds.count()
print("Mean Squared Error = " + str(MSE))
# Save and load model
model.save(sc, "myModelPath")
sameModel = MatrixFactorizationModel.load(sc, "myModelPath")
如果评分矩阵来源于其他信息源(例如,推断自其他信号),我们可以使用ALS.trainImplicit()方法来获得更好的结果。
# Build the recommendation model using Alternating Least Squares based on implicit ratings
model = ALS.trainImplicit(ratings, rank, numIterations, alpha=0.01)
为了运行上面的程序,参考最新Spark编程指南Python版[spark 1.3.0][译]。另外要导入依赖的spark-mllib库。
教程
Spark Summit 2014上的训练练习包含了一个实践教程:personalized movie recommendation with MLlib(使用MLlib的个性化电影推荐)。