Python 如何在scikit学习(sklearn)的管道中应用StandardScaler?

Python 如何在scikit学习(sklearn)的管道中应用StandardScaler?,python,scikit-learn,Python,Scikit Learn,在下面的例子中 pipe = Pipeline([ ('scale', StandardScaler()), ('reduce_dims', PCA(n_components=4)), ('clf', SVC(kernel = 'linear', C = 1))]) param_grid = dict(reduce_dims__n_components=[4,6,8], clf__C=np.logspace(-

在下面的例子中

pipe = Pipeline([
        ('scale', StandardScaler()),
        ('reduce_dims', PCA(n_components=4)),
        ('clf', SVC(kernel = 'linear', C = 1))])

param_grid = dict(reduce_dims__n_components=[4,6,8],
                  clf__C=np.logspace(-4, 1, 6),
                  clf__kernel=['rbf','linear'])

grid = GridSearchCV(pipe, param_grid=param_grid, cv=3, n_jobs=1, verbose=2)
grid.fit(X_train, y_train)
print(grid.score(X_test, y_test))

我使用的是
StandardScaler()
,这也是将其应用于测试集的正确方法吗?

是的,这是正确的方法,但您的代码中有一个小错误。让我为您分析一下

当您使用
StandardScaler
作为
管道中的一个步骤时,scikit learn将在内部为您完成这项工作


发生的情况可以描述如下:

  • 步骤0:根据您在
    GridSearchCV
    中指定的
    cv
    参数,将数据分为
    TRAINING data
    TEST data
  • 步骤1:
    定标器
    安装在
    训练数据上
  • 步骤2:
    scaler
    转换
    训练数据
  • 步骤3:使用转换后的
    训练数据安装/训练模型
  • 步骤4:
    定标器
    用于转换
    测试数据
  • 步骤5:经过训练的模型
    使用
    转换的测试数据预测

注意:您应该使用
grid.fit(X,y)
而不是
grid.fit(X\u-train,y\u-train)
,因为
GridSearchCV
会自动将数据分割为训练和测试数据(这在内部发生)


使用类似以下内容:

from sklearn.pipeline import Pipeline
from sklearn.svm import SVC
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import GridSearchCV
from sklearn.decomposition import PCA

pipe = Pipeline([
        ('scale', StandardScaler()),
        ('reduce_dims', PCA(n_components=4)),
        ('clf', SVC(kernel = 'linear', C = 1))])

param_grid = dict(reduce_dims__n_components=[4,6,8],
                  clf__C=np.logspace(-4, 1, 6),
                  clf__kernel=['rbf','linear'])

grid = GridSearchCV(pipe, param_grid=param_grid, cv=3, n_jobs=1, verbose=2, scoring= 'accuracy')
grid.fit(X, y)
print(grid.best_score_)
print(grid.cv_results_)

运行此代码后(当调用
grid.fit(X,y)
时),可以在grid.fit()返回的结果对象中访问网格搜索的结果。
最佳评分
成员提供对优化过程中观察到的最佳评分的访问,
最佳参数
描述了获得最佳结果的参数组合。


重要编辑1:如果要保留原始数据集的验证数据集,请使用以下命令:

X_for_gridsearch, X_future_validation, y_for_gridsearch, y_future_validation 
    = train_test_split(X, y, test_size=0.15, random_state=1)
然后使用:

grid = GridSearchCV(pipe, param_grid=param_grid, cv=3, n_jobs=1, verbose=2, scoring= 'accuracy')
grid.fit(X_for_gridsearch, y_for_gridsearch)

快速回答:您的方法是正确的


虽然上述答案很好,但我只想指出一些微妙之处:

最佳评分[1]是最佳交叉验证指标,而不是模型的泛化性能[2]。为了评估最佳参数的泛化程度,您应该调用测试集上的分数,正如您所做的那样。因此,首先需要将数据分为训练集和测试集,仅在X_序列、y_序列中拟合网格搜索,然后使用X_测试、y_测试对其进行评分[2]


深潜:

from sklearn.pipeline import Pipeline
from sklearn.svm import SVC
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import GridSearchCV
from sklearn.decomposition import PCA

pipe = Pipeline([
        ('scale', StandardScaler()),
        ('reduce_dims', PCA(n_components=4)),
        ('clf', SVC(kernel = 'linear', C = 1))])

param_grid = dict(reduce_dims__n_components=[4,6,8],
                  clf__C=np.logspace(-4, 1, 6),
                  clf__kernel=['rbf','linear'])

grid = GridSearchCV(pipe, param_grid=param_grid, cv=3, n_jobs=1, verbose=2, scoring= 'accuracy')
grid.fit(X, y)
print(grid.best_score_)
print(grid.cv_results_)
将数据分成训练集验证集测试集三部分是防止网格搜索过程中参数过度拟合的一种方法。另一方面,GridSearchCV在训练集中使用交叉验证,而不是同时使用训练集和验证集,但这不会取代测试集。这可以在[2]和[3]中得到验证


参考文献:

from sklearn.pipeline import Pipeline
from sklearn.svm import SVC
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import GridSearchCV
from sklearn.decomposition import PCA

pipe = Pipeline([
        ('scale', StandardScaler()),
        ('reduce_dims', PCA(n_components=4)),
        ('clf', SVC(kernel = 'linear', C = 1))])

param_grid = dict(reduce_dims__n_components=[4,6,8],
                  clf__C=np.logspace(-4, 1, 6),
                  clf__kernel=['rbf','linear'])

grid = GridSearchCV(pipe, param_grid=param_grid, cv=3, n_jobs=1, verbose=2, scoring= 'accuracy')
grid.fit(X, y)
print(grid.best_score_)
print(grid.cv_results_)
[1]

[2]


[3]

这是一个伟大的答案@seralouk!谢谢训练模型的输入是否也需要缩放?我知道这不是原始问题的一部分,但是如果你能把它添加到你的答案中,那就太好了。当您说“训练模型的输入也需要缩放”时,您的确切意思是什么?不。如果您对整个数据集进行了
GridSearchCV
,那么您已经对整个数据集进行了超参数训练,并且不再有测试集来验证您的模型。@seralouk,我的意思是您可以为
.predict()
添加一行吗?如果我做一些类似于
grid.predict(X_测试)
的事情,它会在不需要再次指定StandardScalar的情况下工作吗?我想原始海报想知道在整个交叉验证之后是否调用了grid.predict(X_测试),缩放仍然应用于X_测试?如果是,使用X_序列的平均值/std或是基于X_检验计算的新平均值/std,什么类型的标度。我也在想同样的事情。谢谢你的帮助。