GridSearchCV 意外行为(总是返回第一个参数为最佳)

     2023-03-12     303

关键词:

【中文标题】GridSearchCV 意外行为(总是返回第一个参数为最佳)【英文标题】:GridSearchCV unexpected behaviour (always returns the first parameter as the best) 【发布时间】:2021-12-18 15:05:47 【问题描述】:

我有一个多类分类问题,我需要找到最佳参数。我无法更改max_itersolvertol(它们是给定的),但我想检查哪个penalty 更好。但是,GridSearchCV 总是将第一个给定的罚分返回为最佳罚分。

例子:

from sklearn.model_selection import cross_val_score, GridSearchCV, StratifiedKFold
cv = StratifiedKFold(n_splits=5, random_state=0, shuffle=True)

fixed_params = 
    'random_state': 42,
    'multi_class': 'multinomial',
    'solver': 'saga',
    'tol': 1e-3,
    'max_iter': 500


parameters = [
    'C': [0.001, 0.01, 0.1, 1, 10, 100, 1000], 'penalty': ['l1', 'l2', None],
    'C': [0.001, 0.01, 0.1, 1, 10, 100, 1000], 'penalty': ['elasticnet'], 'l1_ratio': np.arange(0.0, 1.0, 0.1)     
]

model = GridSearchCV(LogisticRegression(**fixed_params), parameters, n_jobs=-1, verbose=10, scoring='f1_macro' ,cv=cv)
model.fit(X_train, y_train)

print(model.best_score_)
# 0.6836409100287101

print(model.best_params_)
# 'C': 0.1, 'penalty': 'l2'

如果我更改parameters 行的顺序,结果将完全相反:

from sklearn.model_selection import cross_val_score, GridSearchCV, StratifiedKFold
cv = StratifiedKFold(n_splits=5, random_state=0, shuffle=True)
    
fixed_params = 
    'random_state': 42,
    'multi_class': 'multinomial',
    'solver': 'saga',
    'tol': 1e-3,
    'max_iter': 500


parameters = [
        'C': [0.001, 0.01, 0.1, 1, 10, 100, 1000], 'penalty': ['elasticnet'], 'l1_ratio': np.arange(0.0, 1.0, 0.1) 
        'C': [0.001, 0.01, 0.1, 1, 10, 100, 1000], 'penalty': ['l1', 'l2', None]          
]
    
model = GridSearchCV(LogisticRegression(**fixed_params), parameters, n_jobs=-1, verbose=10, scoring='f1_macro' ,cv=cv)
model.fit(X_train, y_train)

print(model.best_score_)
# 0.6836409100287101

print(model.best_params_)
# 'C': 0.1, 'l1_ratio': 0.0, 'penalty': 'elasticnet'

因此,best_score_ 对于两个选项是相同的,但 best_params_ 不是。

你能告诉我有什么问题吗?

已编辑 与使用默认参数的基线相比,GridSearchCV 的结果更差。基线:

baseline_model = LogisticRegression(multi_class='multinomial', solver='saga', tol=1e-3, max_iter=500)
baseline_model.fit(X_train, y_train)
train_pred_baseline = baseline_model.predict(X_train)
print(f1_score(y_train, train_pred_baseline, average='micro'))

LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=真, 拦截缩放=1,l1_ratio=无,max_iter=500, multi_class='多项式',n_jobs=无,惩罚='l2', random_state=None,solver='saga',tol=0.001,verbose=0, warm_start=False)

Baseline 给我的 f1_micro 比 GridSearchCV 更好:

0.7522768670309654
 

Edited-2 因此,根据最佳f1_score 性能,C = 1 是我模型的最佳选择。但是 GridSearchCV 返回我C = 0.1。 我想,我想念一些东西... Baseline 的 f1_macro 也比 GridSearchCV 好:

    train_pred_baseline = baseline_model.predict(X_train)
    print(f1_score(y_train, train_pred_baseline, average='macro'))
    # 0.7441968750050458

【问题讨论】:

