梯度提升正则化

Machine LearningMachine LearningBeginner
立即练习

This tutorial is from open-source community. Access the source code

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在本实验中,你将学习如何使用 scikit-learn 为梯度提升实现不同的正则化策略。正则化是一种有助于防止过拟合的技术,过拟合是机器学习模型中常见的问题。本实验我们将使用二项偏差损失函数和 make_hastie_10_2 数据集。

虚拟机使用小贴士

虚拟机启动完成后,点击左上角切换到“笔记本”标签页,以访问 Jupyter Notebook 进行练习。

有时,你可能需要等待几秒钟让 Jupyter Notebook 完成加载。由于 Jupyter Notebook 的限制,操作验证无法自动化。

如果你在学习过程中遇到问题,随时向 Labby 提问。课程结束后提供反馈,我们会及时为你解决问题。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL sklearn(("Sklearn")) -.-> sklearn/ModelSelectionandEvaluationGroup(["Model Selection and Evaluation"]) ml(("Machine Learning")) -.-> ml/FrameworkandSoftwareGroup(["Framework and Software"]) sklearn/ModelSelectionandEvaluationGroup -.-> sklearn/model_selection("Model Selection") sklearn/ModelSelectionandEvaluationGroup -.-> sklearn/metrics("Metrics") ml/FrameworkandSoftwareGroup -.-> ml/sklearn("scikit-learn") subgraph Lab Skills sklearn/model_selection -.-> lab-49154{{"梯度提升正则化"}} sklearn/metrics -.-> lab-49154{{"梯度提升正则化"}} ml/sklearn -.-> lab-49154{{"梯度提升正则化"}} end

导入库

让我们先导入必要的库。

import numpy as np
import matplotlib.pyplot as plt

from sklearn import ensemble
from sklearn import datasets
from sklearn.metrics import log_loss
from sklearn.model_selection import train_test_split

加载并分割数据

我们将使用 make_hastie_10_2 数据集,并将其分割为训练集和测试集。

X, y = datasets.make_hastie_10_2(n_samples=4000, random_state=1)

## map labels from {-1, 1} to {0, 1}
labels, y = np.unique(y, return_inverse=True)

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.8, random_state=0)

定义参数

我们将为梯度提升分类器定义参数。我们将使用以下参数:

  • n_estimators:要执行的提升阶段数
  • max_leaf_nodes:每棵树中最大的叶节点数
  • max_depth:树的最大深度
  • random_state:用于一致性的随机种子
  • min_samples_split:拆分内部节点所需的最小样本数
original_params = {
    "n_estimators": 400,
    "max_leaf_nodes": 4,
    "max_depth": None,
    "random_state": 2,
    "min_samples_split": 5,
}

实施正则化策略

我们现在将实施不同的正则化策略并比较它们的性能。

无收缩

我们将从无收缩开始,这意味着学习率将设置为 1。

params = dict(original_params)
params.update({"learning_rate": 1.0, "subsample": 1.0})

clf = ensemble.GradientBoostingClassifier(**params)
clf.fit(X_train, y_train)
学习率 = 0.2

接下来,我们将学习率设置为 0.2,子采样设置为 1。

params = dict(original_params)
params.update({"learning_rate": 0.2, "subsample": 1.0})

clf = ensemble.GradientBoostingClassifier(**params)
clf.fit(X_train, y_train)
子采样 = 0.5

我们现在将子采样设置为 0.5,学习率设置为 1。

params = dict(original_params)
params.update({"learning_rate": 1.0, "subsample": 0.5})

clf = ensemble.GradientBoostingClassifier(**params)
clf.fit(X_train, y_train)
学习率 = 0.2 且 子采样 = 0.5

接下来,我们将学习率设置为 0.2,子采样设置为 0.5。

params = dict(original_params)
params.update({"learning_rate": 0.2, "subsample": 0.5})

clf = ensemble.GradientBoostingClassifier(**params)
clf.fit(X_train, y_train)
学习率 = 0.2 且 最大特征数 = 2

最后,我们将学习率设置为 0.2,并且每棵树仅使用 2 个特征。

params = dict(original_params)
params.update({"learning_rate": 0.2, "max_features": 2})

clf = ensemble.GradientBoostingClassifier(**params)
clf.fit(X_train, y_train)

绘制测试集偏差

我们现在将为每种正则化策略绘制测试集偏差。

plt.figure()

for label, color, setting in [
    ("无收缩", "橙色", {"learning_rate": 1.0, "subsample": 1.0}),
    ("learning_rate=0.2", "青绿色", {"learning_rate": 0.2, "subsample": 1.0}),
    ("subsample=0.5", "蓝色", {"learning_rate": 1.0, "subsample": 0.5}),
    (
        "learning_rate=0.2, subsample=0.5",
        "灰色",
        {"learning_rate": 0.2, "subsample": 0.5}
    ),
    (
        "learning_rate=0.2, max_features=2",
        "品红色",
        {"learning_rate": 0.2, "max_features": 2}
    )
]:
    params = dict(original_params)
    params.update(setting)

    clf = ensemble.GradientBoostingClassifier(**params)
    clf.fit(X_train, y_train)

    ## 计算测试集偏差
    test_deviance = np.zeros((params["n_estimators"],), dtype=np.float64)

    for i, y_proba in enumerate(clf.staged_predict_proba(X_test)):
        test_deviance[i] = 2 * log_loss(y_test, y_proba[:, 1])

    plt.plot(
        (np.arange(test_deviance.shape[0]) + 1)[::5],
        test_deviance[::5],
        "-",
        color=color,
        label=label
    )

plt.legend(loc="upper right")
plt.xlabel("提升迭代次数")
plt.ylabel("测试集偏差")

plt.show()

总结

在本实验中,我们学习了如何使用 scikit-learn 为梯度提升实现不同的正则化策略。我们使用了二项偏差损失函数和 make_hastie_10_2 数据集。我们实现了不同的正则化策略,如无收缩、学习率 = 0.2、子采样 = 0.5 以及最大特征数 = 2。最后,我们为每种正则化策略绘制了测试集偏差,以比较它们的性能。