如何从交叉验证器中获得经过训练的最佳模型

how to obtain the trained best model from a crossvalidator

我构建了一个包含 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)

但问题是,我想查看参数.toDebugTreeDecisionTreeClassificationModel的最佳训练决策树模型。但是模型是CrossValidatorModel。是的,你可以使用model.bestModel,但它仍然是Model类型,你不能对它应用.toDebugTree。而且我假设 bestModel 仍然是一个管道,包括 labelIndexerfeatureIndexerdtlabelConverter.

所以有谁知道我如何从crossvalidator拟合的模型中得到decisionTree模型,我可以通过toDebugString查看实际模型?或者有什么解决方法可以让我查看 decisionTree 模型吗?

好吧,在 中,答案总是相同的 - 请具体说明类型。

首先提取流水线模型,因为你要训练的是流水线:

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)

(免责声明:还有另一个方面,恕我直言,它应该有自己的答案。我知道这个问题有点过时了,但是,它质疑这个问题。如果有人因为不同意内容而投反对票,也请发表评论)

你是否应该提取 "best" 树,答案通常是否定的。

我们为什么要做简历?我们正在尝试评估我们的选择,以获得。选择是使用的分类器、使用的超参数、特征选择等预处理。对于最后一个,重要的是这发生在训练数据上。例如,不要对所有数据的特征进行归一化。所以CV的输出就是生成的pipeline。附注:特征选择应该在 "internal cv"

上进行评估

我们没有做的是,我们没有生成 "pool of classifiers" 我们选择最佳分类器的地方。但是,我经常看到这种情况。问题是您极有可能产生缠绕效应。即使在完美的 Iid 数据集中,也可能存在(几乎)重复的训练示例。 "best" CV 分类器很有可能只是指示您在哪个折叠中具有最佳缠绕。

所以,你该怎么办?一旦确定了参数,就应该使用整个训练数据来构建最终模型。希望,但没有人这样做,你已经预留了一个额外的评估集,你在这个过程中从未接触过它来获得对你的最终模型的评估。