Ich möchte eine zufällige Gesamtstruktur auswerten, die an einigen Daten trainiert wird. Gibt es ein Dienstprogramm in Apache Spark, um dasselbe zu tun, oder muss ich die Kreuzvalidierung manuell durchführen?Wie validiere ich das RandomForest Modell?
17
A
Antwort
31
ML bietet CrossValidator
Klasse, die verwendet werden kann, um Kreuzvalidierung und Parametersuche durchzuführen. Vorausgesetzt, dass Ihre Daten bereits vorverarbeitet können Sie Kreuzvalidierung wie folgt hinzufügen:
import org.apache.spark.ml.Pipeline
import org.apache.spark.ml.tuning.{ParamGridBuilder, CrossValidator}
import org.apache.spark.ml.classification.RandomForestClassifier
import org.apache.spark.ml.evaluation.MulticlassClassificationEvaluator
// [label: double, features: vector]
trainingData org.apache.spark.sql.DataFrame = ???
val nFolds: Int = ???
val NumTrees: Int = ???
val metric: String = ???
val rf = new RandomForestClassifier()
.setLabelCol("label")
.setFeaturesCol("features")
.setNumTrees(NumTrees)
val pipeline = new Pipeline().setStages(Array(rf))
val paramGrid = new ParamGridBuilder().build() // No parameter search
val evaluator = new MulticlassClassificationEvaluator()
.setLabelCol("label")
.setPredictionCol("prediction")
// "f1" (default), "weightedPrecision", "weightedRecall", "accuracy"
.setMetricName(metric)
val cv = new CrossValidator()
// ml.Pipeline with ml.classification.RandomForestClassifier
.setEstimator(pipeline)
// ml.evaluation.MulticlassClassificationEvaluator
.setEvaluator(evaluator)
.setEstimatorParamMaps(paramGrid)
.setNumFolds(nFolds)
val model = cv.fit(trainingData) // trainingData: DataFrame
Mit PySpark:
from pyspark.ml import Pipeline
from pyspark.ml.classification import RandomForestClassifier
from pyspark.ml.tuning import CrossValidator, ParamGridBuilder
from pyspark.ml.evaluation import MulticlassClassificationEvaluator
trainingData = ... # DataFrame[label: double, features: vector]
numFolds = ... # Integer
rf = RandomForestClassifier(labelCol="label", featuresCol="features")
evaluator = MulticlassClassificationEvaluator() # + other params as in Scala
pipeline = Pipeline(stages=[rf])
crossval = CrossValidator(
estimator=pipeline,
estimatorParamMaps=paramGrid,
evaluator=evaluator,
numFolds=numFolds)
model = crossval.fit(trainingData)
1
Um auf zero323 die große Antwort zu bauen mit Random Forest Classifier, hier ist ein ähnliches Beispiel für Random Wald Regressor:
import org.apache.spark.ml.Pipeline
import org.apache.spark.ml.tuning.{ParamGridBuilder, CrossValidator}
import org.apache.spark.ml.regression.RandomForestRegressor // CHANGED
import org.apache.spark.ml.evaluation.RegressionEvaluator // CHANGED
import org.apache.spark.ml.feature.{VectorAssembler, VectorIndexer}
val numFolds = ??? // Integer
val data = ??? // DataFrame
// Training (80%) and test data (20%)
val Array(train, test) = data.randomSplit(Array(0.8,0.2))
val featuresCols = data.columns
val va = new VectorAssembler()
va.setInputCols(featuresCols)
va.setOutputCol("rawFeatures")
val vi = new VectorIndexer()
vi.setInputCol("rawFeatures")
vi.setOutputCol("features")
vi.setMaxCategories(5)
val regressor = new RandomForestRegressor()
regressor.setLabelCol("events")
val metric = "rmse"
val evaluator = new RegressionEvaluator()
.setLabelCol("events")
.setPredictionCol("prediction")
// "rmse" (default): root mean squared error
// "mse": mean squared error
// "r2": R2 metric
// "mae": mean absolute error
.setMetricName(metric)
val paramGrid = new ParamGridBuilder().build()
val cv = new CrossValidator()
.setEstimator(regressor)
.setEvaluator(evaluator)
.setEstimatorParamMaps(paramGrid)
.setNumFolds(numFolds)
val model = cv.fit(train) // train: DataFrame
val predictions = model.transform(test)
predictions.show
val rmse = evaluator.evaluate(predictions)
println(rmse)
Evaluator metrische Quelle: https://spark.apache.org/docs/latest/api/scala/#org.apache.spark.ml.evaluation.RegressionEvaluator
Sind Sie sicher, dass dies für Leave-One-Out funktioniert? Der Aufruf kFold() unter der Haube scheint nicht deterministisch zwei Falten Länge N-1 und 1 zurückgeben. Wenn ich den Code oben mit einem RegressionEvaluator und Lasso-Modell ausführen, bekomme ich: Ausnahme im Thread "Main" java.lang .IllegalArgumentException: Anforderung fehlgeschlagen: Dieser Zusammenfassung wurde nichts hinzugefügt. – paradiso
Nein, ich bin mir ziemlich sicher, dass es nicht so ist. 'MLUtils.kFold' verwendet' BernoulliCellSampler', um Split zu bestimmen. Andererseits sind die Kosten für die Durchführung einer Leave-One-Out-Kreuzvalidierung in Spark wahrscheinlich zu hoch, um sie in der Praxis machbar zu machen. – zero323
Hallo @ Zero323, wenn Sie eine Metrik in Ihrem Evaluator-Objekt wie .setMetricName ("Genauigkeit") festlegen. Meine Frage ist, wie kann ich diese Metrik während des Trainingsprozesses berechnen lassen? (Bitte beziehen Sie sich auf diese Frage: http://stackoverflow.com/questions/37778532/how-to-get-precision-recall-using-crossvalidator-for-training-naivebayes-model-u) – dbustosp