网格搜索交叉验证中的均方误差评分

3
我正在尝试设置GridSearchCV实例,以确定哪组超参数会产生最低的平均绝对误差。这个scikit文档指出,在创建GridSearchCV时可以将分数度量传递到网格中(如下所示)。
param_grid = {
    'hidden_layer_sizes' : [(20,),(21,),(22,),(23,),(24,),(25,),(26,),(27,),(28,),(29,),(30,),(31,),(32,),(33,),(34,),(35,),(36,),(37,),(38,),(39,),(40,)],
    'activation' : ['relu'],
    'random_state' : [0]
    }
gs = GridSearchCV(model, param_grid, scoring='neg_mean_absolute_error')
gs.fit(X_train, y_train)
print(gs.scorer_)

[1] make_scorer(mean_absolute_error, greater_is_better=False)

然而,网格搜索并没有选择在平均绝对误差方面表现最佳的模型。
model = gs.best_estimator_.fit(X_train, y_train)
print(metrics.mean_squared_error(y_test, model.predict(X_test)))
print(gs.best_params_)

[2] 125.0
[3] Best parameters found by grid search are: {'hidden_layer_sizes': (28,), 'learning_rate': 'constant', 'learning_rate_init': 0.01, 'random_state': 0, 'solver': 'lbfgs'}

运行上述代码并确定所谓的“最佳参数”后,我删除了gs.best_params_中找到的一个值,并发现重新运行程序时均方误差有时会减少。

param_grid = {
'hidden_layer_sizes' : [(20,),(21,),(22,),(23,),(24,),(25,),(26,),(31,),(32,),(33,),(34,),(35,),(36,),(37,),(38,),(39,),(40,)],
'activation' : ['relu'],
'random_state' : [0]
}

[4] 122.0
[5] Best parameters found by grid search are: {'hidden_layer_sizes': (23,), 'learning_rate': 'constant', 'learning_rate_init': 0.01, 'random_state': 0, 'solver': 'lbfgs'}

为了澄清,我更改了输入到网格搜索中的集合,使其不包含选择隐藏层大小为28的选项。当进行此更改时,我再次运行了代码,这一次它选择了一个隐藏层大小为23,并且平均绝对误差减小了(即使大小23从一开始就可用),为什么它没有从一开始就选择这个选项,如果它正在评估平均绝对误差呢?

1个回答

2
网格搜索和模型拟合在本质上依赖于不同目的的随机数生成器。在scikit-learn中,这由参数random_state控制。请参阅我的其他答案以了解更多信息: 现在在您的情况下,我可以想到这些影响训练的随机数生成的事情:
1)对于回归任务,默认情况下,GridSearchCV将使用3折KFold,可能会在不同运行中分别拆分数据。两个网格搜索过程中发生的拆分可能是不同的,因此得分也不同。
2)您正在使用单独的测试数据来计算mse,但GridSearchCV无法访问该数据。因此,它将找到适用于提供的数据的参数,这些参数可能或可能不完全适用于单独的数据集。

更新:

我现在看到您在模型的参数网格中使用了random_state,因此这一点3现在不适用。
3)您没有显示您正在使用哪个model。但是,如果模型在训练过程中使用数据的子样本(例如选择更少的特征或更少的迭代行或不同的内部估计器),则您还需要修复它以获得相同的分数。您需要首先检查结果并进行修复。

推荐示例

您可以从此示例中获取灵感:
# Define a custom kfold
from sklearn.model_selection import KFold
kf = KFold(n_splits=3, random_state=0)

# Check if the model you chose support random_state
model = WhateEverYouChoseClassifier(..., random_state=0, ...)

# Pass these to grid-search
gs = GridSearchCV(model, param_grid, scoring='neg_mean_absolute_error', cv = kf)

然后再次进行两个实验,通过更改参数网格来完成。


我正在使用sklearn.neural_network中的MLPRegressor。我从您的解决方案中添加了kf变量。我的结果确实发生了变化,但是当我删除网格参数时,平均绝对误差仍在波动上下。我还意识到GridSearchCV正在对我的训练数据执行,而不是我的测试数据,因此我也更改了输出以反映这一点。 - David Bean

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接