Sklearn 模型选择

2024年8月29日 | 13分钟阅读

Sklearn 的模型选择模块提供了各种函数来交叉验证我们的模型、调整估计器的超参数,或者生成验证曲线和学习曲线。

以下是此模块中提供的函数列表。稍后我们将通过代码示例理解这些函数的理论和用法。

分割器类

model_selection.GroupKFold([ n_splits ])此函数是 KFold 交叉验证的一种变体,它形成非重叠组。
model_selection.GroupShuffleSplit([ ... ])此函数执行洗牌-分组(s)-出交叉验证测试。
model_selection.KFold([ n_splits, shuffle, ... ])此函数用于执行 KFold 交叉验证测试。
model_selection.LeaveOneGroupOut( )此函数执行留一分组交叉验证测试。
model_selection.LeavePGroupsOut( n_groups )此函数通过使用留 P 分组执行测试。
model_selection.LeaveOneOut( )此测试执行留一交叉验证。
model_selection.LeavePOut( p )使用留一法交叉验证器
model_selection.PredefinedSplit( test_fold )这是留一测试的通用版本,即留 P 交叉验证测试。
model_selection.RepeatedKFold( *[, n_splits, ... ] )这在预定义分割上执行交叉验证测试。
model_selection.RepeatedStratifiedKFold( *[, ... ] )此测试执行重复分层 K-折叠交叉验证。
model_selection.ShuffleSplit([n_splits, ... ])此函数使用随机置换在洗牌分割数据集上执行交叉验证测试。
model_selection.StratifiedKFold([ n_splits, ... ])此函数执行分层 KFold 交叉验证测试。
model_selection.StratifiedShuffleSplit([ ... ])此函数执行分层洗牌分割交叉验证测试。
model_selection.StratifiedGroupKFold([ ... ])此函数在非重叠组上执行分层 K-折叠交叉验证测试。
model_selection.TimeSeriesSplit([ n_splits, ... ])此交叉验证测试用于时间序列。

分割器函数

model_selection.check_cv([ cv, y, classifier ])此函数检查执行交叉验证测试的实用程序。
model_selection.train_test_split( *arrays[, ...] )此函数通过将矩阵或数组随机分离成训练和测试数据集来执行交叉验证。

超参数优化器

model_selection.GridSearchCV( estimator, ... )此函数对定义的参数执行估计器的穷举搜索。
model_selection.HalvingGridSearchCV( ...[, ...] )此函数通过使用逐次减半对给定参数执行搜索。
model_selection.ParameterGrid( param_grid )此函数执行参数网格,其中每个参数具有离散值范围。
model_selection.ParameterSampler( ...[, ...] )此函数作为从给定分布中获取的参数样本生成器。
model_selection.RandomizedSearchCV( ...[, ...] )此函数对超参数执行随机搜索。
model_selection.HalvingRandomSearchCV( ...[, ...] )此函数对超参数执行随机搜索。

交叉验证:评估估计器的性能

数据科学家在创建模型时犯的一个基本错误是学习预测函数的参数并在相同数据集上评估模型。一个简单地重复它刚刚训练过的数据点标签的模型会得分很高,但无法对模型尚未见过的数据做出任何预测。这种现象被称为过拟合。

在进行机器学习实验时,通常会保留一部分给定数据作为验证集或测试集 (X test, y test) 以避免此问题。我们应该注意,“实验”一词不仅仅指学术目的,因为机器学习实验有时在当今商业世界中开始。

代码

输出

Size of Dataset is: 150
K-fold Cross Validation Scores are:  [1.         1.         0.86666667 0.93333333 0.83333333]
Mean Cross Validation score is:  0.9266666666666665

交叉验证方法的另一个示例。

代码

输出

Size of Dataset is:  150
LeavePOut Cross Validation Scores are:  [1. 1. 1. ... 1. 1. 1.]
Average Cross Validation score is:  0.9494854586129754

交叉验证指标计算

调用估计器和数据集的 cross_val _score 实用方法是计算交叉验证测试性能最直接的方法。

以下示例展示了分割数据、开发模型、通过交叉验证测试对其进行测试以及连续五次(每次使用不同的分割)计算得分以测量支持向量机模型在 sklearn 的鸢尾花数据集上的准确度得分的方法。

代码

输出

0.9666666666666667
[0.96666667 1.         0.96666667 0.96666667 1.        ]
0.9800000000000001

调整估计器的超参数

超参数是估计器不明确获取的变量,它们作为参数提供给估计器类的构造函数。在支持向量分类器中,常见的例子是 C、核函数和 gamma、Lasso 的 alpha 等。

在超参数域中搜索最大交叉验证分数是可行且建议的。

我们可以使用此方法在构建估计器时优化任何提供的参数。使用以下函数