你可以尝试通过查看所有 GridSearch 的结果来调试它(检查model.cv_results_)。 【参考方案1】:

其实并没有错。事情就是这样。 Elasticnet 使用 L1 和 L2 惩罚项。但是,如果您的 l1_ratio 为 0,那么您基本上是在应用 L2 正则化,因此您只使用 L2 惩罚项。如文档中所述:

设置l1_ratio=0相当于使用penalty='l2',而设置l1_ratio=1相当于使用penalty='l1'。对于0 < l1_ratio <1,惩罚是 L1 和 L2 的组合。

由于您的第二个结果 l1_ratio 为 0,因此相当于使用 L2 惩罚项。

【讨论】:

你能告诉我,为什么 GridSearchCV 给我的 f1_score 比基线差吗? (我编辑了我的问题)。 使用默认设置,我的 f1 score_micro = 0.75,但在 GridSearchCV 之后只有 0.68。基线也更适合我的测试样本... 您使用f1_macro 作为网格搜索的记分员,但您的基线使用f1_micro。还要考虑到网格搜索使用交叉验证,因此部分训练集被保留在每个 CV 拆分中,其中保留的样本被评分和平均。 我的错,但问题仍然在我身上,f1_macro 也更适合基线。 更改 CV 参数是个好主意吗?

C++ std::find() 寻址返回向量的类函数时的意外行为

】C++std::find()寻址返回向量的类函数时的意外行为【英文标题】:C++std::find()unexpectedbehaviorwhenaddressingaClassfunctionreturningavector【发布时间】:2019-07-3122:37:26【问题描述】:我是一个理论问题。我有一个类Patient,其中有一个函数返... 查看详情

录制音频时 AudioQueueServices 回调的意外行为

】录制音频时AudioQueueServices回调的意外行为【英文标题】:UnexpectedbehaviorwithAudioQueueServicescallbackwhilerecordingaudio【发布时间】:2010-03-2604:23:45【问题描述】:我正在使用AudioQueueServices录制连续的数据流。据我了解,只有当缓冲区... 查看详情

查询的意外行为

】查询的意外行为【英文标题】:Unexpectedbehaviourofthequery【发布时间】:2011-07-3019:52:12【问题描述】:这个特定的查询应该将用户输入到数据库中。此查询并不总是将firstname和lastname字段的值与其他字段一起插入。对于少数插入... 查看详情

XGBoost - 帮助解释助推器的行为。为啥第 0 次迭代总是最好的?

】XGBoost-帮助解释助推器的行为。为啥第0次迭代总是最好的?【英文标题】:XGBoost-Helpinterpretingtheboosterbehaviour.Whyisthe0thiterationalwayscomingouttobebest?XGBoost-帮助解释助推器的行为。为什么第0次迭代总是最好的?【发布时间】:2021-05-... 查看详情

装饰器的意外行为[重复]

】装饰器的意外行为[重复]【英文标题】:Unexpectedbehaviourwithdecorator[duplicate]【发布时间】:2021-08-1717:27:48【问题描述】:假设我有一个简单的函数返回它自己的名字deffoo():print(foo.__name__)当然调用时的输出是foo。但是,如果我们... 查看详情

opencv cv::max 行为意外

】opencvcv::max行为意外【英文标题】:opencvcv::maxbehaviorunexpected【发布时间】:2014-05-1417:25:23【问题描述】:我将cv::max与未初始化的Mat对象一起使用,当将未初始化的对象作为第一个参数传递时发生错误:Mata=Mat::ones(2,3,CV_32S);Matb;m... 查看详情

意外的 redux 操作调度行为

】意外的redux操作调度行为【英文标题】:Unexpectedreduxactiondispatchbehaviour【发布时间】:2020-09-2220:23:35【问题描述】:所以我有一个从api获取的调度,然后它将根据请求的响应代码调度成功或错误操作。成功时,我的操作应该添... 查看详情

javascript:使用三元运算符的意外评估行为

