Spark 0.9.1 MLLib 机器学习库简介

Spark 0.9.1 MLLib 

机器学习库简介 



  • 依赖 
  • 二元分类 
  • 线性回归 
  • 聚类 
  • 协同过滤

    • 隐性反馈 vs 显性反馈 
      
  • 梯度下降基础算法 
  • 用Scala调用MLLib

    • 二元分类 
    • 线性回归 
    • 聚类 
    • 协同过滤 
      
  • 用Java调用MLLib 
  • 用Python调用MLLib

    • 二元分类 
    • 线性回归 
    • 聚类 
    • 协同过滤 
      
MLlib 是Spark对常用的机器学习算法的实现库,同时包括相关的测试和数据生成器。MLlib 目前支持四种常见的机器学习问题:二元分类,回归,聚类以及协同过滤,同时也包括一个底层的梯度下降优化基础算法。本指南将会简要介绍 MLlib 中所支持的功能,并给出相应的调用 MLlib 的例子。
依赖

  MLlib 将会调用 jblas 线性代数库,这个库本身依赖于原生的 Fortran 程序。如果你的节点中没有这些库,你也许会需要安装 gfortran runtime library 。如果程序没有办法自动检测到这些库,MLlib 将会抛出链接错误的异常。 
  如果想用 Python 调用 MLlib,你需要安装 NumPy 1.7 或者更新的版本。 
二元分类

  二元分类是一个监督学习问题。在这个问题中,我们希望将实体归类到两个独立的类别或标签的其中一个中,例如判断一个邮件是否是垃圾邮件。这个问题涉及在一组被  打过标签  的样例运行一个学习  算法  ,例如一组由(数字)特征和(相关的)类别标签所代表的实体。这个算法将会返回一个训练好的模型,该模型能够对标签未知的新个体进行潜在标签预测。 
  MLlib 目前支持两个适用于二元分类的标准模型家族: 线性支持向量机(SVMs) 和 逻辑回归 ,同时也包括分别适用与这两个模型家族的 L1 和 L2 正则化 变体。这些训练算法都利用了一个底层的梯度下降基础算法(描述如下)。二元分类算法的输入值是一个正则项参数(regParam) 和多个与梯度下降相关的参数( stepSize, numIterations, miniBatchFraction  ) 。 
目前可用的二元分类算法:


  • SVMWithSGD 
  • LogisticRegressionWithSGD 
线性回归

  线性回归是另一个经典的监督学习问题。在这个问题中,每个个体都有一个与之相关联的实数标签(而在二元分类中个体的标签都是二元的),并且我们希望在给出用于表示这些实体的数值特征后,所预测出的标签值可以尽可能接近实际值。MLlib支持线性回归和与之相关的 L1 ( lasso )和 L2 ( ridge ) 正则化的变体。MLlib中的回归算法也利用了底层的梯度下降基础算法(描述如下),输入参数与上述二元分类算法一致。 
目前可用的线性回归算法:


  • LinearRegressionWithSGD 
  • RidgeRegressionWithSGD 
  • LassoWithSGD 
聚类

  聚类是一个非监督学习问题,在这个问题上,我们的目标是将一部分实体根据某种意义上的相似度和另一部分实体聚在一起。聚类通常被用于探索性的分析,或者作为层次化监督学习管道网(hierarchical supervised learning pipeline) 的一个组件(其中每一个类簇都会用与训练不同的分类器或者回归模型)。 MLlib 目前已经支持作为最被广泛使用的聚类算法之一的 k-means 聚类算法,根据事先定义的类簇个数,这个算法能对数据进行聚类。MLlib 的实现中包含一个 k-means++ 方法的并行化变体 kmeans|| 。 MLlib 里面的实现有如下的参数: 


  • k 是所需的类簇的个数。 
  • maxIterations 是最大的迭代次数。 
  • initializationMode 这个参数决定了是用随机初始化还是通过 k-means|| 进行初始化。 
  • runs 是跑 k-means 算法的次数(k-mean 算法不能保证能找出最优解,如果在给定的数据集上运行多次,算法将会返回最佳的结果)。 
  • initializiationSteps 决定了 k-means|| 算法的步数。 
  • epsilon 决定了判断 k-means 是否收敛的距离阀值。 
目前可用的聚类算法:


  • KMeans 
