You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spark ML CrossValidator是否可配置多Evaluator同时获取R2与RMSE

问题解答

方案可行性结论

你提出的连续调用两次setEvaluator配置多评估器的方案不可行。
Spark MLlib 中CrossValidator的设计仅支持传入单个Evaluator作为超参数优化的排序依据,setEvaluator为覆盖式赋值,后一次传入的R2评估器会直接覆盖之前设置的RMSE评估器,最终交叉验证只会按R2筛选最优模型,也仅能输出R2对应的交叉验证平均指标。

可行实现方案

仅需要运行一次交叉验证即可同时获取两类指标,无需创建两个CrossValidator实例,参考实现如下:

基础配置

选择一个作为最优模型筛选依据的主指标(示例用RMSE)配置CrossValidator,同时开启子模型收集能力:

val lr_evaluator_rmse = new RegressionEvaluator()
                       .setLabelCol("ArrDelay")
                       .setPredictionCol("predictionLR")
                       .setMetricName("rmse")

val lr_evaluator_r2 = new RegressionEvaluator()
                     .setLabelCol("ArrDelay")
                     .setPredictionCol("predictionLR")
                     .setMetricName("r2")

val lr_cv = new CrossValidator()
              .setEstimator(lr_pipeline)
              .setEvaluator(lr_evaluator_rmse)
              .setEstimatorParamMaps(lr_paramGrid)
              .setNumFolds(3)
              .setParallelism(3)
              .setCollectSubModels(true) // 开启子模型收集,Spark 3.0及以上版本支持

计算多指标

拟合完成后可按需求计算不同场景的指标:

场景1:只需最优模型在测试集的两类指标

// 拟合交叉验证模型
val lr_cv_model = lr_cv.fit(train_dataset)
val best_lr_model = lr_cv_model.bestModel
val test_predictions = best_lr_model.transform(test_dataset)

// 分别计算两个评估指标
val test_rmse = lr_evaluator_rmse.evaluate(test_predictions)
val test_r2 = lr_evaluator_r2.evaluate(test_predictions)

场景2:需要交叉验证K折的平均两类指标

// RMSE的K折平均可直接从CrossValidator结果获取
val avg_cv_rmse = lr_cv_model.avgMetrics.head

// 遍历各折的子模型手动计算R2的平均
val avg_cv_r2 = lr_cv_model.subModels.map { fold_model =>
  lr_evaluator_r2.evaluate(fold_model.transform(fold_validation_dataset))
}.sum / lr_cv_model.subModels.length

内容的提问来源于stack exchange,提问作者rayqz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 16:45:02