【问题标题】:Issue while using different scoring metric in Gridsearchcv sklearn在 Gridsearchcv sklearn 中使用不同的评分指标时出现问题
【发布时间】:2021-01-09 07:15:11
【问题描述】:

我正在做弹性网络回归并尝试使用 GridSearchCV 估计最佳超参数。但是当我将 GridSearchCV 中的评分从默认的 r2 更改为 mean_squared_error 时,GridSearchCV 使每个特征系数为 0。我不知道为什么会这样。

这里是代码。

param={
'elastic__alpha':np.linspace(.1,1,15),
'elastic__l1_ratio':np.linspace(0,1,30)
}
pipe=Pipeline([('scalar',StandardScaler()),('elastic',ElasticNet(max_iter=10000))])
search=GridSearchCV(pipe,param_grid=param,cv=4,scoring=make_scorer(mean_squared_error))
search.fit(train_x,train_y)

【问题讨论】:

  • 您能否提供一个minimal, reproducible example 您的代码?目前您的代码无法运行,因为“train_x”和“train_y”未定义。

标签: python scikit-learn regression hyperparameters gridsearchcv


【解决方案1】:

你会因为错误使用函数 make_scorer 得到这个问题。默认情况下,它假定分数越高越好,如果您查看help page,在参数greater_is_better 下:

greater_is_better bool, default=True score_func 是否为分数 函数(默认),意思是高是好的,或者是损失函数,意思是 低是好的。在后一种情况下,记分者对象将符号翻转 score_func 的结果。

如果您使用 r2,则默认值有效。如果你使用均方误差,你想最小化误差,你需要设置greater_is_better = False

我们可以使用一个示例数据集来证明这一点:

from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.linear_model import ElasticNet
from sklearn.model_selection import GridSearchCV, train_test_split
from sklearn.metrics import make_scorer, mean_squared_error
from sklearn import datasets

data = datasets.load_boston()
X = data['data']
y = data['target']

然后设置一些简单的参数:

param={
'elastic__alpha':np.linspace(0.2,0.8,2),
'elastic__l1_ratio':np.linspace(0.2,0.8,2)
}

pipe=Pipeline([('scalar',StandardScaler()),('elastic',ElasticNet(max_iter=10000))])
search=GridSearchCV(pipe,param_grid=param,cv=4,scoring="r2")
search.fit(X_train,y_train)

search.best_params_
{'elastic__alpha': 0.2, 'elastic__l1_ratio': 0.2}

运行你的函数:

pipe=Pipeline([('scalar',StandardScaler()),('elastic',ElasticNet(max_iter=10000))])
search=GridSearchCV(pipe,param_grid=param,cv=4,scoring=make_scorer(mean_squared_error))
search.fit(X_train,y_train)

search.best_params_
{'elastic__alpha': 0.8, 'elastic__l1_ratio': 0.2}

最佳参数不同,您可以看到选择了最大均方误差的参数:

res = pd.DataFrame(search.cv_results_['params'])
res['score'] = search.cv_results_['mean_test_score']
res.sort_values('score',ascending=False)

elastic__alpha  elastic__l1_ratio   score
2   0.8 0.2 30.348081
3   0.8 0.8 29.191112
1   0.2 0.8 25.891039
0   0.2 0.2 25.733661

如果我们这样做greater_is_better=False,结果是有意义的:

pipe=Pipeline([('scalar',StandardScaler()),('elastic',ElasticNet(max_iter=10000))])
search=GridSearchCV(pipe,param_grid=param,cv=4,scoring=make_scorer(mean_squared_error,greater_is_better=False))
search.fit(X_train,y_train)

search.best_params_

{'elastic__alpha': 0.2, 'elastic__l1_ratio': 0.2}

res = pd.DataFrame(search.cv_results_['params'])
res['score'] = search.cv_results_['mean_test_score']
res.sort_values('score',ascending=False)

    elastic__alpha  elastic__l1_ratio   score
0   0.2 0.2 -25.733661
1   0.2 0.8 -25.891039
3   0.8 0.8 -29.191112
2   0.8 0.2 -30.348081

所以他们提供了一个名为“neg_mean_squared_error”的选项是有充分理由的,如果我们使用它,你会看到你得到相同的结果。

【讨论】:

    猜你喜欢
    • 2018-11-05
    • 2020-08-08
    • 1970-01-01
    • 2018-09-09
    • 2015-04-22
    • 2020-03-07
    • 2015-10-15
    • 2021-11-18
    • 2018-04-19
    相关资源
    最近更新 更多