协同过滤

  协同过滤 常被应用于推荐系统。这些技术旨在补充用户-商品关联矩阵中所缺失的部分。MLlib当前支持基于模型的协同过滤,其中用户和商品通过一小组隐语义因子进行表达,并且这些因子也用于预测缺失的元素。为此,我们实现了 交替最小二乘法(ALS) 来学习这些隐性语义因子。在 MLlib 中的实现有如下的参数: 
   numBlocks  是用于并行化计算的分块个数 (设置为-1为自动配置)。 
rank  是模型中隐语义因子的个数。 
iterations  是迭代的次数。 
lambda  是ALS的正则化参数。 
implicitPrefs  决定了是用  显性反馈  ALS的版本还是用适用  隐性反馈  数据集的版本。 
alpha  是一个针对于  隐性反馈  ALS 版本的参数,这个参数决定了偏好行为强度的  基准  。 
隐性反馈 vs 显性反馈

基于矩阵分解的协同过滤的标准方法一般将用户商品矩阵中的元素作为用户对商品的显性偏好。
  在许多的现实生活中的很多场景中,我们常常只能接触到  隐性的反馈  (例如游览,点击,购买,喜欢,分享等等)在 MLlib 中所用到的处理这种数据的方法来源于文献: Collaborative Filtering for Implicit Feedback Datasets 。 本质上,这个方法将数据作为二元偏好值和  偏好强度  的一个结合,而不是对评分矩阵直接进行建模。因此,评价就不是与用户对商品的显性评分而是和所观察到的用户偏好强度关联了起来。然后,这个模型将尝试找到隐语义因子来预估一个用户对一个商品的偏好。 
目前可用的协同过滤的算法:


  • ALS 
梯度下降基础算法

  梯度下降 (及其随机的变种)是非常适用于大型分布式计算的一阶优化方案。梯度下降旨在通过向一个函数当前点(当前的参数值)的负梯度方向移动的方式迭代地找到这个函数的本地最优解。MLlib 以梯度下降作为一个底层的基础算法,在上面开发了各种机器学习算法。梯度下降算法有如下的参数: 


  • gradient 这个类是用来计算要被优化的函数的随机梯度(如:相对于单一训练样本当前的参数值)。MLlib 包含常见损失函数 (hinge, logistic, least-squares) 的梯度类。梯度类将训练样本,其标签,以及当前的参数值作为输入值。 
  • updater 是在梯度下降的每一次迭代中更新权重的类。MLlib 包含适用于无正则项,L1 正则项和 L2 正则项3种情况下的类。 
  • stepSize 是一个表示梯度下降初始步长的数值。MLlib 中所有的更新器第 t 步的步长等于 stepSize / sqrt(t)。 
  • numIterations 表示迭代的次数。 
  • regParam 是在使用L1,L2 正则项时的正则化参数。 
  • miniBatchFraction 是每一次迭代中用来计算梯度的数据百分比。 
目前可用的梯度下降算法:


  • GradientDescent 
用Scala调用MLLib

  下面的代码段可以在 spark-shell 中运行。 
二元分类

下面的代码段演示了如何导入一份样本数据集,使用算法对象中的静态方法在训练集上执行训练算法,在所得的模型上进行预测并计算训练误差。
  
  1. import org.apache.spark.SparkContext
  2. import org.apache.spark.mllib.classification.SVMWithSGD
  3. import org.apache.spark.mllib.regression.LabeledPoint
  4. // Load and parse the data file
  5. val data = sc.textFile("mllib/data/sample_svm_data.txt")
  6. val parsedData = data.map { line =>
  7. val parts = line.split(' ')
  8. LabeledPoint(parts(0).toDouble, parts.tail.map(x => x.toDouble).toArray)
  9. }
  10. // Run training algorithm to build the model
  11. val numIterations = 20
  12. val model = SVMWithSGD.train(parsedData, numIterations)
  13. // Evaluate model on training examples and compute training error
  14. val labelAndPreds = parsedData.map { point =>
  15. val prediction = model.predict(point.features)
  16. (point.label, prediction)
  17. }
  18. val trainErr = labelAndPreds.filter(r => r._1 != r._2).count.toDouble / parsedData.count
  19. println("Training Error = " + trainErr)
