第十四节-集成算法实验分析(第一章: 机器学习算法精进及其案例应用(课程笔记) )

14.1集成算法实验分析

集成基本思想:

训练时用多种分类器一起完成同一份任务

测试时对待测试样本分别通过不同的分类器,汇总最后的结果

集成学习的基本思想是将多个机器学习模型组合在一起,以提高整体性能和泛化能力。在集成学习中,训练时使用多个分类器一起完成同一份任务,而在测试时,将不同分类器对待测试样本,然后汇总它们的结果以生成最终的预测或决策。这个思想的核心在于通过组合多个模型的意见来降低模型的方差和偏差,从而提高整体性能。

以下是集成学习的基本思想的关键要点:

  1. 多模型组合: 集成学习使用多个不同的机器学习模型,这些模型可以是同一类型的,也可以是不同类型的。通常,这些模型被称为基学习器(Base Learners)或分类器。

  2. 训练阶段: 在训练阶段,每个基学习器都被独立地训练,通常使用不同的训练数据子集、特征子集或模型参数。这确保了基学习器的多样性,它们会捕捉到数据中的不同模式和特征。

  3. 测试阶段: 在测试阶段,对于每个测试样本,通过不同的基学习器分别进行预测或分类。每个基学习器都提供了一个独立的预测结果。

  4. 汇总决策: 最后,通过某种方法(如投票、平均、加权平均等)将不同基学习器的预测结果汇总,生成最终的预测或决策。这个汇总过程有助于降低模型的方差,提高整体性能。

优势和用途:

集成学习的优势包括:

  • 提高模型性能:通过组合多个模型,集成学习可以显著提高性能,特别是在复杂任务或噪声数据情况下。

  • 改善泛化能力:集成学习有助于减少模型的过拟合,提高泛化能力,从而更好地适应新数据。

  • 鲁棒性增强:基学习器之间的差异性可以增强模型的鲁棒性,使其对数据中的噪声和异常值更具抵抗力。

集成学习通常用于各种机器学习任务,包括分类、回归、聚类、特征选择等。一些著名的集成学习方法包括Bagging、Boosting、Stacking、随机森林等。选择合适的集成方法和基学习器取决于任务的性质和数据的特点。总之,集成学习的基本思想是通过多样性和合并多个模型的结果来提高机器学习系统的性能和鲁棒性。

import numpy as np
import os
%matplotlib inline
import matplotlib
import matplotlib.pyplot as plt
plt.rcParams['axes.labelsize'] = 14
plt.rcParams['xtick.labelsize'] = 12
plt.rcParams['ytick.labelsize'] = 12
import warnings
warnings.filterwarnings('ignore')
np.random.seed(42)

from sklearn.model_selection import train_test_split
from sklearn.datasets import make_moons

X,y = make_moons(n_samples=500, noise=0.30, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)

plt.plot(X[:,0][y==0],X[:,1][y==0],'yo',alpha = 0.6)
plt.plot(X[:,0][y==0],X[:,1][y==1],'bs',alpha = 0.6)


14.2-硬投票与软投票效果对比

投票策略:软投票与硬投票

  • 硬投票:直接用类别值,少数服从多数
  • 软投票:各自分类器的概率值进行加权平均
# 硬投票
from sklearn.ensemble import RandomForestClassifier, VotingClassifier  # 从sklearn库中导入随机森林、硬投票分类器
from sklearn.linear_model import LogisticRegression  # 从sklearn库中导入逻辑回归模型
from sklearn.svm import SVC  # 从sklearn库中导入支持向量机模型

# 创建逻辑回归模型,设置随机种子为42
log_clf = LogisticRegression(random_state=42)
# 创建随机森林模型,设置随机种子为42
rnd_clf = RandomForestClassifier(random_state=42)
# 创建支持向量机模型,设置随机种子为42
svm_clf = SVC(random_state=42)

# 创建硬投票分类器,包括逻辑回归、随机森林和支持向量机,采用硬投票策略
voting_clf = VotingClassifier(estimators=[('lr', log_clf), ('rf', rnd_clf), ('svc', svm_clf)], voting='hard')

# 使用训练数据对硬投票分类器进行训练
voting_clf.fit(X_train, y_train)

# 导入准确度评估函数
from sklearn.metrics import accuracy_score

# 遍历每个模型,进行训练和预测,并输出准确度
for clf in (log_clf, rnd_clf, svm_clf, voting_clf):
    clf.fit(X_train, y_train)  # 训练当前模型
    y_pred = clf.predict(X_test)  # 使用测试数据进行预测
    print(clf.__class__.__name__, accuracy_score(y_test, y_pred))  # 输出模型名称和准确度评分
LogisticRegression 0.864
RandomForestClassifier 0.896
SVC 0.896
VotingClassifier 0.912
# 硬投票
from sklearn.ensemble import RandomForestClassifier, VotingClassifier  # 从sklearn库中导入随机森林、硬投票分类器
from sklearn.linear_model import LogisticRegression  # 从sklearn库中导入逻辑回归模型
from sklearn.svm import SVC  # 从sklearn库中导入支持向量机模型

# 创建逻辑回归模型,设置随机种子为42
log_clf = LogisticRegression(random_state=42)
# 创建随机森林模型,设置随机种子为42
rnd_clf = RandomForestClassifier(random_state=42)
# 创建支持向量机模型,设置随机种子为42,同时启用了概率估计
svm_clf = SVC(probability=True, random_state=42)

# 创建软投票分类器,包括逻辑回归、随机森林和支持向量机,采用软投票策略
voting_clf = VotingClassifier(estimators=[('lr', log_clf), ('rf', rnd_clf), ('svc', svm_clf)], voting='soft')

# 使用训练数据对软投票分类器进行训练
voting_clf.fit(X_train, y_train)

# 导入准确度评估函数
from sklearn.metrics import accuracy_score

# 遍历每个模型,进行训练和预测,并输出准确度
for clf in (log_clf, rnd_clf, svm_clf, voting_clf):
    clf.fit(X_train, y_train)  # 训练当前模型
    y_pred = clf.predict(X_test)  # 使用测试数据进行预测
    print(clf.__class__.__name__, accuracy_score(y_test, y_pred))  # 输出模型名称和准确度评分
