Press "Enter" to skip to content

集成学习:从决策树到随机森林

探索集成学习的威力

图片来源:Joe在Pixabay上的图片

在本文中,我们将讨论和描述集成学习。

我们将从决策树模型开始讨论。然后,我们将解释集成学习,并最后描述随机森林模型作为构建在决策树之上的集成模型。

对于决策树和随机森林,我们将提供Python代码,展示如何在分类任务中实现它们。

决策树模型

决策树(DT)是一种非常通用的机器学习模型,能够执行回归和分类任务,并且可以处理数值和分类变量。

在这里,我们将解释决策树模型,展示其学习过程,并实现一个决策树模型。

解释决策树模型

决策树模型是一种类似流程图的机器学习模型,它的构建方式类似于一棵实际的树。它有叶子节点、内部节点、根节点和分支。

让我们来看看它是如何工作以及它的特点,通过一个实际的例子来说明。假设一个决策树需要根据我们的工作决定我们是留在办公室还是外出:

图片来源:作者

所以,我们有:

  • 根节点。这是一切的起点,代表整个数据集。
  • 叶子节点(所有橙色矩形)。它们像树的叶子一样在最末端。
  • 内部节点。这些是被前一个节点分割的节点。
  • 分支。它们是一组内部节点和叶子节点,就像实际的树一样。
  • 最大深度代表决策树有多深;换句话说,它表示在从根节点开始到最后的叶子节点(“回家/去酒吧”)之前需要多少次分割。

决策树模型的基本思想是利用数据集的特征进行决策并将数据分成较小的子集。树中的每个内部节点表示一个特征或属性,分支表示基于该特征值的不同决策或规则。

叶子节点表示最终输出:一个类别(在分类问题中)或一个值(在回归问题中)。

这个过程与我们人类如何做决策非常相似。所以一个问题可能会出现:决策树是如何分割节点的?换句话说:决策树是如何做决策的?

决策树会不断分割,直到所有的叶子节点都是纯净的,也就是说所有的内部节点至少有一个叶子节点。

实际上,这可能导致非常深的决策树,拥有许多节点,很容易导致过拟合。所以,我们通常会通过设置最大深度的限制来修剪树(这是决策树的超参数之一)。

不纯度和信息增益

为了理解决策树如何分割直到叶子节点纯净,也就是如何做决策,我们需要使用一些数学来解释不纯度和信息增益的概念。

特别地,有两种不纯度:熵和基尼不纯度。

在热力学中,熵表示分子的无序程度:当分子静止且有序时,熵为0。

在机器学习中,我们使用熵来衡量不纯度,遵循类似的思想。我们定义熵如下[Ref. 2, 第88页]:

图片来源:作者

在分类问题的情况下,我们有 p(i|t) 表示节点 t 中属于类别 i 的示例比例。

因此,如果特定节点上的所有示例都属于同一类别,则熵为0;如果特定节点上的类别分布均匀,则熵为最大值(最大值为1)。

基尼不纯度

基尼不纯度是评估特征如何将数据分离成不同类别的度量。它定义为在数据集中随机选择一个样本被错误分类的概率。我们如下定义它[Ref. 1, 第169页]:

Source: Image by author.

因此,鉴于在分类问题的情况下,p(i|t) 是节点 t 中属于类别 i 的示例比例,这就是为什么基尼不纯度可以看作是最小化错误分类概率的准则。这是因为如果我们有:

Source: Image by author.

这意味着所有示例属于同一类别,那么:

Source: Image by author.

这意味着节点是纯净的(即,实例属于同一类别,如前所述)。

因此,基尼不纯度的范围是从0到1,其中0表示数据集是纯净的(所有示例属于同一类别),而1表示数据集是不纯的(示例属于多个类别)。

让我们举个例子。假设我们有一个包含两个类别 A 和 B 的数据集,并且我们有两个特征 P 和 Q 可以用来划分数据。如果特征 P 的基尼不纯度为0.2,而特征 Q 的基尼不纯度为0.3,我们将选择特征 P 来划分数据,因为它产生了更低的不纯度,从而得到了更纯净的数据子集。