复制代码

   import org . apache . spark . SparkContext 
  import org . apache . spark . mllib . classification . SVMWithSGD 
  import org . apache . spark . mllib . regression . LabeledPoint 
  // Load and parse the data file 
  val data = sc . textFile ( "mllib/data/sample_svm_data.txt" ) 
  val parsedData = data . map { line = > 
  val parts = line . split ( ' ' ) 
  LabeledPoint ( parts ( 0 ) . toDouble , parts . tail . map ( x = > x . toDouble ) . toArray ) 
  } 
  // Run training algorithm to build the model 
  val numIterations = 20 
  val model = SVMWithSGD . train ( parsedData , numIterations ) 
  // Evaluate model on training examples and compute training error 
  val labelAndPreds = parsedData . map { point = > 
  val prediction = model . predict ( point . features ) 
  ( point . label , prediction ) 
  } 
  val trainErr = labelAndPreds . filter ( r = > r . _1 != r . _2 ) . count . toDouble / parsedData . count 
  println ( "Training Error = " + trainErr ) 


  默认情况下,这个 SVMWithSGD.train() 方法使用正则参数为 1.0 的 L2 正则项。如果我们想配置这个算法,我们可以通过直接新建一个新的对象,并调用setter的方法,进一步个性化设置 SVMWithSGD 。所有其他的 MLlib 算法也是通过这样的方法来支持个性化的设置。比如,下面的代码给出了一个正则参数为0.1的 L1 正则化SVM变体,并且让这个训练算法迭代200遍。 
  
  1. import org.apache.spark.mllib.optimization.L1Updater
  2. val svmAlg = new SVMWithSGD()
  3. svmAlg.optimizer.setNumIterations(200)
  4. .setRegParam(0.1)
  5. .setUpdater(new L1Updater)
  6. val modelL1 = svmAlg.run(parsedData)
复制代码

   import org . apache . spark . mllib . optimization . L1Updater 
  val svmAlg = new SVMWithSGD ( ) 
  svmAlg . optimizer . setNumIterations ( 200 ) 
  . setRegParam ( 0.1 ) 
  . setUpdater ( new L1Updater ) 
  val modelL1 = svmAlg . run ( parsedData ) 


线性回归

  下面这个例子演示了如何导入训练集数据,将其解析为带标签点的RDD。然后,使用 LinearRegressionWithSGD 算法来建立一个简单的线性模型来预测标签的值。最后我们计算了均方差来评估预测值与实际值的 吻合度 。 
  
  1. import org.apache.spark.mllib.regression.LinearRegressionWithSGD
  2. import org.apache.spark.mllib.regression.LabeledPoint
  3. // Load and parse the data
  4. val data = sc.textFile("mllib/data/ridge-data/lpsa.data")
  5. val parsedData = data.map { line =>
  6. val parts = line.split(',')
  7. LabeledPoint(parts(0).toDouble, parts(1).split(' ').map(x => x.toDouble).toArray)
  8. }
  9. // Building the model
  10. val numIterations = 20
  11. val model = LinearRegressionWithSGD.train(parsedData, numIterations)
  12. // Evaluate model on training examples and compute training error
  13. val valuesAndPreds = parsedData.map { point =>
  14. val prediction = model.predict(point.features)
  15. (point.label, prediction)
  16. }
  17. val MSE = valuesAndPreds.map{ case(v, p) => math.pow((v - p), 2)}.reduce(_ + _)/valuesAndPreds.count
  18. println("training Mean Squared Error = " + MSE)
复制代码

   import org . apache . spark . mllib . regression . LinearRegressionWithSGD 
  import org . apache . spark . mllib . regression . LabeledPoint 
  // Load and parse the data 
  val data = sc . textFile ( "mllib/data/ridge-data/lpsa.data" ) 
  val parsedData = data . map { line = > 
  val parts = line . split ( ',' ) 
  LabeledPoint ( parts ( 0 ) . toDouble , parts ( 1 ) . split ( ' ' ) . map ( x = > x . toDouble ) . toArray ) 
  } 
  // Building the model 
  val numIterations = 20 
  val model = LinearRegressionWithSGD . train ( parsedData , numIterations ) 
  // Evaluate model on training examples and compute training error 
  val valuesAndPreds = parsedData . map { point = > 
  val prediction = model . predict ( point . features ) 
  ( point . label , prediction ) 
  } 
  val MSE = valuesAndPreds . map { case ( v , p ) = > math . pow ( ( v - p ) , 2 ) } . reduce ( _ + _ ) / valuesAndPreds . count 
  println ( "training Mean Squared Error = " + MSE ) 


  类似的,你也可以使用 RidgeRegressionWithSGD 和 LassoWithSGD 这两个算法,并比较这些算法在训练集上的均方差。 