LogisticRegression 0.864
RandomForestClassifier 0.872
SVC 0.888
VotingClassifier 0.912

硬投票和软投票是集成学习中两种不同的投票策略。下面是对它们的效果对比的简要概括:

  1. 硬投票

    • 硬投票策略只考虑每个模型的类别预测结果,以多数票决定最终的预测结果。
    • 在给定的数据集上,逻辑回归、随机森林和支持向量机模型分别达到的准确度分别为0.864、0.872和0.888。
    • 硬投票集成模型的准确度为0.896,略高于单个模型中的最高准确度(SVC)。
  2. 软投票

    • 软投票策略不仅考虑每个模型的类别预测结果,还考虑了它们的类别概率估计。
    • 在给定的数据集上,逻辑回归、随机森林和支持向量机模型分别达到的准确度分别为0.864、0.872和0.888(与硬投票相同)。
    • 软投票集成模型的准确度为0.912,比硬投票集成模型的准确度更高。
    • 软投票:要求必须各个分别器都能得出概率值

总结:软投票通常比硬投票效果更好,因为它不仅考虑了模型的预测结果,还利用了类别概率信息,这可以提供更多的信息以做出更准确的决策。在这个特定的数据集上,软投票集成模型表现出更高的准确度,强调了在某些情况下,软投票策略可能会产生更好的结果。但需要注意的是,投票策略的效果还受到模型的性能和数据集的特性等因素的影响,不同情况下可能会有不同的表现。


14.3-Bagging策略效果

Bagging策略

  • 首先对训练数据集进行多次采样,保证每次得到的采样数据都是不同的
  • 分别训练多个模型,例如树模型
  • 预测时需得到所有模型结果再进行集成

# 导入所需的库和类
from sklearn.ensemble import BaggingClassifier  # 从sklearn库中导入Bagging分类器
from sklearn.tree import DecisionTreeClassifier  # 从sklearn库中导入决策树分类器

# 创建Bagging分类器,基分类器为决策树,包括以下参数设置:
# - n_estimators:使用500个基分类器
# - max_samples:每个基分类器随机采样100个样本
# - bootstrap:采用自助采样方式
# - n_jobs:并行处理,使用所有可用CPU核心
# - random_state:随机种子,确保结果的可重复性
bag_clf = BaggingClassifier(DecisionTreeClassifier(),
                  n_estimators=500,
                  max_samples=100,
                  bootstrap=True,
                  n_jobs=-1,
                  random_state=42
)

# 使用训练数据对Bagging分类器进行训练
bag_clf.fit(X_train, y_train)

# 使用Bagging分类器对测试数据进行预测
y_pred = bag_clf.predict(X_test)

# 计算Bagging分类器的准确度分数
accuracy_score(y_test, y_pred)

# 创建单独的决策树分类器,设置随机种子为42
tree_clf = DecisionTreeClassifier(random_state=42)

# 使用训练数据对单独的决策树分类器进行训练
tree_clf.fit(X_train, y_train)

# 使用单独的决策树分类器对测试数据进行预测
y_pred_tree = tree_clf.predict(X_test)

# 计算单独决策树分类器的准确度分数
accuracy_score(y_test, y_pred_tree)

Bagging(Bootstrap Aggregating)策略是一种集成学习方法,通过对多个基分类器的结果进行投票或平均来提高整体模型性能。以下是对Bagging策略和效果的简要概括,结合你提供的代码执行结果:

  1. Bagging策略

    • Bagging分类器使用了Bootstrap采样方法,即随机有放回地从训练数据中抽取多个子样本,然后对每个子样本训练一个基分类器(这里使用了500个基分类器)。
    • 每个基分类器都是决策树分类器。
    • 最终的预测结果是这些基分类器的投票结果,因为采用了硬投票策略。
  2. 效果对比

    • Bagging分类器的准确度分数为0.904,相对较高。
    • 单独的决策树分类器的准确度分数为0.856,相对较低。

总结:Bagging策略通过使用多个基分类器的投票结果来改善模型性能,特别是在处理复杂数据集时,它可以减少过拟合风险。与单独的决策树相比,Bagging分类器的准确度更高,这表明Bagging策略在这个问题上效果更好,提高了模型的鲁棒性和泛化能力。Bagging策略的一个重要特点是它可以并行处理,因此在大型数据集上也能够高效地运行。


14.4-集成效果展示分析

决策边界

  • 集成与传统方法对比
# 导入所需的库和模块
from matplotlib.colors import ListedColormap
import numpy as np
import matplotlib.pyplot as plt

# 定义一个函数,用于绘制决策边界
def plot_decision_boundary(clf, X, y, axes=[-1.5, 2.5, -1, 1.5], alpha=0.5, contour=True):
    # 创建一组 x1 和 x2 坐标点
    x1s = np.linspace(axes[0], axes[1], 100)
    x2s = np.linspace(axes[2], axes[3], 100)
    x1, x2 = np.meshgrid(x1s, x2s)
    X_new = np.c_[x1.ravel(), x2.ravel()]
    
    # 对坐标点进行预测
    y_pred = clf.predict(X_new).reshape(x1.shape)
    
    # 自定义颜色映射
    custom_cmap = ListedColormap(['#fafab0', '#9898ff', '#a0faa0'])
    
    # 绘制决策边界的背景颜色
    plt.contourf(x1, x2, y_pred, cmap=custom_cmap, alpha=0.3)
    
    # 绘制决策边界的轮廓线
    if contour:
        custom_cmap2 = ListedColormap(['#7d7d58', '#4c4c7f', '#507d50'])
        plt.contour(x1, x2, y_pred, cmap=custom_cmap2, alpha=0.8)
    
    # 绘制训练数据点
    plt.plot(X[:, 0][y == 0], X[:, 1][y == 0], 'yo', alpha=0.6)
    plt.plot(X[:, 0][y == 1], X[:, 1][y == 1], 'bs', alpha=0.6)
    
    # 设置坐标轴范围和标签
    plt.axis(axes)
    plt.xlabel('x1')
    plt.ylabel('x2')

# 创建一个图形窗口
plt.figure(figsize=(12, 5))

