Trả lời

31

ML cung cấp CrossValidator lớp có thể được sử dụng để thực hiện xác thực chéo và tìm kiếm thông số. Giả sử dữ liệu của bạn đã được xử lý trước bạn có thể thêm cross-validation như sau:

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 

Sử dụng 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) 
+0

Bạn có chắc chắn rằng điều này có hiệu quả đối với việc bỏ đi không? Cuộc gọi kFold() dưới mui xe không xuất hiện để xác định trở lại hai lần chiều dài N-1 và 1. Khi tôi chạy đoạn mã trên bằng một bộ hồi quy RegressionEvaluator và Lasso, tôi nhận được: Ngoại lệ trong chủ đề "chính" java.lang .IllegalArgumentException: yêu cầu không thành công: Không có gì được thêm vào bản tóm tắt này. – paradiso

+5

Không, tôi khá chắc chắn là không. 'MLUtils.kFold' đang sử dụng' BernoulliCellSampler' để xác định chia nhỏ. Mặt khác, chi phí thực hiện việc bỏ qua xác thực chéo một lần trong Spark có lẽ là cao để làm cho nó khả thi trong thực tế. – zero323

+0

Xin chào @ zero323, khi bạn đặt số liệu trong đối tượng Đánh giá của bạn như .setMetricName ("precision"). Câu hỏi của tôi là, làm cách nào để tôi có được số liệu được tính toán trong quá trình đào tạo? (Vui lòng tham khảo câu hỏi này: http://stackoverflow.com/questions/37778532/how-to-get-precision-recall-using-crossvalidator-for-training-naivebayes-model-u) – dbustosp

1

Để xây dựng dựa trên câu trả lời tuyệt vời zero323 bằng cách sử dụng rừng ngẫu nhiên Phân loại, đây là một ví dụ tương tự cho ngẫu nhiên rừng 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 nguồn số liệu: https://spark.apache.org/docs/latest/api/scala/#org.apache.spark.ml.evaluation.RegressionEvaluator

Các vấn đề liên quan