spark 协同过滤 (翻译)

来源:互联网 发布:软件测试技术 图片 编辑:程序博客网 时间:2024/06/05 23:56

spark 协同过滤

协同过滤是一个常用的推荐算法。这些技术用于填充一个user-item的关联矩阵的缺失项。spark.mllib目前支持基于模型的协同过滤,用户和产品能被一组比较小的潜在因素描述,那样算法就可以来预测缺失的项目。spark.mllib使用最小二乘法(ALS)来学习潜在因素。spark.mllib 主要有以下这些参数:

  • numBlocks 用于并行计算的块的数量(自动设置为-1)
  • rank 是模型中潜在因素的数量
  • iterations 运行时的迭代次数
  • lambda 指定ALS中正则化的参数
  • implicitPrefs 指定使用一个显式反馈的还是一个隐式反馈的ALS变体
  • alpha 是一个参数用于查看隐式反馈的ALS变体控制优先级的基准线

显式或隐式反馈

矩阵分解是协同过滤对待user-item矩阵的一个首选方法。
在现实中往往只能得到隐式的反馈(如:浏览,点击,购买,分享等)。spark-lib中处理隐式反馈信息可以参考协同过滤的隐式反馈的数据集。本质上讲这种方法并没有直接构建评级的矩阵模型,它只是优先使用的是二进制的数据。相关的评级只是用来观察用户的偏好,而不是明确的评级。然后用模型找到潜在的因素,进而预测用户的偏好。

调整正则化参数

从1.1版本,我们就缩放正则化参数lambda来解决最小二乘法的问题(user在更新user因数产生的评级或者product在更新product因数产生的评级)。有一种方法叫做ALS-WR参考资料在Large-Scale Parallel Collaborative Filtering for the Netflix Prize。它让lambda较少的依赖于数据集的规模。那样我们就可以在抽样数据集或者能够完整的数据集都得到好的性能。

实例

Scala

在下面的例子里面我们采用评级数据。每一行包括一个用户,一个产品和一个评级数据。由于评级数据是显式的,我们就可以使用默认的ALS.train()方法计算,使用均方差来评估推荐模型的好坏。
详细的API文档ALS Scala docs

 import org.apache.spark.mllib.recommendation.ALSimport org.apache.spark.mllib.recommendation.MatrixFactorizationModelimport org.apache.spark.mllib.recommendation.Rating// Load and parse the dataval 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 ALSval rank = 10val numIterations = 10val model = ALS.train(ratings, rank, numIterations, 0.01)// Evaluate the model on rating dataval 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 modelmodel.save(sc, "target/tmp/myCollaborativeFilter")val sameModel = MatrixFactorizationModel.load(sc, "target/tmp/myCollaborativeFilter")

完整的例子在源码中examples/src/main/scala/org/apache/spark/examples/mllib/RecommendationExample.scala。如果评级矩阵来源于其它的信息源。使用trainImplicit方法可以得到更好的结果。

val alpha = 0.01val lambda = 0.01val model = ALS.trainImplicit(ratings, rank, numIterations, lambda, alpha)

可以参考spark快速启动指南中的the Self-Contained Applications 来运行上面的程序。保证spark-mlib作为依赖文件加入到你的工程中了。

Java

所有MLlib中的方法都可以被java很好的使用。你可以像scala中那样使用它们。唯一要注意的是,scala中使用的是 Scala RDD 对象,而Spark Java API中使用的是独立的 JavaRDD对象。你可以通过调用 JavaRDD对象的 .rdd() 来转换成 Scala RDD 对象。下面是一个在源码中提供的例子程序。
详细javaAPI文档 ALS Java docs