# 在第一个子图中绘制单独的决策树的决策边界
plt.subplot(121)
plot_decision_boundary(tree_clf, X, y)
plt.title('Decision Tree')

# 在第二个子图中绘制使用Bagging的决策树的决策边界
plt.subplot(122)
plot_decision_boundary(bag_clf, X, y)
plt.title('Decision Tree With Bagging')

Colormap颜色:matplotlib.colors(ListedColormap)_listedcolormap导入_为知教育的博客-CSDN博客

  1. 单独的决策树(左图):

    • 单独的决策树在每个决策边界处形成了尖锐的、不规则的分界线。
    • 这种情况下,单独的决策树容易受到数据中的噪声和小波动的影响,可能导致过拟合。
  2. 使用Bagging的决策树(右图):

    • 使用Bagging的决策树产生了更平滑、更一致的决策边界。
    • 集成的决策边界能够更好地捕捉数据中的整体模式,对噪声更加鲁棒。
    • 这种平滑效果是由于Bagging集成了多个决策树的预测结果,通过投票产生最终的预测,降低了单个决策树的方差。

总结:使用Bagging集成策略的决策树相对于单独的决策树具有更好的泛化能力,它能够更好地适应复杂的数据分布并减少过拟合的风险。通过多次随机采样和集成投票,Bagging减小了决策树模型的方差,提高了整体模型的性能和稳定性。这个可视化效果清楚地展示了集成方法的优势,尤其在处理复杂数据时,Bagging策略能够产生更平滑的决策边界,更好地捕捉数据的真实模式。

14.5-OOB袋外数据的作用

OOB策略

  • Out Of Bag
# 导入所需的库和模块
from sklearn.ensemble import BaggingClassifier  # 从sklearn库中导入Bagging分类器
from sklearn.tree import DecisionTreeClassifier  # 从sklearn库中导入决策树分类器

# 创建Bagging分类器,基分类器为决策树,包括以下参数设置:
# - n_estimators:使用500个基分类器
# - max_samples:每个基分类器随机采样100个样本
# - bootstrap:采用自助采样方式
# - n_jobs:并行处理,使用所有可用CPU核心
# - random_state:随机种子,确保结果的可重复性
# - oob_score:开启out-of-bag(OOB)评估
bag_clf = BaggingClassifier(DecisionTreeClassifier(),
                  n_estimators=500,
                  max_samples=100,
                  bootstrap=True,
                  n_jobs=-1,
                  random_state=42,
                  oob_score=True
)

# 使用训练数据对Bagging分类器进行训练
bag_clf.fit(X_train, y_train)

# 输出Bagging分类器的out-of-bag(OOB)准确度评分
bag_clf.oob_score_

# bag_clf.oob_score_ = 0.9253333333333333

# 使用Bagging分类器对测试数据进行预测
y_pred = bag_clf.predict(X_test)

# 计算Bagging分类器在测试数据上的准确度分数
accuracy_score(y_test, y_pred)

# accuracy_score(y_test, y_pred) = 0.904

# 获取Bagging分类器的out-of-bag(OOB)决策函数值
bag_clf.oob_decision_function_


14.6-特征重要性热度图展示

随机森林

from sklearn.ensemble import RandomForestClassifier
rf_clf = RandomForestClassifier()
rf_clf.fit(X_train,y_train)

特征重要性:

sklearn中是看每个特征的平均深度

from sklearn.datasets import load_iris
iris = load_iris()
rf_clf = RandomForestClassifier(n_estimators=500,n_jobs=-1)
rf_clf.fit(iris['data'],iris['target'])
for name,score in zip(iris['feature_names'],rf_clf.feature_importances_):
    print (name,score)
# 导入所需的库和模块
from sklearn.datasets import fetch_mldata  # 从sklearn库中导入fetch_mldata函数
from sklearn.ensemble import RandomForestClassifier  # 从sklearn库中导入随机森林分类器
import matplotlib.pyplot as plt  # 导入matplotlib库中的绘图模块
import matplotlib  # 导入matplotlib库

# 使用fetch_mldata函数加载MNIST数据集
mnist = fetch_mldata('MNIST original')

# 创建一个随机森林分类器,包括以下参数设置:
# - n_estimators:使用500个决策树
# - n_jobs:使用所有可用CPU核心并行处理
rf_clf = RandomForestClassifier(n_estimators=500, n_jobs=-1)

# 使用MNIST数据集的图像数据和标签进行训练
rf_clf.fit(mnist['data'], mnist['target'])

# 查看随机森林分类器的特征重要性数组的形状
rf_clf.feature_importances_.shape
# (784,)

# 定义一个函数,用于绘制MNIST数字图像
def plot_digit(data):
    image = data.reshape(28, 28)  # 将数据转换为28x28像素的图像
    plt.imshow(image, cmap=matplotlib.cm.hot)  # 使用热图颜色映射绘制图像
    plt.axis('off')  # 不显示坐标轴

# 调用plot_digit函数绘制特征重要性图像
plot_digit(rf_clf.feature_importances_)

# 创建颜色栏并设置刻度标签
char = plt.colorbar(ticks=[rf_clf.feature_importances_.min(), rf_clf.feature_importances_.max()])
char.ax.set_yticklabels(['不重要', '非常重要'])

这段代码的目标是生成特征重要性热度图,以下是对特征重要性热度图的简要概括:

  • 特征重要性热度图是一种可视化表示,用于显示随机森林分类器对每个特征(在这里是图像像素)的重要性程度。
  • 随机森林模型通过测量每个特征在数据集分割中的贡献来计算特征重要性。更重要的特征在分裂数据时被更频繁地选取,从而影响模型的性能。
  • 在代码中,rf_clf.feature_importances_包含了每个像素特征的重要性分数,该分数用于绘制热度图。
  • 热度图使用不同的颜色表示不同程度的重要性。在热度图中,颜色越亮表示特征越重要,颜色越暗表示特征越不重要。
  • plot_digit函数用于将一维特征重要性数组重塑为28x28像素的图像,然后使用热图颜色映射来绘制图像。
  • 最后,颜色栏帮助解释热度图的颜色,显示了特征重要性的范围,从“不重要”到“非常重要”。

