如何从交叉验证器获得训练有素的最佳模型

时间:2016-04-01 04:09:13

标签: scala apache-spark machine-learning decision-tree cross-validation

我构建了一个包含DecisionTreeClassifier(dt)的管道,如下所示

val pipeline = new Pipeline().setStages(Array(labelIndexer, featureIndexer, dt, labelConverter))

然后我使用此管道作为CrossValidator中的估算器,以获得具有最佳超参数集的模型

val c_v = new CrossValidator().setEstimator(pipeline).setEvaluator(new MulticlassClassificationEvaluator().setLabelCol("indexedLabel").setPredictionCol("prediction")).setEstimatorParamMaps(paramGrid).setNumFolds(5)

最后,我可以使用此交叉验证器训练模型进行训练测试

val model = c_v.fit(train)

但问题是,我希望使用.toDebugTree的参数DecisionTreeClassificationModel查看经过最佳训练的决策树模型。但模型是CrossValidatorModel。是的,您可以使用model.bestModel,但它仍然是Model类型,您无法对其应用.toDebugTree。而且我还假设bestModel仍然是一个pipline,包括labelIndexerfeatureIndexerdtlabelConverter

所以有人知道如何从crossvalidator拟合的模型中获取decisionTree模型,我可以通过toDebugString查看实际模型吗?或者我有没有可以查看decisionTree模型的解决方法?

2 个答案:

答案 0 :(得分:8)

嗯,在cases like this one中,答案总是一样的 - 具体说明类型。

首先提取管道模型,因为您要训练的是管道:

import org.apache.spark.ml.PipelineModel

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

然后,您需要从基础阶段提取模型。在您的情况下,它是一个决策树分类模型:

import org.apache.spark.ml.classification.DecisionTreeClassificationModel

val treeModel: Option[DecisionTreeClassificationModel] = bestModel
  flatMap {
    _.stages.collect {
      case t: DecisionTreeClassificationModel => t
    }.headOption
  }

要打印树,例如:

treeModel.foreach(_.toDebugString)

答案 1 :(得分:3)

(免责声明:还有另外一个方面,这个问题应该得到答案。我知道这个问题是一个小问题,然而,它对问题提出疑问。如果有人因为不同意这些内容而投票,请同时留下评语)

您是否应该提取“最佳”树,答案通常为否。

我们为什么要做简历?我们正在努力评估我们的选择。选择是使用的分类器,使用的超参数,像特征选择的预处理。对于最后一个,重要的是这发生在训练数据上。例如,不规范所有数据的功能。因此CV的输出是生成的管道。另请注意:功能选择应在“内部简历”上进行评估

我们没有做什么,我们没有生成“分类池”,我们选择最佳分类器。但是,我经常出乎意料地看到这一点。问题是你有很高的缠绕效果。即使在完美的 I id数据集中,也有可能(接近)重复的训练示例。很有可能“最佳”的CV分类器只是表示你有最好的缠绕效果。

因此,你应该怎么做?一旦修复了参数,就应该使用整个训练数据来构建最终模型。希望,但没有人这样做,你已经预留了一个额外的评估集,你从未在过程中接触到评估你的最终模型。