[scikit-learn] 第二章 Model Section

系列文章目录

[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“折”,按照以下步骤进行:

  1. 使用 k - 1 个折叠的数据来训练模型;
  2. 将剩余的数据用作验证集(即,用作测试集来计算性能指标,如准确率)。

​ k折交叉验证报告的性能度量是在循环中计算的值的平均值。这种方法可能会消耗大量计算资源,但不会浪费太多数据(就像固定一个任意的验证集一样),这在样本数量非常小的逆推问题等情况下是一个重大优势。
请添加图片描述

调整估计器的超参数

​ 超参数是在估计器内部不直接学习的参数。在 scikit-learn 中,它们作为参数传递给估计器类的构造函数。典型的例子包括支持向量分类器的 C、kernel 和 gamma,以及 Lasso 的 alpha 等。

​ 推荐的做法是搜索超参数空间,以获得最佳的交叉验证分数。

​ 可以通过这种方式优化构造估计器时提供的任何参数。具体来说,要找到给定估计器的所有参数的名称和当前值,请使用:

estimator.get_params()

一次搜索包括:

  1. 一个估计器(回归器或分类器,例如sklearn.svm.SVC());
  2. 一个参数空间;
  3. 一种搜索或抽样候选项的方法;
  4. 一个交叉验证方案;以及
  5. 一个评分函数。

​ 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())])

# 定义参数网格
param_grid = {'svc__C': [0.1, 1, 10, 100],  # SVM正则化参数
              'svc__gamma': [0.1, 0.01, 0.001, 0.0001],  # RBF核函数的宽度
              'svc__kernel': ['linear', 'rbf', 'poly']}  # SVM的核函数类型

# 定义k折交叉验证
kfold = KFold(n_splits=5, shuffle=True, random_state=42)

# 使用GridSearchCV进行参数调优
grid_search = GridSearchCV(pipe, param_grid, cv=kfold, scoring='accuracy', n_jobs=-1)
grid_search.fit(X, y)

# 输出最佳参数组合
print("Best parameters:", grid_search.best_params_)

# 输出最佳模型的交叉验证得分
print("Best cross-validation score:", grid_search.best_score_)

# 输出每个超参数组合的交叉验证得分
results = grid_search.cv_results_
for mean_score, params in zip(results['mean_test_score'], results['params']):
    print(f"Mean validation score: {mean_score:.3f} with params: {params}")

result:
请添加图片描述

学习曲线

​ 学习曲线展示了估计器在不同数量的训练样本下的验证分数和训练分数。它是一个工具,用于确定我们增加更多训练数据能获得多少收益,以及估计器是否更多地受到方差误差或偏差误差的影响。考虑以下示例,我们绘制了朴素贝叶斯分类器和支持向量机的学习曲线。

​ 对于朴素贝叶斯,随着训练集大小的增加,验证分数和训练分数都收敛到一个相当低的值。因此,我们可能不会从更多的训练数据中获益很多。

​ 相反,对于小量数据,支持向量机的训练分数远远大于验证分数。增加更多的训练样本很可能会增加泛化能力。
请添加图片描述

demo:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import learning_curve
from sklearn.datasets import load_digits
from sklearn.naive_bayes import GaussianNB
from sklearn.svm import SVC

# 加载示例数据集
digits = load_digits()
X, y = digits.data, digits.target

# 定义朴素贝叶斯分类器和支持向量机分类器
nb_classifier = GaussianNB()
svm_classifier = SVC(kernel='linear')

# 定义绘制学习曲线函数
def plot_learning_curve(estimator, title, X, y, ylim=None, cv=None, n_jobs=None, train_sizes=np.linspace(.1, 1.0, 5)):
    plt.figure()
    plt.title(title)
    if ylim is not None:
        plt.ylim(*ylim)
    plt.xlabel("Training examples")
    plt.ylabel("Score")
    train_sizes, train_scores, test_scores = learning_curve(
        estimator, X, y, cv=cv, n_jobs=n_jobs, train_sizes=train_sizes)
    train_scores_mean = np.mean(train_scores, axis=1)
    train_scores_std = np.std(train_scores, axis=1)
    test_scores_mean = np.mean(test_scores, axis=1)
    test_scores_std = np.std(test_scores, axis=1)
    plt.grid()

    plt.fill_between(train_sizes, train_scores_mean - train_scores_std,
                     train_scores_mean + train_scores_std, alpha=0.1,
                     color="r")
    plt.fill_between(train_sizes, test_scores_mean - test_scores_std,
                     test_scores_mean + test_scores_std, alpha=0.1, color="g")
    plt.plot(train_sizes, train_scores_mean, 'o-', color="r",
             label="Training score")
    plt.plot(train_sizes, test_scores_mean, 'o-', color="g",
             label="Cross-validation score")

    plt.legend(loc="best")
    return plt