综上所述,特征重要性热度图是一种直观的工具,用于理解模型对不同特征的依赖程度,可以帮助我们识别对分类任务最为关键的特征。在这个示例中,热度图显示了哪些像素对于手写数字识别的决策最为关键。


14.7-Adaboost算法概述

Boosting-提升策略

AdaBoost

跟上学时的考试一样,这次做错的题,是不是得额外注意,下次的时候就和别错了!

Adaboost(Adaptive Boosting) 是一种集成学习算法,属于Boosting(提升策略)家族的一部分。Boosting是一种将弱学习器(也称为基学习器)组合成强学习器的机器学习方法。Adaboost具有以下主要特点和概述:

  1. 目标

    • Adaboost的主要目标是将多个弱学习器组合成一个强学习器,以提高整体模型的性能。
  2. 权重分配

    • 在Adaboost中,每个训练样本都会被赋予一个权重,初始时,所有样本的权重相等。
    • 在每一轮的训练中,Adaboost会调整权重,将上一轮分类错误的样本赋予更高的权重,以便下一轮更关注这些难以分类的样本。
  3. 迭代训练

    • Adaboost是一个迭代算法,它通过反复训练弱学习器,每一轮都调整样本的权重,以改善模型的性能。
    • 弱学习器通常是简单的模型,如决策树桩(仅包含一层决策树)。
  4. 加权组合

    • 弱学习器的输出通过加权组合来构建最终的预测结果。每个弱学习器的权重取决于其在训练过程中的性能,性能越好的学习器权重越高。
  5. 自适应性

    • Adaboost是自适应的,它可以适应不同类型的数据和问题,因为它在每一轮训练中都更关注那些被错误分类的样本。
  6. 强分类器

    • 最终的组合模型是多个弱学习器的线性组合,但具有较强的整体性能。
    • Adaboost通常在分类问题上表现出色,但也可以应用于回归问题。
  7. 容易受到噪声干扰

    • Adaboost对噪声数据敏感,因此需要对数据进行预处理和去噪处理。

总之,Adaboost是一种强大的集成学习算法,通过迭代训练和动态权重调整,将多个弱学习器组合成一个性能较好的强学习器。它在实际应用中广泛用于图像分类、人脸检测、文本分类等各种机器学习任务中,并且具有很好的泛化性能。

14.8-Adaboost决策边界效果

以SVM分类器为例来演示AdaBoost的基本策略

# 导入所需的库和模块
from sklearn.svm import SVC  # 从sklearn库中导入支持向量机分类器
import matplotlib.pyplot as plt  # 导入matplotlib库的绘图模块
import numpy as np

# 获取训练数据集的样本数量
m = len(X_train)

# 创建一个图形窗口,包括两个子图
plt.figure(figsize=(14, 5))

# 针对不同的学习率(learning_rate)分别进行可视化
for subplot, learning_rate in ((121, 1), (122, 0.5)):
    sample_weights = np.ones(m)  # 初始化样本权重,初始时所有样本的权重相等
    plt.subplot(subplot)
    
    # 迭代训练5轮
    for i in range(5):
        svm_clf = SVC(kernel='rbf', C=0.05, random_state=42)  # 创建一个RBF核的支持向量机分类器
        svm_clf.fit(X_train, y_train, sample_weight=sample_weights)  # 使用当前样本权重进行训练
        y_pred = svm_clf.predict(X_train)  # 对训练数据进行预测
        sample_weights[y_pred != y_train] *= (1 + learning_rate)  # 调整错误分类样本的权重
        plot_decision_boundary(svm_clf, X, y, alpha=0.2)  # 绘制决策边界,alpha表示透明度
        plt.title('learning_rate = {}'.format(learning_rate))  # 设置子图标题

    if subplot == 121:
        # 在第一个子图中添加文本标签
        plt.text(-0.7, -0.65, "1", fontsize=14)
        plt.text(-0.6, -0.10, "2", fontsize=14)
        plt.text(-0.5,  0.10, "3", fontsize=14)
        plt.text(-0.4,  0.55, "4", fontsize=14)
        plt.text(-0.3,  0.90, "5", fontsize=14)

# 显示图形窗口
plt.show()

# 导入所需的库和模块
from sklearn.ensemble import AdaBoostClassifier  # 从sklearn库中导入AdaBoost分类器
from sklearn.tree import DecisionTreeClassifier  # 从sklearn库中导入决策树分类器

# 创建AdaBoost分类器,包括以下参数设置:
# - 使用决策树桩作为基分类器(每个决策树仅包含一层)
# - n_estimators:使用200个基分类器
# - learning_rate:学习率设置为0.5
# - random_state:随机种子,确保结果的可重复性
ada_clf = AdaBoostClassifier(DecisionTreeClassifier(max_depth=1),
                   n_estimators=200,
                   learning_rate=0.5,
                   random_state=42
)

# 使用训练数据对AdaBoost分类器进行训练
ada_clf.fit(X_train, y_train)

# 调用plot_decision_boundary函数绘制AdaBoost分类器的决策边界
plot_decision_boundary(ada_clf, X, y)

以上两段代码示范了AdaBoost(自适应提升)算法的基本策略和效果:

基本策略

  1. 基本分类器选择:AdaBoost使用弱学习器(在这里是决策树桩),通常是简单的模型,以构建强学习器。这些弱学习器在每一轮迭代中被训练,然后根据它们的性能来分配权重。

  2. 权重调整:AdaBoost通过调整每个样本的权重,使错误分类的样本在下一轮训练中受到更多关注。这样,AdaBoost可以侧重于难以分类的样本,从而提高整体性能。

  3. 迭代训练:AdaBoost是一个迭代算法,它反复训练弱学习器,每一轮都根据上一轮的性能来调整样本权重。这使得模型能够适应复杂的数据分布。

效果

通过绘制AdaBoost分类器的决策边界图,我们可以看到以下效果:

  • AdaBoost在训练后产生了一个复杂的决策边界,它能够很好地适应数据的非线性结构。
  • AdaBoost通过组合多个弱学习器,形成了一个性能强大的强学习器,它在处理复杂数据时表现出色。
  • 强学习器的决策边界是多个弱学习器的加权组合,因此具有较高的准确性和泛化能力。
  • AdaBoost的自适应性使其能够对难以分类的样本进行更多关注,从而提高了模型对噪声和复杂数据的鲁棒性。

