系列文章目录
[scikit-learn] 第一章 初识scikit-learn及内置数据集介绍
文章目录
[scikit-learn] 第二章 Model Section
菜鸡镇贴!!!
Model Section
sklearn.model_selection
模块是 Scikit-learn 库中用于模型选择和评估的核心工具集。该模块提供了用于分割数据集、交叉验证、参数调优和性能评估的功能。本贴主要从交叉验证:评估估计器性能、调整估计器的超参数和学习曲线部分进行介绍。
交叉验证:评估估计器性能
在同一数据上学习预测函数的参数并在该数据上进行测试是一种方法上的错误:一个仅会重复其刚刚见过的样本标签的模型可能会获得完美的分数,但在尚未见过的数据上却无法预测任何有用的信息。这种情况称为过拟合。为了避免这种情况,在执行(监督)机器学习实验时,通常会将部分可用数据保留为测试集 X_test、y_test。请注意,“实验”一词并不仅用于学术用途,因为即使在商业环境中,机器学习通常也是从实验开始的。以下是模型训练中典型交叉验证工作流程的流程图。最佳参数可以通过网格搜索技术确定。
在scikit中,可以使用train_test_split辅助函数快速计算随机划分为训练集和测试集。让我们加载鸢尾数据集,以在其上拟合线性支持向量机:
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn import datasets
from sklearn import svm
// return_X_y=True参数表示返回的数据是分开的。X包含特征数据,y包含对应的标签。
X, y = datasets.load_iris(return_X_y=True)
// test_size=0.4参数指定了测试集占总数据的比例为40%,random_state=0参数确保每次运行代码时得到的随机拆分结果相同。
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4, random_state=0)
// 创建支持向量机分类器对象(SVC),使用线性核(kernel='linear'),正则化参数(C=1)。然后使用训练集(X_train和y_train)对分类器进行训练。
clf = svm.SVC(kernel='linear', C=1).fit(X_train, y_train)
// 使用测试集评估分类器的性能。score()方法返回分类器在测试集上的准确率。
print(clf.score(X_test, y_test))
在评估不同的估算器设置(即“超参数”)时,比如对于 SVM 必须手动设置的 C 参数,仍然存在着在测试集上过度拟合的风险,因为参数可以调整直至估算器表现最佳。这样一来,关于测试集的信息可能会“泄露”到模型中,评估指标也就无法再报告出泛化性能。为了解决这个问题,数据集的另一部分可以被保留作为所谓的“验证集”:先在训练集上进行训练,然后在验证集上进行评估;当实验看起来成功时,最终评估可以在测试集上进行。
然而,将可用数据分成三组会大幅减少可用于模型学习的样本数量,并且结果可能依赖于对(训练、验证)集的特定随机选择。
解决这一问题的方法是一种称为交叉验证(CV)的程序。尽管最终评估仍需保留一个测试集,但在进行CV时不再需要验证集。在基本的k折交叉验证方法中,训练集被分成k个较小的子集(还有其他方法,但通常遵循相同的原则)。对于每一个k“折”,按照以下步骤进行:
- 使用 k - 1 个折叠的数据来训练模型;
- 将剩余的数据用作验证集(即,用作测试集来计算性能指标,如准确率)。
k折交叉验证报告的性能度量是在循环中计算的值的平均值。这种方法可能会消耗大量计算资源,但不会浪费太多数据(就像固定一个任意的验证集一样),这在样本数量非常小的逆推问题等情况下是一个重大优势。
调整估计器的超参数
超参数是在估计器内部不直接学习的参数。在 scikit-learn 中,它们作为参数传递给估计器类的构造函数。典型的例子包括支持向量分类器的 C、kernel 和 gamma,以及 Lasso 的 alpha 等。
推荐的做法是搜索超参数空间,以获得最佳的交叉验证分数。
可以通过这种方式优化构造估计器时提供的任何参数。具体来说,要找到给定估计器的所有参数的名称和当前值,请使用:
estimator.get_params()
一次搜索包括:
- 一个估计器(回归器或分类器,例如sklearn.svm.SVC());
- 一个参数空间;
- 一种搜索或抽样候选项的方法;
- 一个交叉验证方案;以及
- 一个评分函数。
scikit-learn提供了两种通用的参数搜索方法:对于给定的值,GridSearchCV会详尽考虑所有参数组合,而RandomizedSearchCV则可以从指定分布的参数空间中抽取指定数量的候选项。这两种工具都有对应的连续减半版本,即HalvingGridSearchCV和HalvingRandomSearchCV,后者在寻找优秀参数组合时可能更快。
demo:
import numpy as np
from sklearn.datasets import load_iris
from sklearn.model_selection import cross_val_score, GridSearchCV, KFold
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
# 加载数据集
iris = load_iris()
X = iris.data
y = iris.target
# 创建一个SVM分类器的Pipeline
pipe = Pipeline([('scaler', StandardScaler()), ('svc', SVC())]