# 绘制朴素贝叶斯分类器的学习曲线
plot_learning_curve(nb_classifier, "Naive Bayes Learning Curve", X, y, cv=5)
plt.show()

# 绘制支持向量机分类器的学习曲线
plot_learning_curve(svm_classifier, "SVM Learning Curve", X, y, cv=5)
plt.show()

result:
请添加图片描述

库函数介绍:

Splitter Classes:

model_selection.GroupKFold([n_splits]) K-fold iterator variant with non-overlapping groups. n_splits参数含义是将数据集分成多少份。

model_selection.GroupShuffleSplit([...]) Shuffle-Group(s)-Out cross-validation iterator. [...]表示其他可选参数。

model_selection.KFold([n_splits, shuffle, ...]) K-Fold cross-validator. n_splits参数含义是将数据集分成多少份,shuffle参数表示是否在每次划分时打乱数据顺序。

model_selection.LeaveOneGroupOut() Leave One Group Out cross-validator.

model_selection.LeavePGroupsOut(n_groups) Leave P Group(s) Out cross-validator. n_groups参数含义是每次留出的组数。

model_selection.LeaveOneOut() Leave-One-Out cross-validator.

model_selection.LeavePOut(p) Leave-P-Out cross-validator. p参数含义是每次留出的数据点数量。

model_selection.PredefinedSplit(test_fold) Predefined split cross-validator. test_fold参数含义是预定义的测试集划分。

model_selection.RepeatedKFold(*[, n_splits, ...]) Repeated K-Fold cross validator. *表示其他可选参数,n_splits参数含义是将数据集重复分成多少份。

model_selection.RepeatedStratifiedKFold(*[, ...]) Repeated Stratified K-Fold cross validator. *表示其他可选参数。

model_selection.ShuffleSplit([n_splits, ...]) Random permutation cross-validator. n_splits参数含义是将数据集分成多少份。

model_selection.StratifiedKFold([n_splits, ...]) Stratified K-Fold cross-validator. n_splits参数含义是将数据集分成多少份。

model_selection.StratifiedShuffleSplit([...]) Stratified ShuffleSplit cross-validator. [...]表示其他可选参数。

model_selection.StratifiedGroupKFold([...]) Stratified K-Fold iterator variant with non-overlapping groups. [...]表示其他可选参数。

model_selection.TimeSeriesSplit([n_splits, ...]) Time Series cross-validator. n_splits参数含义是将时间序列数据分成多少份。

Splitter Functions

model_selection.check_cv([cv, y, classifier]) Input checker utility for building a cross-validator. cv参数含义是交叉验证器,y参数含义是目标变量,classifier参数含义是分类器。

model_selection.train_test_split(*arrays[, ...]) Split arrays or matrices into random train and test subsets. *arrays表示输入的数组或矩阵,...表示其他可选参数。

Hyper-parameter optimizers
model_selection.GridSearchCV(estimator, ...) Exhaustive search over specified parameter values for an estimator. estimator参数含义是估计器,...表示其他可选参数。

model_selection.HalvingGridSearchCV(...[, ...]) Search over specified parameter values with successive halving. ...[, ...]表示其他可选参数。

model_selection.ParameterGrid(param_grid) Grid of parameters with a discrete number of values for each. param_grid参数含义是参数网格。

model_selection.ParameterSampler(...[, ...]) Generator on parameters sampled from given distributions. ...[, ...]表示其他可选参数。

model_selection.RandomizedSearchCV(...[, ...]) Randomized search on hyper parameters. ...[, ...]表示其他可选参数。

model_selection.HalvingRandomSearchCV(...[, ...]) Randomized search on hyper parameters. ...[, ...]表示其他可选参数。

Model validation

model_selection.cross_validate(estimator, X) Evaluate metric(s) by cross-validation and also record fit/score times. estimator参数含义是估计器,X参数含义是输入数据。

model_selection.cross_val_predict(estimator, X) Generate cross-validated estimates for each input data point. estimator参数含义是估计器,X参数含义是输入数据。

model_selection.cross_val_score(estimator, X) Evaluate a score by cross-validation. estimator参数含义是估计器,X参数含义是输入数据。

model_selection.learning_curve(estimator, X, ...) Learning curve. estimator参数含义是估计器,X参数含义是输入数据,...表示其他可选参数。

model_selection.permutation_test_score(...) Evaluate the significance of a cross-validated score with permutations. ...表示其他可选参数。

model_selection.validation_curve(estimator, ...) Validation curve. estimator参数含义是估计器,...表示其他可选参数。

Visualization

model_selection.LearningCurveDisplay(*, ...) Learning Curve visualization. 表示其他可选参数。

model_selection.ValidationCurveDisplay(*, ...) Validation Curve visualization. 表示其他可选参数。
  • 24
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值