使用sklearn的pipeline方法,可以将从数据预处理、特征提取到模型部署等组件拼装在一起,形成一条算法链。要求是这些组件都具有transfomr
方法,从而实现数据的转换。此外,值得关注的是,使用网格搜索可以直接在算法链上搜索我们需要的参数,比如我们想要启用多项式特征,而不知道1、2、3哪个参数更好,同时我们想要使用岭回归进行回归任务,需要设定参数alpha(岭回归Ridge使用L2正则化,而lasso使用L1正则化,二者都是Linear Regression加入正则化的变体),将加入多项式特征的polynomialfeatures和Ridge组合成一条算法链pipe,并将pipe输入到GridSearchCV进行网格搜索,即可获得最佳的参数配置。
①加载波士顿房价数据集并部署管道。
from sklearn.datasets import load_boston
from sklearn.linear_model import Ridge
from sklearn.preprocessing import PolynomialFeatures, StandardScaler
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.pipeline import make_pipeline
boston = load_boston()
X_train, X_test, y_train, y_test = train_test_split(boston.data, boston.target, random_state=0)
#制作管道
pipe = make_pipeline(
StandardScaler(),
PolynomialFeatures(),
Ridge()
)
②为参数设置搜索字典。
#为网格搜索GridSearchCV制作参数搜索字典
param_grid = {'polynomialfeatures__degree': [1, 2, 3],
'ridge__alpha': [0.001, 0.01, 0.1, 1, 10, 100]}
③将管道部署至GridSearchCV,进行网格搜索。注意,此处有一个bug不知道如何解决,当启用GridSearchCV的n_jobs参数时,会报错,但是删掉这个参数就好了。
grid = GridSearchCV(pipe, param_grid=param_grid, cv=5)
grid.fit(X_train, y_train)
import matplotlib.pyplot as plt
plt.matshow(grid.cv_results_['mean_test_score'].reshape(3, -1),
vmin=0, cmap="viridis")
plt.xlabel("ridge__alpha")
plt.ylabel("polynomialfeatures__degree")
plt.xticks(range(len(param_grid['ridge__alpha'])), param_grid['ridge__alpha'])
plt.yticks(range(len(param_grid['polynomialfeatures__degree'])),
param_grid['polynomialfeatures__degree'])
plt.colorbar()
显然,参数2(多项式幂级数)和10(L2正则化的alpha参数)是最佳的。
print("Best parameters: {}".format(grid.best_params_))
print("Test-set score: {:.2f}".format(grid.score(X_test, y_test)))
param_grid = {'ridge__alpha': [0.001, 0.01, 0.1, 1, 10, 100]}
pipe = make_pipeline(StandardScaler(), Ridge())
grid = GridSearchCV(pipe, param_grid, cv=5)
grid.fit(X_train, y_train)
print("Score without poly features: {:.2f}".format(grid.score(X_test, y_test)))
显然,向线性模型中加入非线性特征,可以显著提高其性能。