获取给定估计器的所有参数的名称和当前值。

搜索的组成部分是:一个估计器函数(例如,回归器或分类器,如 sklearn.svm.SVC())、一个参数字段、一个搜索策略或采样过程、一个交叉验证策略和一个评分函数。

GridSearchCV 使用两种方法:“fit”和“score”。如果用于网格搜索的估计器支持以下任何方法,它也会实现这些方法。这些方法是“score samples”、“predict proba”、“predict”、“transform”和“inverse transform”、“decision function”。

在参数网格上使用交叉验证网格搜索来改进网格搜索策略所使用的估计器的参数。

代码

输出

GridSearchCV(estimator=SVC(),
             param_grid={'C': [1, 20], 'kernel': ('linear', 'poly')})
['mean_fit_time',
 'mean_score_time',
 'mean_test_score',
 'param_C',
 'param_kernel',
 'params',
 'rank_test_score',
 'split0_test_score',
 'split1_test_score',
 'split2_test_score',
 'split3_test_score',
 'split4_test_score',
 'std_fit_time',
 'std_score_time',
 'std_test_score']

我们可以通过执行逐半网格搜索算法来提高 GridSearchCV 的效率。

搜索方法首先分析每个选项的少量元素,然后重复选择最佳选项,并逐步增加元素。

代码

输出

{'max_depth' : None, 'min_samples_split': 10, 'n_estimators': 9}

执行参数搜索时要记住的要点

定义目标指标

参数搜索默认使用估计器的评分函数评估参数配置。对于分类,使用的指标是 sklearn.metrics.accuracy_score,对于回归分析,是 sklearn.metrics.r2_score。其他评分指标可能更适合特定情况。

定义多个评估指标

我们可以使用 GridSearchCV 和 RandomizedSearchCV 函数指定多个评分指标。

多指标评分方法可以作为参数给出,可以是 Python 字典,将评分器的名称映射到评分函数和/或预定义的评分器名称,也可以是预定义评分器名称的字符串集合。

嵌套估计器和参数空间

使用特殊的 <estimator>_<parameter> 语法,GridSearchCV 和 RandomizedSearchCV 允许查找嵌套估计器(如 Pipeline、VotingClassifier、CalibratedClassifierCV 或 ColumnTransformer)的参数。

并行性

参数搜索函数分别评估每个数据子集上的每个参数排列。术语 n_jobs=-1 启用计算的并行处理。

故障鲁棒性

某些参数选择可能导致无法适应一个或多个数据子集。即使算法可能完全评估某些参数值,但这默认会在整个搜索中失败。如果指定 error_score=0(或 =np.NaN),算法将抵抗此类故障,生成警告并将该子集的得分值分配为 0(或 NaN),但完成搜索。

计算预测质量

我们可以使用三种不同的 API 来评估模型对未来的预测能力

估计器评分系统:估计方法具有评分系统,可为其旨在解决的主题提供默认评分标准。这在每个估计器的手册中都有介绍。

  • 评分标准:交叉验证模型评估方法使用内在评分系统,例如 sklearn.model_selection.cross_val_score 和 sklearn.model_selection.GridSearchCV。
  • 度量系统:对于特定用途,sklearn.metrics 模块包含用于测量估计误差的例程。

模型评估技术示例

model_selection.GridSearch() 和 model_selection.cross_val_score() 等函数提供了一个评分参数来定义评分方法。

使用 sklearn.metrics 包含不同的评分方法

代码

输出

Accuracy score for the scoring method 'balanced_accuracy' : 
 [0.95238095 1.         1.         0.95238095 0.95238095 0.95238095
 1.        ]
Accuracy score for the scoring method 'f1_micro' : 
 [0.95454545 1.         1.         0.95238095 0.95238095 0.95238095
 1.        ]

此外,Scikit-learn 的 GridSearchCV、RandomizedSearchCV 和 cross_validate 都支持同时基于多个指标进行评估。

代码

输出

{'fit_time': array([0.00099993, 0.00099993, 0.0150001 , 0.00200009, 0.00199986,
       0.00100017, 0.00100017]), 'score_time': array([0.00099993, 0.00099993, 0.00099993, 0.00200033, 0.00099993,
       0.00099993, 0.00099993]), 'test_accuracy': array([0.95454545, 1.        , 1.        , 0.95238095, 0.95238095,
       0.95238095, 1.        ]), 'test_prec': array([0.9331307 , 1.        , 1.        , 0.92857143, 0.92857143,
       0.92857143, 1.        ])}
{'fit_time': array([0.00099993, 0.00099993, 0.0150001 , 0.00200009, 0.00199986,
       0.00100017, 0.00100017]), 'score_time': array([0.00099993, 0.00099993, 0.00099993, 0.00200033, 0.00099993,
       0.00099993, 0.00099993]), 'test_accuracy': array([0.95454545, 1.        , 1.        , 0.95238095, 0.95238095,
       0.95238095, 1.        ]), 'test_prec': array([0.9331307 , 1.        , 1.        , 0.92857143, 0.92857143,
       0.92857143, 1.        ])}