总之,AdaBoost是一种强大的集成学习算法,通过迭代训练和权重调整,将多个弱学习器组合成一个性能强大的强学习器,适用于各种分类问题,尤其在处理复杂数据和非线性结构时表现出色。

14.9-GBDT提升算法流程

Gradient Boosting

# 导入所需的库和模块
import numpy as np  # 导入NumPy库
from sklearn.tree import DecisionTreeRegressor  # 从sklearn库中导入决策树回归器

# 设置随机种子以确保结果的可重复性
np.random.seed(42)

# 生成随机数据集X和目标值y
X = np.random.rand(100, 1) - 0.5  # 生成100个随机数,范围在[-0.5, 0.5]之间
y = 3 * X[:, 0]**2 + 0.05 * np.random.randn(100)  # 基于X生成y,带有一些随机噪声

# 创建第一个决策树回归器,设置最大深度为2,并将其与数据集拟合
tree_reg1 = DecisionTreeRegressor(max_depth=2)
tree_reg1.fit(X, y)

# 计算第二个目标值y2,用于训练第二个决策树回归器
y2 = y - tree_reg1.predict(X)

# 创建第二个决策树回归器,设置最大深度为2,并将其与数据集拟合
tree_reg2 = DecisionTreeRegressor(max_depth=2)
tree_reg2.fit(X, y2)

# 计算第三个目标值y3,用于训练第三个决策树回归器
y3 = y2 - tree_reg2.predict(X)

# 创建第三个决策树回归器,设置最大深度为2,并将其与数据集拟合
tree_reg3 = DecisionTreeRegressor(max_depth=2)
tree_reg3.fit(X, y3)

# 创建新的数据点X_new,并使用三个决策树回归器的预测值加和以进行预测
X_new = np.array([[0.8]])  # 新数据点
y_pred = sum(tree.predict(X_new) for tree in (tree_reg1, tree_reg2, tree_reg3))

# 输出预测结果
# y_pred = array([0.75026781])

梯度提升决策树(Gradient Boosting Decision Trees,简称GBDT)是一种集成学习算法,用于解决回归和分类问题。以下是GBDT算法的基本流程:

  1. 初始化

    • 使用基础模型(通常是一个简单的回归模型,如平均值)初始化模型的预测值。这个初始预测值作为梯度提升的起点。
  2. 迭代训练

    • 对于每一轮迭代:
      • 计算当前模型的梯度。梯度表示了损失函数相对于模型预测值的变化情况。
      • 使用梯度信息拟合一个新的基础模型(通常是回归树或分类树)。这个基础模型的目标是减小损失函数的梯度。
      • 计算一个学习率(通常较小),控制每轮迭代的步长,以避免过拟合。
      • 使用学习率乘以新模型的预测值(即模型的输出),然后将这个值加到前一轮模型的预测值上,更新模型的预测。
      • 重复上述步骤,进行多轮迭代,每一轮都试图减小损失函数的梯度,逐渐改进模型的性能。
  3. 停止条件

    • 可以设定停止条件,如迭代次数达到预定值或梯度的大小足够小。当满足停止条件时,停止迭代。
  4. 生成最终模型

    • 将所有基础模型的预测值加权组合,得到最终的梯度提升模型。
    • 这个加权组合通常通过学习率来调整,以平衡不同基础模型的影响。
  5. 预测

    • 使用训练好的梯度提升模型进行新数据的预测。

GBDT的关键思想在于通过迭代,逐渐改进模型的性能,每一轮迭代都试图减小损失函数的梯度,从而使模型更加拟合训练数据。这使得GBDT在处理复杂数据和非线性关系时表现出色,成为一种强大的机器学习算法。GBDT在实际应用中广泛用于回归、分类和排名等各种任务。


14.10-集成参数对比分析

# 导入所需的库和模块
import numpy as np  # 导入NumPy库
import matplotlib.pyplot as plt  # 导入matplotlib库的绘图模块

# 定义绘制预测结果的函数
def plot_predictions(regressors, X, y, axes, label=None, style="r-", data_style="b.", data_label=None):
    # 创建X坐标轴的数据点
    x1 = np.linspace(axes[0], axes[1], 500)
    # 计算所有模型的预测值加和
    y_pred = sum(regressor.predict(x1.reshape(-1, 1)) for regressor in regressors)
    
    # 绘制训练数据的散点图
    plt.plot(X[:, 0], y, data_style, label=data_label)
    # 绘制模型的预测曲线
    plt.plot(x1, y_pred, style, linewidth=2, label=label)
    
    # 添加图例
    if label or data_label:
        plt.legend(loc="upper center", fontsize=16)
    plt.axis(axes)

# 创建一个大图,包括多个子图
plt.figure(figsize=(11, 11))

# 第一个子图:显示第一个决策树模型的预测结果和残差
plt.subplot(321)
plot_predictions([tree_reg1], X, y, axes=[-0.5, 0.5, -0.1, 0.8], label="$h_1(x_1)$", style="g-", data_label="Training set")
plt.ylabel("$y$", fontsize=16, rotation=0)
plt.title("Residuals and tree predictions", fontsize=16)

# 第二个子图:显示第一个决策树模型的整体预测结果
plt.subplot(322)
plot_predictions([tree_reg1], X, y, axes=[-0.5, 0.5, -0.1, 0.8], label="$h(x_1) = h_1(x_1)$", data_label="Training set")
plt.ylabel("$y$", fontsize=16, rotation=0)
plt.title("Ensemble predictions", fontsize=16)

# 第三个子图:显示第二个决策树模型的预测结果和残差
plt.subplot(323)
plot_predictions([tree_reg2], X, y2, axes=[-0.5, 0.5, -0.5, 0.5], label="$h_2(x_1)$", style="g-", data_style="k+", data_label="Residuals")
plt.ylabel("$y - h_1(x_1)$", fontsize=16)

