在scikit-learn(sklearn)的管道中应用StandardScaler

时间:2018-07-21 19:26:52

标签: 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(-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(),这也是将其应用于测试集的正确方法吗?

2 个答案:

答案 0 :(得分:7)

是的,这样做是正确的方法,但是您的代码中有一个小错误。让我为您详细介绍一下。

当您在StandardScaler中使用Pipeline作为步骤时,scikit-learn将在内部为您完成这项工作。


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

  • 第0步:根据您在TRAINING data中指定的TEST data参数将数据分为cvGridSearchCV
  • 第1步:将scaler放在TRAINING data
  • 第2步:scaler转换TRAINING data
  • 第3步:使用经过转换的TRAINING data
  • 拟合/训练模型
  • 第4步:使用scaler变换TEST data
  • 第5步:使用predict
  • 训练后的模型transformed TEST data

注意:您应该使用grid.fit(X, y),并不要 grid.fit(X_train, y_train),因为GridSearchCV会自动将数据分为训练数据和测试数据(内部发生)。


使用类似这样的内容:

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()返回的结果对象中访问网格搜索的结果。 best_score_成员提供对在优化过程中观察到的最佳分数的访问,并且best_params_描述了获得最佳结果的参数组合。


重要编辑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 :(得分:1)

快速解答:您的方法是正确的。


尽管以上答案很好,但我只想指出一些细微之处:

best_score _ [1]是最佳的交叉验证指标,而不是模型的泛化性能[2]。要评估找到的最佳参数的概括程度,您应该像完成操作一样在测试集中调用分数。因此,需要首先将数据分为训练集和测试集,仅在X_train,y_train中进行网格搜索,然后使用X_test,y_test [2]对其评分。


深潜:

将数据分为训练集验证集测试集三倍是防止在网格搜索过程中参数过度拟合的一种方法。另一方面,GridSearchCV在训练集中使用交叉验证,而不是同时具有训练和验证集,但是此不会代替测试集。可以在[2]和[3]中进行验证。


参考:

[1] GridSearchCV

[2] Introduction to Machine Learning with Python

[3] 3.1 Cross-validation: evaluating estimator performance