如何使用 GridSearch 的输出?

数据挖掘 机器学习 交叉验证
2021-10-06 21:47:43

我目前正在使用 Python 和 Scikit learn 进行分类,并围绕 GridSearch 进行了一些阅读,我认为这是优化我的估计器参数以获得最佳结果的好方法。

我的方法是这样的:

  1. 将我的数据拆分为训练/测试。
  2. 使用 GridSearch 和 5Fold Cross 验证来训练和测试我的估计器(随机森林、梯度提升、SVC 等),以获得具有最佳超参数组合的最佳估计器。
  3. 然后,我使用我的测试集来预测分类并将它们与实际的类标签进行比较,计算我的每个估计器的指标,例如 Precision、Recall、FMeasure 和 Matthews Correlation Coefficient。

正是在这个阶段,我看到了奇怪的行为,我不确定如何进行。我是否从 GridSearch 获取 .best_estimator_ 并将其用作网格搜索的“最佳”输出,并使用此估计器执行预测?如果我这样做,我发现第 3 阶段的指标通常比我简单地训练所有训练数据并在测试集上进行测试要低得多。或者,我是否只是将输出 GridSearchCV 对象作为新的估计器如果我这样做,我的第 3 阶段指标会得到更好的分数,但使用 GridSearchCV 对象而不是预期的分类器(例如随机森林)似乎很奇怪......

编辑: 所以我的问题是返回的 GridSearchCV 对象和 .best_estimator_ 属性有什么区别?我应该使用其中哪一个来计算进一步的指标?我可以像常规分类器一样使用这个输出(例如使用预测),否则我应该如何使用它?

2个回答

决定离开并找到可以满足我的问题的答案,并将它们写在这里以供其他想知道的人使用。

.best_estimator_ 属性是指定模型类型的一个实例,它具有来自 param_grid 的给定参数的“最佳”组合。此实例是否有用取决于 refit 参数是否设置为 True(默认情况下)。例如:

clf = GridSearchCV(estimator=RandomForestClassifier(), 
                    param_grid=parameter_candidates,
                    cv=5,
                    refit=True,
                    error_score=0,
                    n_jobs=-1)

clf.fit(training_set, training_classifications)
optimised_random_forest = clf.best_estimator_
return optimised_random_forest

将返回一个 RandomForestClassifier。从 [文档][1] 中可以清楚地看到这一点。文档中不清楚的是为什么大多数示例没有专门使用 .best_estimator_ 而是这样做:

clf = GridSearchCV(estimator=RandomForestClassifier(), 
                    param_grid=parameter_candidates,
                    cv=5,
                    refit=True,
                    error_score=0,
                    n_jobs=-1)

clf.fit(training_set, training_classifications)
return clf

第二种方法返回一个 GridSearchCV 实例,其中包含 GridSearchCV 的所有花里胡哨,例如 .best_estimator_、.best_params 等,它本身可以像经过训练的分类器一样使用,因为:

Optimised Random Forest Accuracy:  0.916970802919708
[[139  47]
 [ 44 866]]
GridSearchCV Accuracy:  0.916970802919708
[[139  47]
 [ 44 866]]

它只是在进行预测时使用相同的最佳估计器实例。因此,在实践中,这两者之间没有区别,除非您特别想要估算器实例本身。作为旁注,我在指标上的差异是无关的,并且归结为错误的类权重函数。[1]:http ://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html#sklearn.model_selection.GridSearchCV.fit

GridSearchCV 允许您将估计器与网格搜索前导相结合来调整超参数。该方法从网格搜索中选择最佳参数,并将其与用户选择的估计器一起使用。GridSearchCV 继承了分类器的方法,所以是的,您可以直接通过 GridSearchCV 接口使用 .score、.predict 等方法。如果您希望提取网格搜索识别的最佳超参数,您可以使用 .best_params_ ,这将返回最佳超参数。然后,您可以将此超参数分别传递给您的估算器。

直接使用 .predict 将产生与通过 .best_param_ 获得最佳超参数然后在模型中使用它相同的结果。通过了解网格搜索的下划线工作原理,我们可以了解为什么会出现这种情况。


网格搜索

该技术用于找到与算法一起使用的最佳参数。这不是权重或模型,它们是使用数据学习的。这显然很令人困惑,所以我将通过调用一个超参数来区分这些参数。

超参数就像 k-Nearest Neighbors (k-NN) 中的 k。k-NN 要求用户在计算距离时选择要考虑的邻居。然后该算法调整一个参数,一个阈值,以查看一个新示例是否属于学习分布,这是通过数据完成的。

我们如何选择k?

有些人只是根据过去对数据类型的研究提出建议。其他人使用网格搜索。此方法将能够最好地确定哪个 k 最适合您的数据。

它是如何工作的?

首先你需要建立一个网格。这本质上是您的超参数可以采用的一组可能值。对于我们的案例,我们可以使用[1,2,3,...,10]. 然后,您将为网格中的每个值训练您的 k-NN 模型。首先你会做 1-NN,然后是 2-NN,依此类推。对于每次迭代,您将获得一个性能分数,该分数将告诉您算法使用该超参数值的执行情况。完成整个网格后,您将选择提供最佳性能的值。

这违背了不使用测试数据的原则!!

你是绝对正确的。这就是网格搜索经常与交叉验证混合的原因。这样我们就可以将测试数据完全分开,直到我们对结果真正满意并准备好进行测试。n-fold 交叉验证接受一个训练集并将其分成n部分。然后它继续训练n-1折叠和测试被遗漏的折叠。对于网格中的每个值,将重新训练算法n次,对于每个被遗漏的折叠。然后对每个折叠的性能进行平均,这就是该超参数值所达到的性能。

所选的超参数值是在 n 倍中实现最高平均性能的超参数值。一旦您对您的算法感到满意,您就可以在测试集上对其进行测试。如果你直接进入测试集,那么你就有过拟合的风险。