# 第四个子图:显示前两个决策树模型的整体预测结果
plt.subplot(324)
plot_predictions([tree_reg1, tree_reg2], X, y, axes=[-0.5, 0.5, -0.1, 0.8], label="$h(x_1) = h_1(x_1) + h_2(x_1)$")
plt.ylabel("$y$", fontsize=16, rotation=0)

# 第五个子图:显示第三个决策树模型的预测结果和残差
plt.subplot(325)
plot_predictions([tree_reg3], X, y3, axes=[-0.5, 0.5, -0.5, 0.5], label="$h_3(x_1)$", style="g-", data_style="k+")
plt.ylabel("$y - h_1(x_1) - h_2(x_1)$", fontsize=16)
plt.xlabel("$x_1$", fontsize=16)

# 第六个子图:显示前三个决策树模型的整体预测结果
plt.subplot(326)
plot_predictions([tree_reg1, tree_reg2, tree_reg3], X, y, axes=[-0.5, 0.5, -0.1, 0.8], label="$h(x_1) = h_1(x_1) + h_2(x_1) + h_3(x_1)$")
plt.xlabel("$x_1$", fontsize=16)
plt.ylabel("$y$", fontsize=16, rotation=0)

# 显示图形窗口
plt.show()

以上代码和生成的图像展示了梯度提升回归模型的逐步迭代过程以及不同集成参数的对比分析。下面是对不同部分的简要概括:

  1. 第一个子图

    • 这个子图显示了第一个决策树模型(最大深度为2)的预测结果,以及训练数据的散点图。
    • 模型的预测结果较为简单,对训练数据的拟合不够好,存在一定的偏差。
  2. 第二个子图

    • 第二个子图显示了第一个决策树模型的整体预测结果,即只有一个模型的集成。
    • 整体预测结果仍然较为简单,与第一个模型的预测一致。
  3. 第三个子图

    • 这个子图显示了第二个决策树模型(最大深度为2)的预测结果,以及残差(实际值减去第一个模型的预测值)的散点图。
    • 模型的预测结果针对第一个模型的残差,试图进一步减小误差,捕捉到了部分残差信息。
  4. 第四个子图

    • 第四个子图显示了前两个决策树模型的整体预测结果的集成。
    • 整体预测结果相对于单个模型已经有了一定的改进,更好地拟合了训练数据。
  5. 第五个子图

    • 这个子图显示了第三个决策树模型(最大深度为2)的预测结果,以及残差(前两个模型的预测值减去实际值)的散点图。
    • 模型的预测结果进一步减小了残差,尝试捕捉之前模型未能拟合的部分信息。
  6. 第六个子图

    • 第六个子图显示了前三个决策树模型的整体预测结果的集成。
    • 整体预测结果相对于前两个模型进一步改进,更好地拟合了训练数据。

综合来看,梯度提升回归模型通过迭代训练多个基础模型,并将它们的预测结果逐步加和,不断改进了对训练数据的拟合效果。这个集成方法通过纠正前一个模型的残差来逐渐改善整体模型的性能,从而实现了强大的非线性拟合能力。模型的性能随着迭代次数的增加而提高,集成参数的调整可以影响模型的性能,以平衡拟合和泛化的需求。

# 导入所需的库和模块
from sklearn.ensemble import GradientBoostingRegressor  # 导入梯度提升回归模型
import matplotlib.pyplot as plt  # 导入matplotlib库的绘图模块

# 创建一个梯度提升回归模型 gbrt,设置模型参数
gbrt = GradientBoostingRegressor(max_depth=2,  # 决策树最大深度
                                 n_estimators=3,  # 基础模型的数量
                                 learning_rate=1.0,  # 学习率
                                 random_state=41  # 随机种子,以确保结果可重复
                                )

# 使用训练数据 X 和目标值 y 训练梯度提升回归模型
gbrt.fit(X, y)

# 创建另一个梯度提升回归模型 gbrt_slow_1,设置不同的学习率
gbrt_slow_1 = GradientBoostingRegressor(max_depth=2,
                                       n_estimators=3,
                                       learning_rate=0.1,
                                       random_state=41
                                      )

# 使用训练数据 X 和目标值 y 训练慢学习率的梯度提升回归模型
gbrt_slow_1.fit(X, y)

# 创建另一个梯度提升回归模型 gbrt_slow_2,设置更多的基础模型数量和相同的学习率
gbrt_slow_2 = GradientBoostingRegressor(max_depth=2,
                                       n_estimators=200,
                                       learning_rate=0.1,
                                       random_state=41
                                      )

# 使用训练数据 X 和目标值 y 训练慢学习率的梯度提升回归模型
gbrt_slow_2.fit(X, y)

# 创建两个子图,分别用于显示不同模型的预测结果
plt.figure(figsize=(11, 4))

# 第一个子图:显示学习率为1.0、基础模型数量为3的梯度提升模型的预测结果
plt.subplot(121)
plot_predictions([gbrt], X, y, axes=[-0.5, 0.5, -0.1, 0.8], label='集成模型预测')
plt.title('学习率={}, 基础模型数量={}'.format(gbrt.learning_rate, gbrt.n_estimators))

# 第二个子图:显示学习率为0.1、基础模型数量为3的梯度提升模型的预测结果
plt.subplot(122)
plot_predictions([gbrt_slow_1], X, y, axes=[-0.5, 0.5, -0.1, 0.8], label='集成模型预测')
plt.title('学习率={}, 基础模型数量={}'.format(gbrt_slow_1.learning_rate, gbrt_slow_1.n_estimators))

# 创建两个子图,分别用于显示不同模型的预测结果
plt.figure(figsize=(11, 4))

# 第一个子图:显示学习率为0.1、基础模型数量为200的梯度提升模型的预测结果
plt.subplot(121)
plot_predictions([gbrt_slow_2], X, y, axes=[-0.5, 0.5, -0.1, 0.8], label='集成模型预测')
plt.title('学习率={}, 基础模型数量={}'.format(gbrt_slow_2.learning_rate, gbrt_slow_2.n_estimators))

# 第二个子图:显示学习率为0.1、基础模型数量为3的梯度提升模型的预测结果(重复)
plt.subplot(122)
plot_predictions([gbrt_slow_1], X, y, axes=[-0.5, 0.5, -0.1, 0.8], label='集成模型预测')
plt.title('学习率={}, 基础模型数量={}'.format(gbrt_slow_1.learning_rate, gbrt_slow_1.n_estimators))

