在下面的例子中,
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
作为Pipeline
中的一个步骤使用时,scikit-learn会内部为你完成工作。
发生的情况可以描述如下:
- 步骤0:根据你在
GridSearchCV
中指定的cv
参数,数据被分割成训练数据
和测试数据
。 - 步骤1:
scaler
在训练数据
上进行拟合 - 步骤2:
scaler
转换训练数据
- 步骤3:使用转换后的
训练数据
拟合/训练模型 - 步骤4:
scaler
用于转换测试数据
- 步骤5:训练好的模型使用
转换后的测试数据
进行预测
注意:你应该使用grid.fit(X, y)
而不是grid.fit(X_train, y_train)
,因为GridSearchCV
会自动将数据分割成训练和测试数据(这在内部发生)。
使用类似这样的代码:
from sklearn.pipeline import Pipelinefrom sklearn.svm import SVCfrom sklearn.preprocessing import StandardScalerfrom sklearn.model_selection import GridSearchCVfrom sklearn.decomposition import PCApipe = 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)