3.2 调整估计器的超参数

​ 超参数是估计器的参数中不能通过学习得到的参数。在scikit-learn中,他们作为参数传递给估计器不同类的构造函数。典型的例子有支持向量分类器的参数C,kernel和gamma,Lasso的参数alpha等。

​ 在超参数集中搜索以获得最佳cross validation交叉验证分数的方法是可实现并且推荐的。

​ 当构建一个估计器是,任意参数的选取通过这种方式可能会获得最佳参数。尤其是,要想知道参数名字和其对应的当前值,使用:

estimator.get_params() 

​ 搜索包括:

  • 一个估计器(回归或分类,如sklearn.svm.SVC());
  • 一个参数空间;
  • 一个搜索的方法或可选参数集;
  • 一个交叉验证的方案;
  • 一个评分函数。

一些模型允许专业化,高效的参数搜索策略,outlined below。在scikit-learn中,两种方法可用来抽样搜索最佳参数:对于给定值,GridSearchCV会计算所有参数的组合,而RandomizedSearchCV可以从具有指定分布的参数空间中抽样出定量的参数候选。在描述这些工具后,会详细介绍best practice在这两种方法的应用。

需要注意的是:尽管其它参数都设置为初始值,但一个小的参数集合仍会对模型预测或者计算效果有很大的影响。推荐阅读估计器类的文档,以了解各参数的含义,可能的话还可阅读随附文献资料。

3.2.1 穷尽的网格搜索

GridSearchCV提供的网格搜索,通过使用pram_grid参数指定参数候选值,穷尽的生成候选项。如下param_grid的例子:

param_grid = [
  {'C': [1101001000], 'kernel': ['linear']},
  {'C': [1101001000], 'gamma': [0.0010.0001], 'kernel': ['rbf']},
 ] 

指定探索两个网格:第一个是线性核和C值范围为[1, 10, 100, 1000];第二个是RBF核,C值的交叉乘积范围在[1, 10, 100, 1000]和gamma值范围在[0.001, 0.0001]。

GridSearchCV实例实现常用估计器API:当在数据集上“fitting”(拟合)并获得所有可能的参数值组合评估,从而保留最好的组合。

例如:

3.2.2 随机参数优化

​ 尽管使用网格(grid)的参数设置是应用最广泛的参数优化方法,其它的搜索方法有更多的优良性质。RamdomizedSeaarchCV执行一个参数的随机搜索,其中每一个设置都是从某个分布中抽取出可能的参数值。相较而言,该种方法有两个主要的优势:

  • 运行成本与参数个数和其可能的取值相独立。
  • 添加参数不影响表现,也不影响效率。

指定参数如何被抽样是用字典形式,与指定GridSearchCV参数相类似。除此以外,运行预算的成本,是样本候选量或样本迭代次数,可以使用n_iter参数定义。对于每一个参数,或者可能取值的分布或离散选项的列表(将被统一采样)可以被指定:

{'C': scipy.stats.expon(scale=100), 'gamma': scipy.stats.expon(scale=.1),
  'kernel': ['rbf'], 'class_weight':['balanced'None]} 

该示例使用scipy.stats模块,该模块包含很多采样参数分布,例如expon,gamma,uniform或者randint。

整体而言,通过提供rvs(随机变量样本)方法来采样一个值,任何功能都可以被传递。对rvs函数的调用应在连续调用时提供可能参数值的独立随机样本。

警告:scipy0.16之前的版本不允许指定随机状态,而是使用全局numpy随机状态,可以通过np.random.seed或no.random.set_state设置种子。但是,从scikit-learn0.18开始,如果scipy>=0.16,sklearn.model_selection模块可以设置随机状态。

对于连续参数,例如上面提到的参数C,指定一个连续分布来充分利用随机化是至关重要的。通过提高n_iter参数可以带来更好的搜索结果。

