如何在 GridSearchCV 中正确选择最佳模型 - sklearn 和 caret 都做错了

     2023-03-12     280

关键词:

【中文标题】如何在 GridSearchCV 中正确选择最佳模型 - sklearn 和 caret 都做错了【英文标题】:How to properly select the best model in GridSearchCV - both sklearn and caret do it wrong 【发布时间】:2020-02-27 02:08:15 【问题描述】:

考虑 3 个数据集 train/val/test。 Sklearns GridSearchCV 默认选择具有最高交叉验证分数的最佳模型。在需要准确预测的现实世界环境中,这是选择最佳模型的可怕方法。原因是因为它应该是这样使用的:

-为模型学习数据集的训练集

-Val set 用于验证模型在训练集中学到了什么,并更新参数/超参数以最大化验证分数。

-测试集 - 用看不见的数据测试您的数据。

-最后在现场环境中使用该模型并记录结果以查看结果是否足以做出决策。令人惊讶的是,许多数据科学家冲动地在生产中使用他们训练有素的模型,仅基于选择具有最高验证分数的模型。我发现网格搜索可以选择过度拟合的模型,并且在预测看不见的数据方面比默认参数做得更差。

我的方法:

-手动训练模型并查看每个模型的结果(在一种循环中,但效率不高)。这是非常手动且耗时的,但我得到的结果比网格搜索要好得多。我希望这完全自动化。

-为我要选择的每个超参数绘制验证曲线,然后选择显示train和val set之间差异最小的超参数同时最大化两者(即train = 98%,val = 78%真的很糟糕,但是train=72%, val=70% 是可以接受的)。

就像我说的,我想要一种更好的(自动化)方法来选择最佳模型。

我在寻找什么样的答案:

我想最大化训练集和验证集的分数,同时最小化训练集和验证集之间的分数差异。考虑以下来自网格搜索算法的示例: 有两种型号:

Model A: train score = 99%, val score = 89%

Model B: train score = 80%, val score = 79%

B 型是一个更可靠的模型,任何时候我都会选择 B 型而不是 A 型。它较少过拟合,并且预测是一致的。我们知道会发生什么。然而,网格搜索将选择模型 A,因为 val 分数更高。我发现这是一个常见问题,并且在互联网上的任何地方都没有找到任何解决方案。人们往往如此专注于他们在学校学到的东西,而实际上并没有考虑选择过拟合模型的后果。我看到关于如何使用 sklearn 和 carets gridsearch 包并让他们为您选择模型的多余帖子,但没有看到如何实际选择最佳模型。

到目前为止,我的方法非常手动。我想要一种自动化的方式来做到这一点。

我现在做的是这样的:

gs = GridSearchCV(model, params, cv=3).fit(X_train, y_train) # X_train and y_train consists of validation sets too if you do it this way, since GridSearchCV already creates a cv set.
final_model = gs.best_estimator_
train_predictions = final_model.predict(X_train)
val_predictions = final_model.predict(X_val)
test_predictions = final_model.predict(X_test)

print('Train Score:', accuracy_score(train_predictions, y_train)) # .99
print('Val Score:', accuracy_score(val_predictions, y_val)) # .89
print('Test Score:', accuracy_score(test_predictions, y_test)) # .8

如果我看到类似上面的内容,我会排除该模型并尝试不同的超参数,直到获得一致的结果。通过手动拟合不同的模型并查看所有 3 个结果、验证曲线等……我可以决定什么是最好的模型。我不想手动执行此操作。我希望这个过程是自动化的。网格搜索算法每次都会返回过拟合模型。我期待听到一些答案。

另一个大问题是验证集和测试集之间的差异。由于许多问题都面临时间依赖性问题,我想知道一种可靠的方法来随着时间的推移测试模型的性能。按时间拆分数据集至关重要,否则我们将呈现数据泄漏。我熟悉的一种方法是判别分析(拟合模型以查看模型是否可以预测示例来自哪个数据集:train val test)。另一种方法是 KS / KL 测试并查看目标变量的分布,或者循环遍历每个特征并比较分布。

【问题讨论】:

我认为使用不同的验证集和测试集的目的是根据测试集的性能选择超参数。 得到像Model A: train score = 99%, val score = 98%, test set = 80% 这样的结果让我尖叫,验证集没有正确生成。是否存在时间或空间依赖性?如果是这样,那么我的猜测是验证正在及时完成,而测试集已经过时了。一旦你开始使用你的测试集来选择一个模型,你就会对所有过拟合的东西敞开心扉。 您有一个有效点 ClancyStats - 但是我在上面的模型 A 中列出的内容非常常见。我不是根据测试集“选择”模型。我根据 3 组选择模型,然后在实时提要上测试模型,记录数据,只有在模型证明有效的一段时间后,我才会使用该模型。根据验证集选择模型会阻止您最大化模型的潜力。我的意思是该算法使用 val 集来更新参数,但您实际上并没有看到它对看不见的数据的作用。 我什至会给出我取出测试集的场景 - 这是同样的问题。网格搜索算法选择具有最高验证分数的模型。它不看 train 分数和 val 分数之间的差异。差值应该接近 0。99% 的 train 分数和 88% 的 val 分数不是一个好的模型,但网格搜索将超过 88% 的 train 分数和 87% 的 val 分数。我会选择第二种模式。 如果验证正确完成,无论训练分数如何,验证分数越高的模型可能是更好的模型。不过,您的第一条评论让我相信您可能存在时间依赖性(您的测试集是来自实时提要的新数据)。您最好手动设置使用大量时间的交叉验证折叠,而不是在整个过程中随机选择。 【参考方案1】:

我同意 cmets 的观点,即使用测试集来选择超参数可以消除对验证集 (/folds) 的需求,并使测试集分数不再代表未来的性能。您可以通过“在实时源上测试模型”来解决这个问题。

我什至会给出我取出测试集的场景 - 这是同样的问题。网格搜索算法选择具有最高验证分数的模型。它不看 train 分数和 val 分数之间的差异。差异应该接近 0。99% 的 train 分数和 88% 的 val 分数不是一个好的模型,但网格搜索将超过 88% 的 train 分数和 87% 的 val 分数。我会选择第二种模式。

现在这更容易理解了:除了原始性能之外,还有一些原因希望训练/测试分数差距很小。参见例如https://datascience.stackexchange.com/q/66350/55122。从 v0.20 开始,sklearn 实际上确实适应了这一点:通过使用 return_train_score=Truerefit 作为消耗 cv_results_ 并返回最佳索引的可调用对象:

refit : bool, str, or callable, default=True

...

如果在选择最佳估计器时除了最大分数之外还有其他考虑因素,可以将 refit 设置为一个函数,该函数在给定 cv_results_ 的情况下返回所选的 best_index_。在这种情况下,将根据返回的 best_index_ 设置 best_estimator_ 和 best_params_,而 best_score_ 属性将不可用。

...

https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html

当然,这要求您可以将查看分数及其差异的手动过程放入一个函数中,并且可能不承认任何类似验证曲线的东西,但至少它是这样的。

【讨论】:

如何正确合并集成中模型的输出?

...线性回归、GBM等模型。然后我为这些模型中的每一个运行GridSearchCV以了解最佳参数。在此之后,我想在考虑每个模型的单独预测的同时做出最终 查看详情

如何正确使用 GridSearchCV 和 cross_val_score?

】如何正确使用GridSearchCV和cross_val_score?【英文标题】:HowdoIproperlyuseGridSearchCVinconjunctionwithcross_val_score?【发布时间】:2018-12-0419:58:31【问题描述】:目前我有以下代码:我首先将数据集拆分为训练集和测试集。然后我运行GridSea... 查看详情

如何确定 GridSearchCV 中每个评分指标的最佳参数和最佳分数

】如何确定GridSearchCV中每个评分指标的最佳参数和最佳分数【英文标题】:HowtodeterminebestparametersandbestscoreforeachscoringmetricinGridSearchCV【发布时间】:2020-11-0921:39:47【问题描述】:我正在尝试评估多个评分指标以确定模型性能的最... 查看详情

ValueError 在 Scikit 中找到最佳超参数时使用 GridSearchCV 学习 LogisticRegression

】ValueError在Scikit中找到最佳超参数时使用GridSearchCV学习LogisticRegression【英文标题】:ValueErrorwhilefindingbesthyperparameterinScikitlearnLogisticRegressionusingGridSearchCV【发布时间】:2019-09-3006:12:29【问题描述】:在使用GridSearchCV进行LogisticRegre... 查看详情

如何使用 GridSearchCV 找到 GBR 的最佳参数?

】如何使用GridSearchCV找到GBR的最佳参数?【英文标题】:HowtofindoptimumparametersforGBRusingGridSearchCV?【发布时间】:2020-01-2819:54:41【问题描述】:我在excel文件中有34sampleswith4inputsandoneoutput。我正在使用gradientboostregressor(GBR)进行预测,... 查看详情

如何在gridsearchcv中使用最佳参数作为分类器的参数?(代码片段)

...ier2=SVC(**svc_clf)看来这里的参数不是网格..答案您可以使用GridSearchCV来执行此操作。这里有一个例子:#ApplyingGridSearchtofindbestparametersfromsklearn.model_selectionimportGridSearchCVparameters=['criterion':['gini'],'splitter':['best','random'],'min_samples_split':[0... 查看详情

如何在将 GridSearchCV 与 TimeSeriesSplit 一起使用时正确使用 Scaler