实现我们自己的评分对象

通过创建我们自己的自定义评分对象而不是使用函数 make_scorer,我们可以构建更适合我们模型的不同评分方法。一个可调用对象必须遵循以下两个原则中概述的过程才能成为评分器

  • 它支持参数调用 (estimator, X, y)。
  • 它通过提供数据返回一个浮点值,该值衡量模型对样本数据集 X 相对于目标变量 y 的预测的准确度得分。

sklearn.metrics 模块还提供了一组简单的例程,用于评估给定预测值和数据集真实值的估计误差。

  • 以 "_score" 结尾的函数返回的预测值的得分值越大,模型越好。
  • 以 "_error" 或 "_loss" 结尾的函数返回的预测值的得分值越小,模型越好。使用 make_scorer 函数将 greater_is_better 参数设置为 False 以创建评分器对象。

验证曲线和学习曲线

我们构建的每个估计器都有其优点和缺点。偏差、方差误差和噪声共同构成了泛化误差。估计器的偏差表示许多训练数据集的平均误差值。估计器的方差揭示了它对不同训练数据集的响应程度。噪声是原始数据的一个特征。

由于偏差和方差是估计器的固有特性,我们通常必须选择学习算法并调整超参数以最小化偏差和方差。向模型添加额外的训练数据集是降低估计器方差的另一种广泛使用的技术。但是,我们只有在估计由于其复杂性而无法很好地以微小变化建模实际函数时才必须收集更多的训练数据。

验证曲线

我们需要一个评分系统,例如分类器准确度函数来评估模型。网格搜索或其他类似策略(用验证数据集的最佳分数调整估计器的超参数)是选择估计器多个超参数的正确方法。请注意,如果超参数是基于验证准确度分数进行调整的,则验证准确度分数是有偏的,不再是泛化的可靠指标。我们必须在不同的测试集上计算准确度分数才能获得泛化的准确近似值。

代码

输出

[[0.93973174 0.9494471  0.94188484 0.9435467  0.94419797 0.94252983
  0.94608803 0.9460067  0.9423957  0.94253182]
 [0.93944487 0.94914898 0.94164577 0.94328439 0.9439338  0.94224685
  0.94584605 0.9457347  0.94212464 0.94227221]
 [0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.        ]]
[[ 0.97300409  0.87636051  0.95494321  0.9417682   0.92512841  0.93081973
   0.91016821  0.91853245  0.94939447  0.9475685 ]
 [ 0.96865934  0.8803329   0.95417121  0.9445263   0.92533163  0.93193911
   0.90834795  0.91843293  0.95295644  0.94553797]
 [-0.01991239 -0.20576132 -0.09876543 -0.01991239 -0.09876543 -0.51981806
  -0.02805836  0.         -0.01991239 -0.01991239]]

如果训练分数的值和验证分数的值都很小,则估计器将欠拟合。如果训练分数的值高于验证分数的值,则估计器过拟合。但是,如果情况相反,则估计器表现良好。通常不可能出现验证分数高而训练分数低的情况。

学习曲线

学习曲线显示了估计器在作为参数给出的不同长度的训练样本上的训练和验证分数。这是一种确定额外训练数据集能有多大帮助以及估计器是否更容易受到偏差或方差误差影响的方法。请看下面的示例,我们展示了 Lasso 分类器的学习曲线。

代码

输出

[[0.50150218 0.43690063 0.5154695  0.51452348 0.51452348 0.51452348
  0.51452348 0.51452348 0.51452348 0.51452348]
 [0.48754102 0.46153892 0.50115233 0.47687368 0.53209581 0.4838794
  0.4838794  0.4838794  0.4838794  0.4838794 ]
 [0.47761141 0.45787213 0.48397355 0.46741065 0.49652965 0.47942832
  0.50579115 0.48615822 0.45051371 0.48083313]]
[[0.43915574 0.33445944 0.38829399 0.50764841 0.45173949 0.15496657
  0.40651899 0.48801649 0.56571766 0.4732054 ]
 [0.44653145 0.42970004 0.4145817  0.4872139  0.43139094 0.21609031
  0.42580156 0.48481259 0.55030939 0.4521308 ]
 [0.43844149 0.40086229 0.43313405 0.46494005 0.38326539 0.23284754
  0.46030724 0.48905027 0.51427695 0.42897388]]