一个连续的log-uniform随机变量可以通过loguniform使用。它是log-spaced参数的连续版。例如指定参数C,可以使用loguniform(1, 100)而不是[1, 10, 100]或者np.logspace(0, 2, num = 1000)。 它是SciPy's stats.reciprocal的别名。

在网格搜索中镜像以上示例,可以指定一个连续随机变量,它是对数-均匀分布,介于1e0和1e3之间:

from sklearn.utils.fixes import loguniform
{'C': loguniform(1e01e3),
 'gamma': loguniform(1e-41e-3),
 'kernel': ['rbf'],
 'class_weight':['balanced'None]} 

例如:

参考文献:

  • Bergstra, J. and Bengio, Y., Random search for hyper-parameter optimization, The Journal of Machine Learning Research (2012)

3.2.3 参数搜索技巧

3.2.3.1 指定目标度量

参数搜索的初始化是使用估计器的score函数来评估一个参数设置。sklearn.metrics.accuracy_score用于分类,sklearn.metrics.r2_score应用于回归。在一些应用中,其它的评估函数更加适用(例如在样本不平衡的分类中,精度评分往往是信息不足的)。可以给GridSearchCV,RandomizedSearchCV的参数scoring指定其它的评分函数,同时许多的交叉验证工具将在下文介绍。详见评分参数:定义模型评估规则

3.2.3.2 指定多指标评估

GridSearchCV和RandomizedSearchCV允许给scoring指定具体参数。

多指标评估可以通过字符串列表的形式预定义评分名称或者以字典形式将评分名称映射给评分函数,或者预先定义评估名称。详见使用多指标评估

当指定多指标时,参数refit必须被指定一个指标(字符串),才可以调用best_params_,并在整个数据集上构建best_estimator_的度量标准。当设置refit = False时,网格搜索不会refit模型。当使用多指标评估时,使用refit的初始值None会报错。

详见交叉值得分和GridSearchCV多指标评价的实证研究

3.2.3.3 复合估计和参数空间

GridSearchCVRandomizedSearchCV许搜索复合或嵌套估计器的参数,例如PipelineColumnTransFormerVotingClassifier或者CalibratedClassifierCV,均使用__语法设置。

>>> from sklearn.model_selection import GridSearchCV
>>> from sklearn.calibration import CalibratedClassifierCV
>>> from sklearn.ensemble import RandomForestClassifier
>>> from sklearn.datasets import make_moons
>>> X, y = make_moons()
>>> calibrated_forest = CalibratedClassifierCV(
...    base_estimator=RandomForestClassifier(n_estimators=10))
>>> param_grid = {
...    'base_estimator__max_depth': [2468]}
>>> search = GridSearchCV(calibrated_forest, param_grid, cv=5)
>>> search.fit(X, y)
GridSearchCV(cv=5,
             estimator=CalibratedClassifierCV(...),
             param_grid={'base_estimator__max_depth': [2468]})  

是嵌套估计器的名称,在上例中base_estimator。如果元估计器用估计器的集合所构建,如pipeline.Pipelins,然后指向估计器的名称,详见Nested parameters。在实例中,会用不同级别的嵌套:

>>> from sklearn.pipeline import Pipeline
>>> from sklearn.feature_selection import SelectKBest
>>> pipe = Pipeline([
...    ('select', SelectKBest()),
...    ('model', calibrated_forest)])
>>> param_grid = {
...    'select__k': [12],
...    'model__base_estimator__max_depth': [2468]}
>>> search = GridSearchCV(pipe, param_grid, cv=5).fit(X, y) 

3.2.3.4 模型选择:开发和评估

通过评估各种参数设置,模型选择可以看成是使用已标记的数据“训练”的网格参数 。

当评估模型结果时,使用的样本需是不被用来训练网格搜索的数据:将数据拆分为开发集(GridSeaarchCV使用的数据)和评估集来计算各指标表现是推荐做法。

上述推荐做法可用train_test_split功能实现。

3.2.3.5 并行机制

GridSearchCVRandomizedSearchCV会独立评估每一个参数设置。如果你的操作系统支持,计算过程可以同时运行,需要设置参数n_jobs = -1。详见函数签名。