选择哪个准则?

sklearn 默认使用基尼不纯度,但我们可以将熵设置为准则(这是决策树的超参数)。实际上,两者之间没有太大的差异:用熵训练一个决策树和用基尼不纯度训练另一个决策树并不值得努力。

最大化信息增益

信息增益是在选择特征划分数据后数据集不纯度减少的度量。决策树的目标实际上是选择最“有意义”的特征,以便它将导致最纯净的数据子集。因此,我们使用信息增益来确定特征的相对质量。

鉴于信息增益是衡量特征如何将数据分离成不同类别的度量,我们希望最大化它。

我们如下定义它[Ref. 2, 第88页]:

Source: Image by author

我们有:

  • f是要分割的特征,
  • Dp和Dn分别是父节点和第n个子节点的数据集,
  • I是不纯度,
  • Np和Nn分别是父节点和第n个子节点的训练样本总数。

我们在上面介绍了“父节点”和“子节点”的概念。这些是相对的术语:任何属于另一个节点的节点都是子节点或子节点,而在这些子节点之前的任何节点都被称为父节点。

因此,对于上述公式来说,信息增益是父节点不纯度与子节点不纯度之和的差;这意味着子节点的不纯度越低,信息增益越高。

这意味着决策树的决策是为了最大化信息增益,也就是在每个节点降低不纯度。

在分类问题中实现决策树

让我们创建一个数据集,对数据进行标准化,将其分为训练集和测试集,使用决策树模型拟合训练集,并在测试集上计算混淆矩阵:

from sklearn.datasets import make_classificationfrom sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScalerfrom sklearn.tree import DecisionTreeClassifierfrom sklearn.metrics import confusion_matrix# 创建一个分类数据集X, y = make_classification(n_samples=1000, n_features=10, n_informative=5, n_classes=2, random_state=42)# 标准化数据scaler = StandardScaler()X_scaled = scaler.fit_transform(X)# 将数据集分为训练集和测试集X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)# 使用决策树模型拟合训练集dt_model = DecisionTreeClassifier(random_state=42)dt_model.fit(X_train, y_train)# 计算测试集的混淆矩阵y_test_pred = dt_model.predict(X_test)test_confusion_matrix = confusion_matrix(y_test, y_test_pred)print("混淆矩阵(测试集):\n", test_confusion_matrix)

输出结果为:

混淆矩阵(测试集):[[103   9] [ 12  76]]

这是一个相当不错的结果,因为非对角线上的值,表示假阳性和假阴性,非常少。

集成学习

当我们解决一个机器学习问题时,通常会在数据上测试不同的机器学习模型,以找到在新的、未见过的数据上进行更好预测或分类的模型。

改进机器学习问题的一种方式是将一些模型组合起来,通常是表现最佳的模型,形成一个单一的、独特的模型:我们称之为集成学习

集成的结果,或集合,总是比最好的单个模型表现更好。

让我们看看集成学习的工作原理。

投票原则

让我们考虑一个分类示例:在二元分类问题的情况下,我们训练了支持向量机和决策树,并且两个分类器的准确率都在80%左右。这意味着两个分类器在80%的情况下都能预测出正确的类别,这可能非常不错。

集成方法的目标是将不同的方法结合到一个单一的分类器中,使其具有比每个单独的分类器更好的泛化性能。但是这是如何可能的呢?通过某种方式将不同的分类器组合成一个元分类器,如何比单个分类器更好地进行泛化性能呢?

集成学习基于所谓的“大数法则”工作;让我们举个例子来理解它[Ref.1, 第183页]:

“假设我们有一枚有偏置的硬币,正面朝上的概率为51%,反面朝上的概率为49%。如果我们抛硬币1,000次,那么正面朝上的次数会多或少为510次,反面朝上的次数为490次,因此正面朝上的次数占多数。做个简单的数学计算,如果我们抛硬币1,000次,正面朝上的概率接近75%。这是由于大数法则:随着我们不断抛硬币,正面朝上的比例越来越接近正面朝上的概率(51%)。”