】javascript:使用三元运算符的意外评估行为【英文标题】:javascript:UnexpectedEvaluationBehaviorwithTernaryOperator【发布时间】:2014-01-1814:34:16【问题描述】:问题:函数没有返回预期的值(3)。以下代码未按预期返回1。我发现这是由于使... 查看详情

Java 移位字节返回意外结果

】Java移位字节返回意外结果【英文标题】:Javashiftingbytesreturnsanunexpectedresult【发布时间】:2016-04-2613:35:31【问题描述】:我正在尝试将2个字节转换为短字节。这2个字节代表一个无符号短路,反过来又代表一个端口。我尝试了多... 查看详情

REST端点身份验证的Spring Security意外行为?

】REST端点身份验证的SpringSecurity意外行为?【英文标题】:SpringSecurityunexpectedbehaviorforRESTendpointsauthentication?【发布时间】:2017-05-0813:41:19【问题描述】:我们要找的场景如下:客户端通过REST连接到REST登录urlSpring微服务(使用Spri... 查看详情

VS: _BitScanReverse64 内在的意外优化行为

】VS:_BitScanReverse64内在的意外优化行为【英文标题】:VS:unexpectedoptimizationbehaviorwith_BitScanReverse64intrinsic【发布时间】:2017-05-1202:49:44【问题描述】:以下代码在调试模式下工作正常,因为定义了_BitScanReverse64如果未设置Bit,则返... 查看详情

当比较对象总是返回 true 或 false 时标准容器的预期行为

】当比较对象总是返回true或false时标准容器的预期行为【英文标题】:Expectedbehaviourforastandardcontainerwhencomparisonobjectalwaysreturnseithertrueorfalse【发布时间】:2021-06-1910:19:47【问题描述】:当自定义比较对象总是返回相同的结果(可... 查看详情

使用 cookie 的 JWT 身份验证中的意外行为

】使用cookie的JWT身份验证中的意外行为【英文标题】:UnexpectedbehaviorinJWTauthenticationusingcookies【发布时间】:2020-12-2122:26:04【问题描述】:我正在学习Node.js并制作我的第一个项目。我正在使用JWT对项目进行用户身份验证。我正在... 查看详情

GridsearchCV 不检查所有拆分 [关闭]

】GridsearchCV不检查所有拆分[关闭]【英文标题】:GridsearchCVdoesn\'tcheckallsplits[closed]【发布时间】:2021-12-0602:16:48【问题描述】:我有一个复杂的项目,其中包括多输出预测和自定义评分功能(越低越好)。我在网格的“平均测试... 查看详情

Bigint Division 总是返回零

】BigintDivision总是返回零【英文标题】:BigintDivisionalwaysreturningzero【发布时间】:2017-04-2010:54:58【问题描述】:我目前正在使用一个给我的bigint类。我已经成功地创建了加减乘法运算,但是我似乎无法破解除法运算符。我并不热... 查看详情

奇怪的 plist 行为在第一个值上返回 null ,当它应该是 12 时返回 13 个结果

】奇怪的plist行为在第一个值上返回null,当它应该是12时返回13个结果【英文标题】:Weirdplistbehaviourreturningnullonfirstvalueand13resultswhenitshouldbe12【发布时间】:2013-05-2120:56:23【问题描述】:在使用plist并尝试返回数据时,我遇到了这... 查看详情

无法理解 OpenMP 代码中的一些意外行为

】无法理解OpenMP代码中的一些意外行为【英文标题】:TroubleunderstandingsomeunexpectedbehaviourincodewithOpenMP【发布时间】:2019-11-0822:01:48【问题描述】:关于OpenMP并行化的问题。我在下面包含了我的函数的精简版本。问题是,for循环的... 查看详情

自定义 UITableView 的意外行为

】自定义UITableView的意外行为【英文标题】:UnexpectedbehaviorwithcustomUITableView【发布时间】:2011-03-3122:01:53【问题描述】:我正在创建一个实现自定义UITableView的应用程序。我这样做的方式如下:我创建了一个UINavigationController。这... 查看详情