import scala.Tuple2;import org.apache.spark.api.java.*;import org.apache.spark.api.java.function.Function;import org.apache.spark.mllib.recommendation.ALS;import org.apache.spark.mllib.recommendation.MatrixFactorizationModel;import org.apache.spark.mllib.recommendation.Rating;import org.apache.spark.SparkConf;SparkConf conf = new SparkConf().setAppName("Java Collaborative Filtering Example");JavaSparkContext jsc = new JavaSparkContext(conf);// Load and parse the dataString path = "data/mllib/als/test.data";JavaRDD<String> data = jsc.textFile(path);JavaRDD<Rating> ratings = data.map(  new Function<String, Rating>() {    public Rating call(String s) {      String[] sarray = s.split(",");      return new Rating(Integer.parseInt(sarray[0]), Integer.parseInt(sarray[1]),        Double.parseDouble(sarray[2]));    }  });// Build the recommendation model using ALSint rank = 10;int numIterations = 10;MatrixFactorizationModel model = ALS.train(JavaRDD.toRDD(ratings), rank, numIterations, 0.01);// Evaluate the model on rating dataJavaRDD<Tuple2<Object, Object>> userProducts = ratings.map(  new Function<Rating, Tuple2<Object, Object>>() {    public Tuple2<Object, Object> call(Rating r) {      return new Tuple2<Object, Object>(r.user(), r.product());    }  });JavaPairRDD<Tuple2<Integer, Integer>, Double> predictions = JavaPairRDD.fromJavaRDD(  model.predict(JavaRDD.toRDD(userProducts)).toJavaRDD().map(    new Function<Rating, Tuple2<Tuple2<Integer, Integer>, Double>>() {      public Tuple2<Tuple2<Integer, Integer>, Double> call(Rating r){        return new Tuple2<Tuple2<Integer, Integer>, Double>(          new Tuple2<Integer, Integer>(r.user(), r.product()), r.rating());      }    }  ));JavaRDD<Tuple2<Double, Double>> ratesAndPreds =  JavaPairRDD.fromJavaRDD(ratings.map(    new Function<Rating, Tuple2<Tuple2<Integer, Integer>, Double>>() {      public Tuple2<Tuple2<Integer, Integer>, Double> call(Rating r){        return new Tuple2<Tuple2<Integer, Integer>, Double>(          new Tuple2<Integer, Integer>(r.user(), r.product()), r.rating());      }    }  )).join(predictions).values();double MSE = JavaDoubleRDD.fromRDD(ratesAndPreds.map(  new Function<Tuple2<Double, Double>, Object>() {    public Object call(Tuple2<Double, Double> pair) {      Double err = pair._1() - pair._2();      return err * err;    }  }).rdd()).mean();System.out.println("Mean Squared Error = " + MSE);// Save and load modelmodel.save(jsc.sc(), "target/tmp/myCollaborativeFilter");MatrixFactorizationModel sameModel = MatrixFactorizationModel.load(jsc.sc(),  "target/tmp/myCollaborativeFilter");  

完整的例子在源码中examples/src/main/java/org/apache/spark/examples/mllib/JavaRecommendationExample.java。可以参考spark快速启动指南中的the Self-Contained Applications 来运行上面的程序。保证spark-mlib作为依赖文件加入到你的工程中了。

Python

在下面的例子里面我们采用评级数据。每一行包括一个用户,一个产品和一个评级数据。由于评级数据是显式的,我们就可以使用默认的ALS.train()方法计算,使用均方差来评估推荐模型的好坏。
详细的Python APIALS Python docs

from pyspark.mllib.recommendation import ALS, MatrixFactorizationModel, Rating# Load and parse the datadata = 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 Squaresrank = 10numIterations = 10model = ALS.train(ratings, rank, numIterations)# Evaluate the model on training datatestdata = 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).mean()print("Mean Squared Error = " + str(MSE))# Save and load modelmodel.save(sc, "target/tmp/myCollaborativeFilter")sameModel = MatrixFactorizationModel.load(sc, "target/tmp/myCollaborativeFilter")  

完整的例子在源码中examples/src/main/python/mllib/recommendation_example.py。如果评级矩阵来源于其它的信息源。使用trainImplicit方法可以得到更好的结果。

# Build the recommendation model using Alternating Least Squares based on implicit ratingsmodel = ALS.trainImplicit(ratings, rank, numIterations, alpha=0.01)

可以参考spark快速启动指南中的the Self-Contained Applications 来运行上面的程序。保证spark-mlib作为依赖文件加入到你的工程中了。

指南

在spark2014年峰会上的实战训练中提供了一个个性化的电影推荐的例子。

0 0