聚类

  在下面的例子中,在载入和解析数据之后,我们使用 KMeans 对象来将数据聚类到两个类簇当中。所需的类簇个数会被传递到算法中。然后我们将计算集内均方差总和 (WSSSE). 你可以通过增加类簇的个数  k  来减小误差。 实际上,最优的类簇数通常是 1,因为这一点通常是WSSSE图中的 “低谷点”。 
  
  1. import org.apache.spark.mllib.clustering.KMeans
  2. // Load and parse the data
  3. val data = sc.textFile("kmeans_data.txt")
  4. val parsedData = data.map( _.split(' ').map(_.toDouble))
  5. // Cluster the data into two classes using KMeans
  6. val numIterations = 20
  7. val numClusters = 2
  8. val clusters = KMeans.train(parsedData, numClusters, numIterations)
  9. // Evaluate clustering by computing Within Set Sum of Squared Errors
  10. val WSSSE = clusters.computeCost(parsedData)
  11. println("Within Set Sum of Squared Errors = " + WSSSE)
复制代码

   import org . apache . spark . mllib . clustering . KMeans 
  // Load and parse the data 
  val data = sc . textFile ( "kmeans_data.txt" ) 
  val parsedData = data . map ( _ . split ( ' ' ) . map ( _ . toDouble ) ) 
  // Cluster the data into two classes using KMeans 
  val numIterations = 20 
  val numClusters = 2 
  val clusters = KMeans . train ( parsedData , numClusters , numIterations ) 
  // Evaluate clustering by computing Within Set Sum of Squared Errors 
  val WSSSE = clusters . computeCost ( parsedData ) 
  println ( "Within Set Sum of Squared Errors = " + WSSSE ) 


协同过滤

  在下面的例子中,我们导入的训练集中,数据每一行由一个用户,一个商品和相应的评分组成。假设评分是显性的,在这种情况下我们使用默认的 ALS.train() 方法。我们通过计算预测出的评分的均方差来评估这个推荐模型。 
  
  1. import org.apache.spark.mllib.recommendation.ALS
  2. import org.apache.spark.mllib.recommendation.Rating
  3. // Load and parse the data
  4. val data = sc.textFile("mllib/data/als/test.data")
  5. val ratings = data.map(_.split(',') match {
  6. case Array(user, item, rate) => Rating(user.toInt, item.toInt, rate.toDouble)
  7. })
  8. // Build the recommendation model using ALS
  9. val numIterations = 20
  10. val model = ALS.train(ratings, 1, 20, 0.01)
  11. // Evaluate the model on rating data
  12. val usersProducts = ratings.map{ case Rating(user, product, rate) => (user, product)}
  13. val predictions = model.predict(usersProducts).map{
  14. case Rating(user, product, rate) => ((user, product), rate)
  15. }
  16. val ratesAndPreds = ratings.map{
  17. case Rating(user, product, rate) => ((user, product), rate)
  18. }.join(predictions)
  19. val MSE = ratesAndPreds.map{
  20. case ((user, product), (r1, r2)) => math.pow((r1- r2), 2)
  21. }.reduce(_ + _)/ratesAndPreds.count
  22. println("Mean Squared Error = " + MSE)
复制代码

   import org . apache . spark . mllib . recommendation . ALS 
  import org . apache . spark . mllib . recommendation . Rating 
  // Load and parse the data 
  val data = sc . textFile ( "mllib/data/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 numIterations = 20 
  val model = ALS . train ( ratings , 1 , 20 , 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 ) ) = > math . pow ( ( r1 - r2 ) , 2 ) 
  } . reduce ( _ + _ ) / ratesAndPreds . count 
  println ( "Mean Squared Error = " + MSE ) 


  如果这个评分矩阵是通过其他的信息来源(如从其他的信号中提取出来的)所获得,你也可以使用 trainImplicit 的方法来得到更好的结果。 
  
  1. val model = ALS.trainImplicit(ratings, 1, 20, 0.01)
复制代码

  val model = ALS . trainImplicit ( ratings , 1 , 20 , 0.01 ) 

用Java调用MLLib

  所有 MLlib 中的算法都是对Java友好的,因此你可以用在 Scala 中一样的方法来导入和调用这些算法。唯一要注意的是,这些算法的输入值是 Scala RDD 对象,而在 Spark Java API 中用了分离的 JavaRDD 类。你可以在你的 JavaRDD对象中调用 .rdd() 的方法来将 Java RDD 转化成 Scala RDD 。 
