Spark2.0机器学习系列之2:基于Pipeline、交叉验证、ParamMap的模型选择和超参数调优

Spark中的CrossValidation

  • Spark中采用是k折交叉验证 (k-fold cross validation)。举个例子,例如10折交叉验证(10-fold cross validation),将数据集分成10份,轮流将其中9份做训练1份做验证,10次的结果的均值作为对算法精度的估计。
  • 10折交叉检验最常见,是因为通过利用大量数据集、使用不同学习技术进行的大量试验,表明10折是获得最好误差估计的恰当选择,而且也有一些理论根据可以证明这一点。但这并非最终结论,争议仍然存在。而且似乎5折或者20折与10折所得出的结果也相差无几。
  • 交叉检验常用于分析模型的泛化能力,提高模型的稳定。相对于手工探索式的参数调试,交叉验证更具备统计学上的意义。
  • 在Spark中,Cross Validation和ParamMap(“参数组合”的Map)结合使用。具体做法是,针对特定的Param组合,CrossValidator计算K (K 折交叉验证)个评估分数的平均值。然后和其它“参数组合”CrossValidator计算结果比较,完成所有的比较后,将最优的“参数组合”挑选出来,这“最优的一组参数”将用在整个训练数据集上重新训练(re-fit),得到最终的Model。
  • 也就是说,通过交叉验证,找到了最佳的”参数组合“,利用这组参数,在整个训练集上可以训练(fit)出一个泛化能力强,误差相对最小的的最佳模型。
  • 很显然,交叉验证计算代价很高,假设有三个参数:参数alpha有3中选择,参数beta有4种选择,参数gamma有4中选择,进行10折计算,那么将进行(3×4×4)×10=480次模型训练。

Spark documnets 原文: 
(1)CrossValidator begins by splitting the dataset into a set of folds which are used as separate training and test datasets. E.g., with k=3folds, CrossValidator will generate 3 (training, test) dataset pairs, each of which uses 2/3 of the data for training and 1/3 for testing. To evaluate a particular ParamMap, CrossValidator computes the average evaluation metric for the 3 Models produced by fitting the Estimator on the 3 different (training, test) dataset pairs. 
(2)After identifying the best ParamMap, CrossValidator finally re-fits the Estimator using the best ParamMap and the entire dataset. 
(3)Using CrossValidator to select from a grid of parameters.Note that cross-validation over a grid of parameters is expensive. E.g., in the example below, the parameter grid has 3 values for hashingTF.numFeatures and 2 values for lr.regParam, and CrossValidator uses 2 folds. This multiplies out to (3×2)×2=12different models being trained. In realistic settings, it can be common to try many more parameters and use more folds (k=3 and k=10 are common). In other words, using CrossValidator can be very expensive. However, it is also a well-established method for choosing parameters which is more statistically sound than heuristic hand-tuning.

计算流程

//Spark Version 2.0
package my.spark.ml.practice;

import java.io.IOException;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.function.Function;
import org.apache.spark.ml.Pipeline;
import org.apache.spark.ml.PipelineStage;
import org.apache.spark.ml.evaluation.RegressionEvaluator;
import org.apache.spark.ml.param.ParamMap;
import org.apache.spark.ml.recommendation.ALS;
import org.apache.spark.ml.tuning.CrossValidator;
import org.apache.spark.ml.tuning.CrossValidatorModel;
import org.apache.spark.ml.tuning.ParamGridBuilder;
import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.SparkSession;

/**ALS算法协同过滤推荐算法
 * 使用Spark 2.0 基于Pipeline,ParamMap,CrossValidation
 * 对超参数进行调优,并进行模型选择
 */

