2016-11-11 13 views
0

Is it possible to access estimator attributes in spark.ml pipelines?と似ていますが、見積もりにアクセスしたいと思います。パイプラインの最後の要素。パイプラインのスパークアクセス見積もり

spark 2.0.1では、そこに記載されているアプローチはもう機能していないようです。今はどうしていますか?

編集

多分私はもう少し詳細なそれを説明する必要があります。ここに は私の推定+ベクトルアセンブラです:

val numRound = 20 
val numWorkers = 4 
val xgbBaseParams = Map(
    "max_depth" -> 10, 
    "eta" -> 0.1, 
    "seed" -> 50, 
    "silent" -> 1, 
    "objective" -> "binary:logistic" 
) 

val xgbEstimator = new XGBoostEstimator(xgbBaseParams) 
    .setFeaturesCol("features") 
    .setLabelCol("label") 

val vectorAssembler = new VectorAssembler() 
    .setInputCols(train.columns 
     .filter(!_.contains("label"))) 
    .setOutputCol("features") 

    val simplePipeParams = new ParamGridBuilder() 
    .addGrid(xgbEstimator.round, Array(numRound)) 
    .addGrid(xgbEstimator.nWorkers, Array(numWorkers)) 
    .build() 

    val simplPipe = new Pipeline() 
    .setStages(Array(vectorAssembler, xgbEstimator)) 

    val numberOfFolds = 2 
    val cv = new CrossValidator() 
    .setEstimator(simplPipe) 
    .setEvaluator(new BinaryClassificationEvaluator() 
     .setLabelCol("label") 
     .setRawPredictionCol("prediction")) 
    .setEstimatorParamMaps(simplePipeParams) 
    .setNumFolds(numberOfFolds) 
    .setSeed(gSeed) 

    val cvModel = cv.fit(train) 
    val trainPerformance = cvModel.transform(train) 
    val testPerformance = cvModel.transform(test) 

は、今私は、例えば、カスタムスコアリングを実行したいです!= 0.5カットオフポイント。これは、モデルを保持すると可能です:

val realModel = cvModel.bestModel.asInstanceOf[XGBoostClassificationModel] 

このステップはここではコンパイルされません。私はモデルを得ることができ、あなたの提案に ありがとう:

val pipelineModel: Option[PipelineModel] = cvModel.bestModel match { 
    case p: PipelineModel => Some(p) 
    case _ => None 
    } 

    val realModel: Option[XGBoostClassificationModel] = pipelineModel 
    .flatMap { 
     _.stages.collect { case t: XGBoostClassificationModel => t } 
     .headOption 
    } 
    // TODO write it nicer 
    val measureResults = realModel.map { 
    rm => 
     { 
     for (
      thresholds <- Array(Array(0.2, 0.8), Array(0.3, 0.7), Array(0.4, 0.6), 
      Array(0.6, 0.4), Array(0.7, 0.3), Array(0.8, 0.2)) 
     ) { 
      rm.setThresholds(thresholds) 

      val predResult = rm.transform(test) 
      .select("label", "probabilities", "prediction") 
      .as[LabelledEvaluation] 
      println("cutoff was ", thresholds) 
      calculateEvaluation(R, predResult) 
     } 
     } 
    } 

しかし、問題は

val predResult = rm.transform(test) 

vectorAssemblerの機能の列が含まれていませんtrainとして失敗するということです。 この列は、フルパイプラインが実行されている場合にのみ作成されます。

だから私は、第2のパイプラインを作成することにしました:

val scoringPipe = new Pipeline() 
      .setStages(Array(vectorAssembler, rm)) 
val predResult = scoringPipe.fit(train).transform(test) 

をそれは少し不器用であるように思われます。あなたはより良い/より良いアイデアを持っていますか?

+0

私は何を探していることは、配列の形ですべてのステージを返す 'pipeline.getStages()'であると考えています。必要なステージにアクセスできます。詳細については、[Documentation](http://spark.apache.org/docs/latest/api/scala/index.html#org.apache.spark.ml.Pipeline)を参照してください。 – ShirishT

+0

[crossvalidatorから訓練されたベストモデルを取得する方法](http://stackoverflow.com/questions/36347875/how-to-obtain-the-trained-best-model-from-a-crossvalidator) –

答えて

2

Spark 2.0.0では何も変更されておらず、同じアプローチが有効です。 Example Pipeline

import org.apache.spark.ml.{Pipeline, PipelineModel} 
import org.apache.spark.ml.classification.LogisticRegression 
import org.apache.spark.ml.feature.{HashingTF, Tokenizer} 
import org.apache.spark.ml.linalg.Vector 
import org.apache.spark.sql.Row 

// Prepare training documents from a list of (id, text, label) tuples. 
val training = spark.createDataFrame(Seq(
    (0L, "a b c d e spark", 1.0), 
    (1L, "b d", 0.0), 
    (2L, "spark f g h", 1.0), 
    (3L, "hadoop mapreduce", 0.0) 
)).toDF("id", "text", "label") 

// Configure an ML pipeline, which consists of three stages: tokenizer, hashingTF, and lr. 
val tokenizer = new Tokenizer() 
    .setInputCol("text") 
    .setOutputCol("words") 
val hashingTF = new HashingTF() 
    .setNumFeatures(1000) 
    .setInputCol(tokenizer.getOutputCol) 
    .setOutputCol("features") 
val lr = new LogisticRegression() 
    .setMaxIter(10) 
    .setRegParam(0.01) 
val pipeline = new Pipeline() 
    .setStages(Array(tokenizer, hashingTF, lr)) 

// Fit the pipeline to training documents. 
val model = pipeline.fit(training) 

とモデル:

val logRegModel = model.stages.last 
    .asInstanceOf[org.apache.spark.ml.classification.LogisticRegressionModel] 
+0

Msの問題は、クロスバリデーションでパイプラインを使用したいということです。推定子は2回ネストされます。 'cvModel.bestModel.getStages'は動作しません。だから私はどのようにCrossvalidatorのパイプラインを取得するのだろうか? –

+0

それはhttp://stackoverflow.com/questions/36347875/how-to-obtain-the-trained-best-model-from-a-crossvalidatorの複製です。 –

+0

私の編集をご覧ください。 –

関連する問題