# 显示图形窗口
plt.show()

这段代码通过创建不同学习率和基础模型数量的梯度提升回归模型,以及展示它们的预测结果的图像,进行了集成参数对比分析。以下是对不同模型和参数的简要概括:

  1. 第一个子图

    • 这个子图显示了学习率为1.0、基础模型数量为3的梯度提升模型的预测结果。
    • 学习率为1.0意味着模型迭代中每个基础模型的权重都很大,模型能够快速适应训练数据。
    • 基础模型数量较少,预测结果相对不稳定。
  2. 第二个子图

    • 这个子图显示了学习率为0.1、基础模型数量为3的梯度提升模型的预测结果。
    • 学习率为0.1意味着模型迭代中每个基础模型的权重较小,模型需要更多的迭代次数才能适应训练数据。
    • 基础模型数量较少,模型的预测结果相对平滑,对训练数据欠拟合。
  3. 第三个子图

    • 这个子图显示了学习率为0.1、基础模型数量为200的梯度提升模型的预测结果。
    • 学习率为0.1仍然保持较小,但基础模型数量较多,模型具有更强的拟合能力。
    • 预测结果非常平滑,对训练数据的拟合效果非常好,但也可能存在过拟合的风险。

通过对比这三个子图,可以看出学习率和基础模型数量对梯度提升模型的预测结果产生重要影响。较大的学习率和较少的基础模型数量会导致模型更快地适应数据,但可能过拟合。适当降低学习率并增加基础模型数量可以获得更平滑且更稳定的预测结果,提高模型的泛化能力。因此,在实际应用中,需要根据数据和问题的特性选择合适的集成参数,以获得最佳性能。

14.11-模型提前停止策略

# 导入所需的库和模块
from sklearn.metrics import mean_squared_error  # 导入均方误差评估指标
from sklearn.model_selection import train_test_split  # 导入数据集划分工具

# 划分数据集为训练集和验证集
X_train, X_val, y_train, y_val = train_test_split(X, y, random_state=49)

# 创建梯度提升回归模型 gbrt,设置模型参数
gbrt = GradientBoostingRegressor(max_depth=2,  # 决策树最大深度
                                 n_estimators=120,  # 基础模型的数量
                                 random_state=42  # 随机种子,以确保结果可重复
                                )

# 使用训练数据 X_train 和目标值 y_train 训练梯度提升回归模型
gbrt.fit(X_train, y_train)

# 计算每个基础模型在验证集上的均方误差,并保存到列表 errors 中
errors = [mean_squared_error(y_val, y_pred) for y_pred in gbrt.staged_predict(X_val)]

# 找到均方误差最小的基础模型数量 bst_n_estimators 的索引
bst_n_estimators = np.argmin(errors)

# 创建梯度提升回归模型 gbrt_best,使用均方误差最小的基础模型数量
gbrt_best = GradientBoostingRegressor(max_depth=2,
                                      n_estimators=bst_n_estimators,
                                      random_state=42
                                     )

# 使用训练数据 X_train 和目标值 y_train 训练最佳模型
gbrt_best.fit(X_train, y_train)

# 计算最小均方误差
min_error = np.min(errors)
min_error

# 绘制两个子图,展示均方误差和最佳模型的预测结果
plt.figure(figsize=(11, 4))

# 第一个子图:展示均方误差随基础模型数量的变化
plt.subplot(121)
plt.plot(errors, 'b.-')
plt.plot([bst_n_estimators, bst_n_estimators], [0, min_error], 'k--')
plt.plot([0, 120], [min_error, min_error], 'k--')
plt.axis([0, 120, 0, 0.01])
plt.title('验证集误差')

# 第二个子图:展示均方误差最小的模型的预测结果
plt.subplot(122)
plot_predictions([gbrt_best], X, y, axes=[-0.5, 0.5, -0.1, 0.8])
plt.title('最佳模型(%d棵树)' % bst_n_estimators)

这段代码演示了模型提前停止策略,该策略的关键是选择在验证集上性能最佳的模型,以避免过拟合。以下是对代码和生成的图像的简要概括:

  1. 均方误差监测:通过计算不同基础模型数量下,梯度提升模型在验证集上的均方误差(MSE),观察模型性能的变化。均方误差是一种衡量模型预测与真实值之间差距的指标,较低的均方误差表示模型拟合效果更好。

  2. 选择最佳模型数量:通过观察均方误差的变化,找到了均方误差最小的基础模型数量 bst_n_estimators。这个数量对应于在验证集上性能最佳的模型。

  3. 最佳模型展示:在第二个子图中,展示了具有最小均方误差的最佳模型的预测结果。这个模型是在提前停止策略下选择的。

提前停止策略的目标是在模型性能开始下降之前选择停止模型训练,从而避免过拟合。通过在验证集上监测性能,我们可以选择性能最佳的模型,这通常对于获得更好的泛化性能非常重要。在本例中,选择了拥有最小验证集均方误差的模型,这是一种常见的提前停止策略。

Early stopping

# 创建梯度提升回归模型 gbrt,设置模型参数,同时启用了 warm_start 参数
gbrt = GradientBoostingRegressor(max_depth=2,
                                 random_state=42,
                                 warm_start=True
                                )

# 初始化变量 error_going_up 用于计数连续验证集误差上升的次数
error_going_up = 0

# 初始化变量 min_val_error 为正无穷,用于保存最小的验证集误差
min_val_error = float('inf')

# 循环迭代,逐步增加基础模型的数量
for n_estimators in range(1, 120):
    # 设置梯度提升模型的基础模型数量
    gbrt.n_estimators = n_estimators
    
    # 使用训练数据 X_train 和目标值 y_train 训练模型
    gbrt.fit(X_train, y_train)
    
    # 使用训练好的模型进行在验证集上的预测
    y_pred = gbrt.predict(X_val)
    
    # 计算验证集上的均方误差
    val_error = mean_squared_error(y_val, y_pred)
    
    # 检查验证集误差是否小于最小验证集误差,若是则更新最小验证集误差和错误计数器
    if val_error < min_val_error:
        min_val_error = val_error
        error_going_up = 0
    else:
        error_going_up += 1
        
        # 若验证集误差连续上升达到5次,则停止迭代
        if error_going_up == 5:
            break