public class MyCrossValidation {
  public static void main(String[] args) throws IOException{
      SparkSession spark=SparkSession
              .builder()
              .appName("myCrossValidation")
              .master("local[4]")
              .getOrCreate();
    //屏蔽日志
      Logger.getLogger("org.apache.spark").setLevel(Level.WARN);
      Logger.getLogger("org.eclipse.jetty.server").setLevel(Level.OFF);
    //加载数据
      JavaRDD<Rating> ratingsRDD = spark
              .read().textFile("/home/hadoop/spark/spark-2.0.0-bin-hadoop2.6" +
                    "/data/mllib/als/sample_movielens_ratings.txt").javaRDD()
              .map(new Function<String, Rating>() {
                  public Rating call(String str) {
                      return Rating.parseRating(str);
                  }
              });
      //将整个数据集划分为训练集和测试集
      //注意training集将用于Cross Validation,而test集将用于最终模型的评估
      //在traning集中,在Croos Validation时将进一步划分为K份,每次留一份作为
      //Validation,注意区分:ratings.randomSplit()分出的Test集和K 折留
      //下验证的那一份完全不是一个概念,也起着完全不同的作用,一定不要相混淆
      Dataset<Row> ratings = spark.createDataFrame(ratingsRDD, Rating.class);
      Dataset<Row>[] splits = ratings.randomSplit(new double[]{0.8, 0.2});
      Dataset<Row> training = splits[0];
      Dataset<Row> test = splits[1];

      // Build the recommendation model using ALS on the training data
      ALS als=new ALS()
              .setMaxIter(8)
              .setRank(20).setRegParam(0.8)
              .setUserCol("userId")
              .setItemCol("movieId")
              .setRatingCol("rating")
              .setPredictionCol("predict_rating");
      /*
       * (1)秩Rank:模型中隐含因子的个数:低阶近似矩阵中隐含特在个数,因子一般多一点比较好,
       * 但是会增大内存的开销。因此常在训练效果和系统开销之间进行权衡,通常取值在10-200之间。
       * (2)最大迭代次数:运行时的迭代次数,ALS可以做到每次迭代都可以降低评级矩阵的重建误差,
       * 一般少数次迭代便能收敛到一个比较合理的好模型。
       * 大部分情况下没有必要进行太对多次迭代(10次左右一般就挺好了)
       * (3)正则化参数regParam:和其他机器学习算法一样,控制模型的过拟合情况。
       * 该值与数据大小,特征,系数程度有关。此参数正是交叉验证需要验证的参数之一。
       */
      // Configure an ML pipeline, which consists of one stage
      //一般会包含多个stages
      Pipeline pipeline=new Pipeline().
              setStages(new PipelineStage[] {als});
      // We use a ParamGridBuilder to construct a grid of parameters to search over.
      ParamMap[] paramGrid=new ParamGridBuilder()
      .addGrid(als.rank(),new int[]{5,10,20})
      .addGrid(als.regParam(),new double[]{0.05,0.10,0.15,0.20,0.40,0.80})
      .build();

      // CrossValidator 需要一个Estimator,一组Estimator ParamMaps, 和一个Evaluator.
      // (1)Pipeline作为Estimator;
      // (2)定义一个RegressionEvaluator作为Evaluator,并将评估标准设置为“rmse”均方根误差
      // (3)设置ParamMap
      // (4)设置numFolds    

      CrossValidator cv=new CrossValidator()
      .setEstimator(pipeline)
      .setEvaluator(new RegressionEvaluator()
              .setLabelCol("rating")
              .setPredictionCol("predict_rating")
              .setMetricName("rmse"))
      .setEstimatorParamMaps(paramGrid)
      .setNumFolds(5);

      // 运行交叉检验,自动选择最佳的参数组合
      CrossValidatorModel cvModel=cv.fit(training);
      //保存模型
      cvModel.save("/home/hadoop/spark/cvModel_als.modle");

      //System.out.println("numFolds: "+cvModel.getNumFolds());
      //Test数据集上结果评估
      Dataset<Row> predictions=cvModel.transform(test);
      RegressionEvaluator evaluator = new RegressionEvaluator()
      .setMetricName("rmse")//RMS Error
      .setLabelCol("rating")
      .setPredictionCol("predict_rating");
      Double rmse = evaluator.evaluate(predictions);
      System.out.println("RMSE @ test dataset " + rmse);
      //Output: RMSE @ test dataset 0.943644792277118
  }
}

备注:程序运行需要定义Rating Class 在下面链接里可以找到: http://spark.apache.org/docs/latest/ml-collaborative-filtering.html

原文地址:https://www.cnblogs.com/itboys/p/8310134.html

时间: 2024-08-25 04:52:19

Spark2.0机器学习系列之2:基于Pipeline、交叉验证、ParamMap的模型选择和超参数调优的相关文章

Spark2.0机器学习系列之8: 聚类分析(K-Means,Bisecting K-Means,LDA,高斯混合模型)

在写这篇文章之前,先说一些题外话. 许多机器学习算法(如后面将要提到的LDA)涉及的数学知识太多,前前后后一大堆,理解起来不是那么容易. 面对复杂的机器学习模型,尤其是涉及大量数学知识的模型,我们往往要花费大量的时间和精力去推导数学算法(公式),如果过分沉湎于此会忽略了很多背后也许更重要的东西,正所谓只见树木,不见森林,而这是缺乏远见,是迷茫的. 我们需要深入理解模型背后的逻辑和所蕴含的或简或繁的思想.某些思想甚至可能是很美的思想,很伟大的思想.这些理解,使得面对复杂的问题时候,面对陌生问题时,