用Python调用MLLib

  下面的列子可以在 PySpark shell 中得到测试。 
二元分类

下面的代码段表明了如何导入一份样本数据集,使用算法对象中的静态方法在训练集上执行训练算法,在所得的模型上进行预测并计算训练误差。
  
  1. from pyspark.mllib.classification import LogisticRegressionWithSGD
  2. from numpy import array
  3. # Load and parse the data
  4. data = sc.textFile("mllib/data/sample_svm_data.txt")
  5. parsedData = data.map(lambda line: array([float(x) for x in line.split(' ')]))
  6. model = LogisticRegressionWithSGD.train(parsedData)
  7. # Build the model
  8. labelsAndPreds = parsedData.map(lambda point: (int(point.item(0)),
  9. model.predict(point.take(range(1, point.size)))))
  10. # Evaluating the model on training data
  11. trainErr = labelsAndPreds.filter(lambda (v, p): v != p).count() / float(parsedData.count())
  12. print("Training Error = " + str(trainErr))
复制代码

   from pyspark . mllib . classification import LogisticRegressionWithSGD 
  from numpy import array 
  # Load and parse the data 
  data = sc . textFile ( "mllib/data/sample_svm_data.txt" ) 
  parsedData = data . map ( lambda line : array ( [ float ( x ) for x in line . split ( ' ' ) ] ) ) 
  model = LogisticRegressionWithSGD . train ( parsedData ) 
  # Build the model 
  labelsAndPreds = parsedData . map ( lambda point : ( int ( point . item ( 0 ) ) , 
  model . predict ( point . take ( range ( 1 , point . size ) ) ) ) ) 
  # Evaluating the model on training data 
  trainErr = labelsAndPreds . filter ( lambda ( v , p ) : v != p ) . count ( ) / float ( parsedData . count ( ) ) 
  print ( "Training Error = " + str ( trainErr ) ) 


线性回归

  下面这个例子给出了如何导入训练集数据,将其解析为带标签点的RDD。然后,这个例子使用了 LinearRegressionWithSGD 算法来建立一个简单的线性模型来预测标签的值。我们在最后计算了均方差来评估预测值与实际值的 吻合度 。 
  
  1. from pyspark.mllib.regression import LinearRegressionWithSGD
  2. from numpy import array
  3. # Load and parse the data
  4. data = sc.textFile("mllib/data/ridge-data/lpsa.data")
  5. parsedData = data.map(lambda line: array([float(x) for x in line.replace(',', ' ').split(' ')]))
  6. # Build the model
  7. model = LinearRegressionWithSGD.train(parsedData)
  8. # Evaluate the model on training data
  9. valuesAndPreds = parsedData.map(lambda point: (point.item(0),
  10. model.predict(point.take(range(1, point.size)))))
  11. MSE = valuesAndPreds.map(lambda (v, p): (v - p)**2).reduce(lambda x, y: x + y)/valuesAndPreds.count()
  12. print("Mean Squared Error = " + str(MSE))
复制代码

   from pyspark . mllib . regression import LinearRegressionWithSGD 
  from numpy import array 
  # Load and parse the data 
  data = sc . textFile ( "mllib/data/ridge-data/lpsa.data" ) 
  parsedData = data . map ( lambda line : array ( [ float ( x ) for x in line . replace ( ',' , ' ' ) . split ( ' ' ) ] ) ) 
  # Build the model 
  model = LinearRegressionWithSGD . train ( parsedData ) 
  # Evaluate the model on training data 
  valuesAndPreds = parsedData . map ( lambda point : ( point . item ( 0 ) , 
  model . predict ( point . take ( range ( 1 , point . size ) ) ) ) ) 
  MSE = valuesAndPreds . map ( lambda ( v , p ) : ( v - p ) * * 2 ) . reduce ( lambda x , y : x + y ) / valuesAndPreds . count ( ) 
  print ( "Mean Squared Error = " + str ( MSE ) ) 


  类似的,你也可以使用 RidgeRegressionWithSGD 和 LassoWithSGD 这两个算法,并比较这些算法在训练集上的均方差。 
