对于超参数调整,我使用 Python 包
GridSearchCV
中的函数 sklearn
。我测试的一些模型需要特征缩放(例如支持向量回归 - SVR)。最近,在 Udemy 课程机器学习 A-Z™:数据科学中的 Python 和 R 实践中,讲师提到对于 SVR,目标也应该进行缩放(如果不是二进制)。考虑到这一点,我想知道目标是否也在 GridSearchCV
执行的交叉验证过程的每次迭代中进行缩放,或者是否仅缩放特征。请参阅下面的代码,它说明了我用于对需要缩放训练集的估计器进行超参数调整的正常过程:
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVR
def SVRegressor(**kwargs):
'''contruct a pipeline to perform SVR regression'''
return make_pipeline(StandardScaler(), SVR(**kwargs))
params = {'svr__kernel': ["poly", "rbf"]}
grid_search = GridSearchCV(SVRegressor(), params)
grid_search.fit(X, y)
我知道我可以简单地缩放
X
和 y
先验 并从管道中删除 StandardScaler。但是,我想在测试多个模型的代码管道中实现这种方法,其中一些需要缩放,而另一些则不需要。这就是为什么我想知道 GridSearchCV
如何处理底层的缩放。
不,它不会缩放目标,如果你查看 make_pipeline,它只是将 X 和 y 参数传递到你的变压器中,并且
StandardScaler()
对你的 y
没有任何作用:
def _fit_transform_one(transformer,
X,
y,
weight,
message_clsname='',
message=None,
**fit_params):
"""
Fits ``transformer`` to ``X`` and ``y``. The transformed result is returned
with the fitted transformer. If ``weight`` is not ``None``, the result will
be multiplied by ``weight``.
"""
with _print_elapsed_time(message_clsname, message):
if hasattr(transformer, 'fit_transform'):
res = transformer.fit_transform(X, y, **fit_params)
else:
res = transformer.fit(X, y, **fit_params).transform(X)
if weight is None:
return res, transformer
return res * weight, transformer
您可以在 StandardScaler() 上尝试一下,您可以看到它对 y 没有任何作用:
np.random.seed(111)
X = np.random.normal(5,2,(100,3))
y = np.random.normal(5,2,100)
res = StandardScaler().fit_transform(X=X,y=y)
res.shape
(100, 3)
res.mean(axis=0)
array([1.01030295e-15, 4.39648318e-16, 8.91509089e-16])
res.std(axis=0)
array([1., 1., 1.])
您还可以检查 gridsearchcv 的结果:
SVRegressor = make_pipeline(StandardScaler(), SVR())
params = {'svr__kernel': ["poly", "rbf"]}
grid_search = GridSearchCV(SVRegressor, params,
scoring='neg_mean_absolute_error')
在未缩放的 y 上,您将看到在未缩放的数据上,您的负平均绝对误差与标准差的比例大致相同(我在示例中使用了 2):
grid_search.fit(X, y)
grid_search.cv_results_['mean_test_score']
array([-2.01029707, -1.88779205])
在缩放后的 y 上,我们的标准差将为 1,您可以看到误差约为 -1,:
y_scaled = StandardScaler().fit_transform(y.reshape(-1,1)).ravel()
grid_search.fit(X, y_scaled)
grid_search.cv_results_['mean_test_score']
array([-1.00585999, -0.88330208])
grid_search.fit(data_scaled, target): ValueError: 内核产品的参数 length_scale 无效。使用
kernel.get_params().keys()
检查可用参数列表。