# 打印最终确定的基础模型数量
print(gbrt.n_estimators)
# 输出:61

这段代码演示了模型提前停止策略,也称为"Early Stopping"。以下是对此策略的简要概括:

  1. 目标:模型提前停止策略的目标是在验证集上的性能不再提升,或开始下降时停止模型的训练,以避免过拟合。

  2. 策略

    • 代码中使用了 warm_start=True,这允许逐步增加基础模型的数量,然后在每一步检查验证集上的性能。
    • 在每一轮迭代中,计算验证集上的均方误差,并与最小验证集误差进行比较。
    • 如果当前验证集误差小于最小验证集误差,则更新最小验证集误差,并将错误计数器重置为零。
    • 如果当前验证集误差连续上升达到了5次(可以根据需求调整),则停止模型的训练,因为模型性能可能已经开始下降。
  3. 结果:通过这种策略,最终确定了在验证集上性能最佳的基础模型数量,以避免在训练集上过拟合。这样可以获得更好的泛化性能,提高模型的实用性。

模型提前停止策略是一种常用于防止过拟合的技术,它基于验证集上的性能指标来动态地控制模型训练的停止点,从而在不浪费计算资源的情况下获得最佳的模型。


14.12-堆叠模型

Stacking(堆叠集成)

# 导入所需的库和模块
from sklearn.datasets import fetch_mldata
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier, ExtraTreesClassifier
from sklearn.svm import LinearSVC
from sklearn.neural_network import MLPClassifier

# 从MNIST数据集中加载数据
mnist = fetch_mldata('MNIST original')

# 划分数据集为训练集、验证集和测试集
X_train_val, X_test, y_train_val, y_test = train_test_split(
    mnist.data, mnist.target, test_size=10000, random_state=42)
X_train, X_val, y_train, y_val = train_test_split(
    X_train_val, y_train_val, test_size=10000, random_state=42)

# 创建随机森林、极端随机森林、线性支持向量机和多层感知器分类器模型
random_forest_clf = RandomForestClassifier(random_state=42)
extra_trees_clf = ExtraTreesClassifier(random_state=42)
svm_clf = LinearSVC(random_state=42)
mlp_clf = MLPClassifier(random_state=42)

# 将模型放入列表中
estimators = [random_forest_clf, extra_trees_clf, svm_clf, mlp_clf]

# 遍历每个模型,进行训练
for estimator in estimators:
    print("训练模型:", estimator)
    estimator.fit(X_train, y_train)

# 初始化一个数组用于存储各模型对验证集的预测结果
X_val_predictions = np.empty((len(X_val), len(estimators)), dtype=np.float32)

# 遍历每个模型,生成其对验证集的预测结果
for index, estimator in enumerate(estimators):
    X_val_predictions[:, index] = estimator.predict(X_val)

# 输出验证集上的模型预测结果
X_val_predictions

# 创建随机森林分类器作为混合器,并使用验证集上的模型预测结果进行训练
rnd_forest_blender = RandomForestClassifier(n_estimators=200, oob_score=True, random_state=42)
rnd_forest_blender.fit(X_val_predictions, y_val)

# 输出混合器模型在袋外数据上的得分
rnd_forest_blender.oob_score_
# 输出:0.9642

这段代码演示了一种堆叠集成的方法。以下是对这种方法的简要概括:

  1. 模型组合:堆叠集成是一种模型组合方法,它将多个不同的基本模型(这里使用了随机森林、极端随机森林、线性支持向量机和多层感知器分类器)组合在一起,以获得更好的整体性能。

  2. 划分数据集:首先,数据集被划分为训练集、验证集和测试集,以便进行模型训练、验证和评估。

  3. 基本模型训练:每个基本模型都在训练集上进行训练,以学习数据的不同方面和模式。

  4. 基本模型预测:每个基本模型都对验证集进行预测,生成验证集上的预测结果。

  5. 堆叠混合器:然后,这些基本模型的验证集预测结果被合并成一个新的特征矩阵,作为输入供堆叠混合器(这里使用了随机森林分类器)进行训练。混合器模型将这些不同模型的输出作为输入,进一步学习如何组合它们以获得更好的性能。

  6. 评估性能:最后,堆叠模型的性能可以通过oob得分(out-of-bag score)进行评估,用于估计模型的泛化性能。

堆叠模型(Stacking)是一种集成学习方法,它通过组合多个不同基础学习器(通常包括多个分类器或回归器)的预测结果,以提高模型性能和泛化能力。以下是对堆叠模型的简要概括:

  1. 多层结构:堆叠模型通常由多个层次组成,包括底层基础学习器和一个顶层的元学习器(也称为混合器或元分类器)。

  2. 基础学习器:在底层,堆叠模型包含多个不同的基础学习器,每个学习器可以是不同类型的机器学习算法,例如决策树、支持向量机、神经网络等。这些基础学习器独立地对数据进行预测。

  3. 特征:除了原始特征,堆叠模型的底层还可以使用基础学习器的预测结果作为新特征。这些特征用于提供额外信息以改进性能。

  4. 元学习器:在顶层,堆叠模型包含一个元学习器,它接收底层基础学习器的预测结果作为输入,并生成最终的模型预测。元学习器可以是简单的模型,例如逻辑回归,用于组合底层学习器的输出。

  5. 训练过程:堆叠模型的训练过程通常分为两个阶段。首先,底层基础学习器在训练数据上独立训练。然后,使用基础学习器的预测结果和验证数据,训练元学习器以生成最终的集成模型。

  6. 优势:堆叠模型的优势在于它可以充分利用不同模型的优点,从而提高模型的性能。通过将多个模型的预测结果结合在一起,堆叠模型通常能够降低过拟合风险,提高泛化能力,并在比单一模型更复杂的问题上表现更好。

总的来说,堆叠模型是一种强大的集成学习方法,它通过多层结构和组合不同模型的预测来提高机器学习模型的性能,尤其适用于复杂问题和大规模数据集。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值