聚类

  在下面的例子中,在载入和解析数据之后,我们使用 KMeans对象来将数据聚类到两个类簇当中。所需的类簇个数被传递到算法中。然后我们将计算集内均方差总和(WSSSE). 你可以通过增加类簇的个数  k  来减小误差。 实际上,最优的类簇数通常是 1,因为这一点通常是WSSSE图中的”低谷点”。 
  
  1. from pyspark.mllib.clustering import KMeans
  2. from numpy import array
  3. from math import sqrt
  4. # Load and parse the data
  5. data = sc.textFile("kmeans_data.txt")
  6. parsedData = data.map(lambda line: array([float(x) for x in line.split(' ')]))
  7. # Build the model (cluster the data)
  8. clusters = KMeans.train(parsedData, 2, maxIterations=10,
  9. runs=30, initialization_mode="random")
  10. # Evaluate clustering by computing Within Set Sum of Squared Errors
  11. def error(point):
  12. center = clusters.centers[clusters.predict(point)]
  13. return sqrt(sum([x**2 for x in (point - center)]))
  14. WSSSE = parsedData.map(lambda point: error(point)).reduce(lambda x, y: x + y)
  15. print("Within Set Sum of Squared Error = " + str(WSSSE))
复制代码

   from pyspark . mllib . clustering import KMeans 
  from numpy import array 
  from math import sqrt 
  # Load and parse the data 
  data = sc . textFile ( "kmeans_data.txt" ) 
  parsedData = data . map ( lambda line : array ( [ float ( x ) for x in line . split ( ' ' ) ] ) ) 
  # Build the model (cluster the data) 
  clusters = KMeans . train ( parsedData , 2 , maxIterations = 10 , 
  runs = 30 , initialization_mode = "random" ) 
  # Evaluate clustering by computing Within Set Sum of Squared Errors 
  def error ( point ) : 
  center = clusters . centers [ clusters . predict ( point ) ] 
  return sqrt ( sum ( [ x* * 2 for x in ( point - center ) ] ) ) 
  WSSSE = parsedData . map ( lambda point : error ( point ) ) . reduce ( lambda x , y : x + y ) 
  print ( "Within Set Sum of Squared Error = " + str ( WSSSE ) ) 


协同过滤

  在下面的例子中,我们导入的训练集中,数据每一行由一个用户,一个商品和相应的评分组成。假设评分是显性的,在这种情况下我们使用默认的> ALS.train() 方法。我们通过计算预测出的评分的均方差来评估这个推荐模型。 
  
  1. from pyspark.mllib.recommendation import ALS
  2. from numpy import array
  3. # Load and parse the data
  4. data = sc.textFile("mllib/data/als/test.data")
  5. ratings = data.map(lambda line: array([float(x) for x in line.split(',')]))
  6. # Build the recommendation model using Alternating Least Squares
  7. model = ALS.train(ratings, 1, 20)
  8. # Evaluate the model on training data
  9. testdata = ratings.map(lambda p: (int(p[0]), int(p[1])))
  10. predictions = model.predictAll(testdata).map(lambda r: ((r[0], r[1]), r[2]))
  11. ratesAndPreds = ratings.map(lambda r: ((r[0], r[1]), r[2])).join(predictions)
  12. MSE = ratesAndPreds.map(lambda r: (r[1][0] - r[1][1])**2).reduce(lambda x, y: x + y)/ratesAndPreds.count()
  13. print("Mean Squared Error = " + str(MSE))
复制代码

   from pyspark . mllib . recommendation import ALS 
  from numpy import array 
  # Load and parse the data 
  data = sc . textFile ( "mllib/data/als/test.data" ) 
  ratings = data . map ( lambda line : array ( [ float ( x ) for x in line . split ( ',' ) ] ) ) 
  # Build the recommendation model using Alternating Least Squares 
  model = ALS . train ( ratings , 1 , 20 ) 
  # Evaluate the model on training data 
  testdata = ratings . map ( lambda p : ( int ( p [ 0 ] ) , int ( 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 ) ) 


  如果这个评分矩阵是通过其他的信息来源(如从其他的信号中提取出来的)所获得,你也可以使用 trainImplicit 的方法来得到更好的结果。 
  
  1. import org.apache.spark.mllib.optimization.L1Updater
  2. val svmAlg = new SVMWithSGD()
  3. svmAlg.optimizer.setNumIterations(200)
  4. .setRegParam(0.1)
  5. .setUpdater(new L1Updater)
  6. val modelL1 = svmAlg.run(parsedData)0
复制代码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值