python - 使用 GridSearchCV 进行目标缩放

标签 python python-3.x scikit-learn svm gridsearchcv

对于超参数调整,我使用 Python 包 sklearn 中的函数 GridSearchCV。我测试的一些模型需要特征缩放(例如支持向量回归 - SVR)。最近,在 Udemy 类(class)《机器学习 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)

我知道我可以简单地缩放Xy先验并从管道中删除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])

关于python - 使用 GridSearchCV 进行目标缩放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67136674/

相关文章:

python - 在Python中,我应该为此使用线程吗?

python - 第 8 行 : 'crsf_token' , 上的无效 block 标记应为 'endblock'。您是否忘记注册或加载此标签?

python - Sklearn LogisticRegression 求解器需要 2 类数据

python - Python 中的简单二维聚类算法

python - 为什么 Pandas 的速度如此之快?如何定义这样的功能?

python - LinearSVC 无法使用均值差进行分类

python - 我什么时候在 Gekko 中使用 Param 而不是 Const?

python - Django - 在 apache 每个请求创建的所有进程之间共享 RabbitMQ 连接?

python - 我如何按值分组?

python-3.x - Microsoft Speech to Text Python SDK SPXERR_INVALID_HEADER 问题