】如何在将GridSearchCV与TimeSeriesSplit一起使用时正确使用Scaler【英文标题】:HowdoIacorrectlyuseaScalerwhileusingGridSearchCVwithTimeSeriesSplit【发布时间】:2019-11-0413:01:50【问题描述】:我目前正在像这样使用GridSearchCV和TimeSeriesSplit,以便将... 查看详情

如果 GridSearchCV 给出了一些排名为 1 的估计器,它将选择哪一个作为最佳估计器?

】如果GridSearchCV给出了一些排名为1的估计器,它将选择哪一个作为最佳估计器?【英文标题】:IfGridSearchCVgivesafewestimatorswithrank1,whichonewillitpickasthebestestimator?【发布时间】:2020-09-1918:21:29【问题描述】:使用Scikit-learn的GridSearchCV... 查看详情

拟合 sklearn GridSearchCV 模型

】拟合sklearnGridSearchCV模型【英文标题】:FittingsklearnGridSearchCVmodel【发布时间】:2019-04-2605:20:27【问题描述】:我正在尝试在randomforestregressor的帮助下解决BostonDataset上的回归问题。我使用GridSearchCV来选择最佳超参数。问题1我是... 查看详情

具有单独训练和验证集的 GridSearchCV 错误地考虑了最终选择最佳模型的训练结果

】具有单独训练和验证集的GridSearchCV错误地考虑了最终选择最佳模型的训练结果【英文标题】:GridSeachCVwithseparatetraining&validationsetserroneouslytakesalsointoaccountthetrainingresultsforfinallychoosingthebestmodel【发布时间】:2019-03-0520:46:42【问... 查看详情

如何在 python 中的 sklearn 中获取 GridSearchCV 中的选定功能

】如何在python中的sklearn中获取GridSearchCV中的选定功能【英文标题】:HowtogettheselectedfeaturesinGridSearchCVinsklearninpython【发布时间】:2019-09-0304:03:16【问题描述】:我使用recurivefeatureeliminationwithcrossvalidation(rfecv)作为GridSearchCV的特征选... 查看详情

在 gridsearchcv sklearn 中进行训练和验证集

】在gridsearchcvsklearn中进行训练和验证集【英文标题】:Heldouttrainingandvalidationsetingridsearchcvsklearn【发布时间】:2016-10-1416:21:09【问题描述】:我看到在gridsearchcv中最佳参数是根据cross-validation确定的,但我真正想做的是根据oneheldou... 查看详情

如何将最佳参数(使用 GridSearchCV)从管道传递到另一个管道

】如何将最佳参数(使用GridSearchCV)从管道传递到另一个管道【英文标题】:Howtopassonbestparameters(usingGridSearchCV)fromapipelinetoanotherpipeline【发布时间】:2018-05-0217:35:23【问题描述】:我有一个自定义管道,我正在使用Sklearn的GridSearc... 查看详情

如何正确选择指令中的元素?

】如何正确选择指令中的元素?【英文标题】:Howtoproperlyselectanelementinsideadirective?【发布时间】:2016-08-0614:27:26【问题描述】:如果我为我的angular指令定义一个link函数,那么在指令中选择特定元素的最佳方法是什么?例如,如... 查看详情

如何从 gridSearchCV 的输出中获取特征名称

】如何从gridSearchCV的输出中获取特征名称【英文标题】:HowtogetfeaturenamesfromoutputofgridSearchCV【发布时间】:2016-08-1805:06:10【问题描述】:我使用sklearn使用朴素贝叶斯实现了PCA,并使用GridSearchCV优化了PCA的组件数量。我试图找出最... 查看详情

我应该使用 LassoCV 还是 GridSearchCV 来找到 Lasso 的最佳 alpha?

】我应该使用LassoCV还是GridSearchCV来找到Lasso的最佳alpha?【英文标题】:ShouldIuseLassoCVorGridSearchCVtofindanoptimalalphaforLasso?【发布时间】:2021-07-0219:00:02【问题描述】:据我了解,在使用Lasso回归的时候,可以在sklearn中使用GridSearchCV... 查看详情

在 Backbone.js 集合中“选择”一个模型的最佳方法?

】在Backbone.js集合中“选择”一个模型的最佳方法?【英文标题】:Bestwaytomakeonemodel\'selected\'inaBackbone.jscollection?【发布时间】:2011-09-2502:05:57【问题描述】:我的Backbone.js应用程序中有一组模型。这是一个项目列表,您可以将鼠... 查看详情

GridSearchCV 最佳超参数不会产生最佳精度

】GridSearchCV最佳超参数不会产生最佳精度【英文标题】:GridSearchCVbesthyperparametersdon\'tproducebestaccuracy【发布时间】:2020-10-1023:27:20【问题描述】:使用UCI人类活动识别数据集,我正在尝试生成一个决策树分类器模型。在默认参数... 查看详情