集成学习在组合不同的分类器时利用了这个原理。事实上,创建一个集成分类器的简单方法是聚合我们训练的每个分类器的预测结果,并预测得到得票数最多的类别:我们称之为多数投票原则。

让我们创建一个图表来更好地理解多数投票原则。假设我们在给定的数据集上训练了一个SVM和一个决策树,这是一个二分类问题。多数投票原则的工作方式如下:

来源:作者提供的图片

虽然我们可以组合任何类型的分类器,但这种原则与独立分类器更配合,因为每个独立分类器与其他分类器产生不相关的错误。换句话说,集成中的每个分类器能够捕捉数据的不同方面,并通过组合它们的预测,比任何单独的分类器都能做出更准确的预测。

多数投票原则的数学原理

让我们使用一个分类示例来数学上展示多数投票原则的工作原理。

我们想要实现一个算法,允许我们组合不同的分类器,每个分类器都与一个置信度权重相关联。我们的目标是构建一个元分类器,在一组数据上平衡各个分类器的弱点(即高偏差或高方差)。我们可以按照以下方式创建加权多数投票 [Ref. 2, page 209]:

来源:作者提供的图片

其中:

  • “y”表示集成的预测类别。
  • “Wj”表示与某个分类器“Cj”相关联的权重。
  • “Fa”是一个函数,如果第j个分类器的预测类别与i匹配,则返回1,即“Cj(x)=i”。

arg max函数返回最大的参数。

在我们为每个分类器分配相等的权重的情况下,我们简单地有以下公式:

来源:作者提供的图片

请记住,在统计学中,众数是一组数据中出现最频繁的值,也就是说,y^ 简单地是我们的分类器输出中的众数。

因此,假设我们有一个二分类问题,有三个分类器:

  • C1(x) → 1
  • C2(x) → 0
  • C3(x) → 0

我们有:

来源:作者提供的图片

现在,让我们为我们的分类器分配一些权重,如下:

  • C1(x) → 1,W1=0.6
  • C2(x) → 0,W2=0.2
  • C3(x) → 0,W3=0.2
来源:作者提供的图片

因此,在这种情况下,C1的预测比其他分类器的预测权重更大,集成预测的类别是1。

换句话说,W1=0.6是C2和C3权重的三倍,即0.6=3⋅0.20.6。所以,我们想要表达的是C1的权重是其他两个分类器的三倍,我们甚至可以使用以下公式计算集成的预测:

来源:作者提供的图片

使用Bagging和Pasting进行集成

Bagging是说bootstrap aggregating的简称。

在统计学中,bootstrap aggregation是使用带替换的随机抽样的任何测试。 替换意味着一个个体数据点可以被选择多次。

Pasting是一种不使用替换的随机抽样技术。Pasting不使用替换的事实意味着一个个体数据点只能被选择一次。

让我们使用一个方案来澄清Bagging的过程:

来源:作者提供的图片

因此,在上述情况下,我们从训练集中取出了5个样本,并使用Bagging技术将它们馈送给了三个分类器/回归器;也就是说,我们可以多次使用从训练集中取出的同一个样本。

请注意,每个子集都包含一定数量的重复子集,并且一些原始子集不会出现在所有重新采样的子集中,这是由于替换的缘故。为了清楚起见:我们使用不包含子集n°5的数据来馈送分类器/回归器1。对于其他分类器/回归器也是如此。

随机森林模型

不幸的是,决策树(DTs)具有很高的方差,我们可以通过限制它们的深度来限制它们的方差。

此外,DTs会根据数据的每个分割调整它们的预测。这意味着它们越深,可能过拟合的程度就越高。

为了避免过多地处理DTs的高方差,一种增强DTs性能的解决方案是创建一个集成:这就是随机森林模型的诞生方式。

在DTs之上构建RF模型

集成方法在机器学习领域近年来变得越来越受欢迎,因为它们对抗过拟合的性能良好。