3.2.3.6 对失败的鲁棒性

一些参数设置可能会导致不能fit一个或多个折叠的数据。如果不修改初始值,尽管某些参数可以被完全评估,但仍会引起整个网格搜索的失败。设置error_socre=0(或者 =np.NaN)可以使整个流程对于类似失败具有鲁棒性,程序返回报警并把该折叠的分数设为0(或者NaN),但会完成整个搜索。

3.2.4 暴力参数搜索的替代方法

3.2.4.1 模型特定的交叉验证

一些模型可以根据一定范围的参数值来fit(拟合)数据,这与估计器fit(拟合)单个参数取值的效率一致。设置该参数的模型选择可以用来执行更有效率的交叉验证。

适应该策略的最常见参数是编码正则器强度的参数。在该例子中,计算的是规范化路径的估计器。

如下是这些模型的列表:

模型 解释
linear_model.ElasticNetCV(*[, l1_ratio, ...]) Elastic Net model with iterative fitting along a regularization path. 沿单一标准化路径迭代fitting的Elastic Net模型。
linear_model.LarsCV(*[, fit_intercept, ...]) Cross-validated Least Angle Regression model. 交叉验证的Least Angle 回归模型。
linear_model.LassoCV(*[, eps, n_alphas, ...]) Lasso linear model with iterative fitting along a regularization path. 沿单一标注化路径迭代fitting Lasso线性模型。
linear_model.LassoLarsCV(*[, fit_intercept, ...]) Cross-validated Lasso, using the LARS algorithm. Lasso交叉验证,使用LARS算法。
Linear_model_LogisticRegressionCV(*[, Cs, ...]) Logistic Regression CV (aka logit, MaxEnt) classifier. 逻辑回归交叉验证(aka logit, MaxEnt)分类器。
linear_model.MultiTaskElasticNetCV(*[, ...]) Multi-task L1/L2 ElasticNet with built-in cross-validation. 内置交叉验证的多任务L1/L2 ElasticNet。
linear_model.MultiTaskLassoCV(*[, eps, ...]) Multi-task Lasso model trained with L1/L2 mixed-norm as regularizer. L1/L2混合标准作为正则化的多任务Lasso模型
linear_OrthogonalMatchingPursuitCV(*) Cross-validated Orthogonal Matching Pursuit model (OMP).
linear_model.RidgeCV([alphas, ...]) Ridge regression with built-in cross-validation. 内置交叉验证的岭回归。
linear_model.RidgeClassifierCV([alphas, ...]) Ridge classifier with built-in cross-validation. 内置交叉验证的岭分类器 。

3.2.4.2 信息标准

通过计算单个(不是许多)标准化路径,一些模型可以提供最佳估计的标准化参数的信息理论闭合公式。

下面是收益于Akaike信息标准(AIC)或者贝叶斯信息标准(BIC)的模型列表,用于自动模型选择:

模型 解释
linear_model.LassoLarsIC([criterion, ...]) Lasso模型fit Lars时,模型选择使用BIC或者AIC标准。

3.2.4.3 袋外估计

当使用基于bagging 的集成方法时,例如使用不同的采样生成新的训练集,训练集中部分数据仍然不被使用。对于集成算法中的每一个分类器,训练集中的不同数据会落到袋外。

不需要划分验证集,就可以使用袋外数据估计泛化误差。该估计方式“免费”提供,因此不需要额外数据,可被用于模型选择中。

以下类可以执行该操作:

模型 解释
ensemble.RandomForestClassifier([...]) 随机森林分类器
ensemble.RandomForestRegressor([...]) 随机森林回归器
ensemble.ExtraTreesClassifier([...]) extra-trees分类器
ensemble.ExtraTreesRegressor([n_estimators, ...]) extra-tess回归器
ensemble.GradientBoostingClassifier(*[, ...]) 梯度提升分类
ensemble.GradientBoostingRegressor(*[, ...]) 梯度提升回归