Spark2.0机器学习系列之6:GBDT(梯度提升决策树)、GBDT与随机森林差异、参数调试及Scikit代码分析

概念梳理 GBDT的别称 GBDT(Gradient Boost Decision Tree),梯度提升决策树.     GBDT这个算法还有一些其他的名字,比如说MART(Multiple Additive Regression Tree),GBRT(Gradient Boost Regression Tree),Tree Net等,其实它们都是一个东西(参考自wikipedia – Gradient Boosting),发明者是Friedman. 研究GBDT一定要看看Friedman的pa

机器学习:模型性能评估与参数调优

模型性能评估的常用指标 真阳性(True Positive,TP):指被分类器正确分类的正例数据 真阴性(True Negative,TN):指被分类器正确分类的负例数据 假阳性(False Positive,FP):被错误地标记为正例数据的负例数据 假阴性(False Negative,FN):被错误地标记为负例数据的正例数据 精确率=TP/(TP+FP),TP+FP是模型预测的正样本总数,精确率衡量的是准确性: 召回率=TP/(TP+FN),TP+FN是真实的正样本总数,召回率衡量的是覆盖率

【机器学习】超参数调优

超参数调优方法 网格搜索 通过查找搜索范围内的所有的点来确定最优值.如果采用较大的搜索范围以及较小的步长,网络搜索有很大概率找到全局最优值.然而,这种搜索方案十分消耗计算资源和时间,特别是需要调优的超参数比较多的时候,因此,在实际应用中,网格搜索法一般会使用较广的搜索范围和步长,来寻找全局最优值可能的位置:然后会逐渐缩小搜索范围和步长,来寻找更精确的最优值.这种方案可以降低所需的时间和计算量,但由于目标函数一般是非凸的,所以很可能会错过全局最优值. 随机搜索 理论依据是如果样本集足够大,那么通过

机器学习 | 特征工程- 超参数调优方法整理

特征工程是机器学习当中很重要的部分,可以帮助我们设计.创建新特征,以便模型从中提取重要相关性.本文将记录并持续更新相关特征工程的工具包介绍,包括自动模型选择和超参数调优等各方面. · Featuretools Featuretools 是一个开源的Python 库,用于自动化特征工程.自动特征工程能够缩减时间成本,构建更优秀的预测模型,生成更有意义的特征,还能防止数据泄漏(data leakage). 目标任务:从数据表格集中获取所有的数据信息并整合到一张表中,再创建特征. 解决方案:采用深度特

机器学习系列(12)_XGBoost参数调优完全指南(附Python代码)

https://blog.csdn.net/han_xiaoyang/article/details/52665396 转: 原文地址:Complete Guide to Parameter Tuning in XGBoost by Aarshay Jain 原文翻译与校对:@MOLLY && 寒小阳 ([email protected]) 时间:2016年9月. 出处:http://blog.csdn.net/han_xiaoyang/article/details/52665396 声

机器学习系列(6)_从白富美相亲看特征预处理与选择(下)

作者:viewmode=contents">龙心尘 &&寒小阳 时间:2016年1月. 出处: http://blog.csdn.net/longxinchen_ml/article/details/50493845. http://blog.csdn.net/han_xiaoyang/article/details/50503115 声明:版权全部,转载请联系作者并注明出处 1. 剧情一:挑螃蟹的秘密 李雷与韩梅梅的关系发展得不错.趁国庆休假一起来天津玩. 今天,李雷十分

spark机器学习系列:(三)用Spark Python构建推荐系统

上一篇博文详细介绍了如何使用Spark Python进行数据处理和特征提取,本系列从本文开始,将陆续介绍用Spark Python对机器学习模型进行详细的探讨. 推荐引擎或许是最为大众所知的一种机器学习模型.人们或许并不知道它确切是什么,但在使用Amazon.Netflix.YouTube.Twitter.LinkedIn和Facebook这些流行站点的时候,可能已经接触过了.推荐是这些网站背后的核心组件之一,有时还是一个重要的收入来源. 推荐引擎背后的想法是预测人们可能喜好的物品并通过探寻物品

Spark2.x 机器学习视频教程

Spark2.x 机器学习视频教程讲师:轩宇老师链接:https://pan.baidu.com/s/1TcFl6KDjxJS597TxYFSCOA 密码:3t2z 本课程讲解Spark 在机器学习中的应用,并介绍如何从各种公开渠道获取用于机器学习系统的数据.内容涵盖推荐系统.回归.聚类.分类等经典机器学习算法及其实际应用,涵盖使用Spark ML Pipeline API创建和调试机器学习流程,内容更加系统.全面.与时俱进,适合所有欲借助Spark来实现常见机器学习应用的开发者. 本课程主要讲