随机森林 (RF) 是一个既可以进行分类又可以进行回归任务的机器学习模型,它是通过Bagging方法构建的一组决策树的集成。这意味着RF具有DT的所有超参数,同时也具有控制集成本身的Bagging分类器/回归器的所有超参数。

让我们可视化创建RF模型的过程:

来源:作者提供的图片

因此,在这里我们正在使用替换的方式,从初始训练数据中获取子样本,并对其进行决策树的训练。

此外,在构建树时,RF模型引入了一些额外的随机性,因为它在选择分割节点时不是搜索最佳特征(与DT模型中的情况相反),而是在一组随机特征中选择最佳特征。这会导致更高的偏差和更低的方差,因此相对于单个DT而言,得到了更好的模型。

换句话说,在分割节点时,DTs考虑了每个可能的特征,并选择产生子节点之间最大分离的特征。而在RF模型的情况下,每棵树只能选择一组随机特征。这增加了树之间的随机性和变化,从而导致更多的独立性和多样化。

让我们来可视化这个概念:

来源:作者提供的图片

假设我们有一个包含5个特征的数据集。通过检查我们的RF模型的树,我们可以看到:

  • DT 1 考虑特征 1、特征 3 和特征 5。
  • DT 2 考虑特征 1、特征 4 和特征 5。
  • DT 3 考虑特征 2、特征 3 和特征 4。

所有这些特征都是我们 RF 的每个 DT 随机选择的。

假设我们之前训练过一个单独的 DT,使用所有特征,并且找到了用于分割节点的最佳特征是特征 2。然而,DT 1 和 DT 2 不能使用特征 2 进行训练,它们分别被强制使用特征 3 和特征 4 进行训练(以上图像中以粗体显示)。

我们最终得到的树是在初始数据的不同随机子集上进行训练的,即使在随机选择的特征子集上也是如此,且不进行替换。

一般来说,RF 的可解释性不如 DT 高,但 RF 的一个重要优势是我们不需要过多担心它们的超参数。例如,我们通常不需要修剪 RF,因为整个集合通过对创建模型的 DT 的预测进行平均来对噪声具有鲁棒性。

我们应该关注的典型参数是创建 RF 的树的数量。我们可以通过使用更多的树来获得更好的性能,但代价是更高的计算成本(需要更多的时间和硬件资源)。

实现一个 RF

让我们使用与决策树相同的数据集来比较在使用随机森林时的结果:

from sklearn.datasets import make_classificationfrom sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScalerfrom sklearn.ensemble import RandomForestClassifierfrom sklearn.metrics import confusion_matrix# 创建一个分类数据集X, y = make_classification(n_samples=1000, n_features=10, n_informative=5, n_classes=2, random_state=42)# 用 StandardScaler 对数据进行标准化scaler = StandardScaler()X_scaled = scaler.fit_transform(X)# 将数据集拆分为训练集和测试集X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)# 用随机森林模型拟合训练集rf_model = RandomForestClassifier(n_estimators=100, random_state=42)rf_model.fit(X_train, y_train)# 计算测试集的混淆矩阵y_test_pred = rf_model.predict(X_test)test_confusion_matrix = confusion_matrix(y_test, y_test_pred)print("混淆矩阵(测试集):\n", test_confusion_matrix)

我们得到:

混淆矩阵(测试集):[[106   6] [  5  83]]

如我们所见,RF 的性能优于单个 DT,因为该混淆矩阵具有较少的非对角线元素(FP 和 FN),以及更多的对角线元素(TP 和 TN),这正是我们希望的。

结论

本文讨论了集成学习如何通过从 DT 模型开始并最终得到 RF 提高单个 ML 模型的性能。

参考文献:

[1]: 《Scikit-Learn & Tensorflow 机器学习实战》, Aurelien Gueron

[2]: 《PyTorch 和 Scikit-Learn 机器学习实战》, Sebastian Raschka, Yuxi Liu, Vahid Mirjalili

注:即使未明确指定页码,参考文献必须按照 [1] 和 [2] 的规定来考虑。

Leave a Reply

Your email address will not be published. Required fields are marked *