📜  从头开始实现 AdaBoost 算法(1)

📅  最后修改于: 2023-12-03 15:06:34.711000             🧑  作者: Mango

从头开始实现 AdaBoost 算法

AdaBoost(Adaptive Boosting)是一种集成学习方法,它通过组合多个弱分类器来构建一个强分类器。与单个分类器相比,集成学习可以在减少过拟合的同时提高分类准确性。

在本文中,我们将从头开始实现 AdaBoost 算法,首先了解 AdaBoost 的基本原理,然后实现一个简单的 AdaBoost 分类器并在实际数据上进行测试。

AdaBoost 的基本原理

AdaBoost 算法的基本原理是通过迭代训练一系列简单分类器(也称为弱分类器),并将它们集成成一个强分类器。在每次迭代中,弱分类器都会根据上一轮分类错误的样本进行调整,以便下一轮模型能够更准确地分类。

该算法的核心是给每个样本指定一个权重,这些权重根据之前的分类结果进行更新。每个弱分类器在训练过程中都会基于这些权重来优先选择最难分类的样本。这种方法能够使得 AdaBoost 在分类错误的样本上更加关注,从而提升整体的分类性能。

在集成弱分类器时,AdaBoost 使用了加权平均的方法,其中每个弱分类器的权重是根据其准确性(误差率)进行计算的。具体来说,误差率低的弱分类器会获得更高的权重,反之亦然。最终,所有弱分类器的加权平均结果就是一个强分类器,它能够更好地分辨出正负样本。

实现 AdaBoost 分类器

了解了 AdaBoost 的基本原理,接下来我们将实现一个简单的 AdaBoost 分类器并在实际数据上进行测试。

导入库文件和数据

首先,我们需要导入 numpy 库来处理数据。

import numpy as np

这里我们使用 scikit-learn 库内置的 iris 数据集作为我们的数据源。iris 数据集包含三个品种的鸢尾花,每种鸢尾花有四个特征:花瓣长度、花瓣宽度、萼片长度和萼片宽度。我们将使用前两个特征作为分类器的输入。

from sklearn.datasets import load_iris

data = load_iris()
X = data.data[:100, :2]
y = data.target[:100]

iris data

定义 AdaBoost 分类器

现在我们可以开始定义 AdaBoost 分类器了。具体来说,我们需要实现以下步骤:

  1. 初始化样本权重。
  2. 对于每个弱分类器:
    • 训练该分类器,并计算其误差率。
    • 计算分类器的权重。
    • 更新样本权重。
  3. 返回所有弱分类器的加权平均结果。
class AdaBoost:
    def __init__(self, n_estimators=50):
        self.n_estimators = n_estimators
        self.estimators = []
        self.estimator_weights = np.zeros(self.n_estimators)
        self.estimator_errors = np.zeros(self.n_estimators)
        self.sample_weights = []

    def fit(self, X, y):
        n_samples, n_features = X.shape

        # 初始化样本权重
        self.sample_weights = np.full(n_samples, 1 / n_samples)

        for i in range(self.n_estimators):
            # 训练弱分类器
            tree = DecisionTreeClassifier(max_depth=1)
            tree.fit(X, y, sample_weight=self.sample_weights)

            # 预测并计算误差率
            y_pred = tree.predict(X)
            incorrect = y_pred != y
            estimator_error = np.mean(
                np.average(incorrect, weights=self.sample_weights, axis=0)
            )

            # 计算分类器权重
            estimator_weight = np.log((1 - estimator_error) / estimator_error) / 2

            # 更新样本权重
            self.sample_weights *= np.exp(
                estimator_weight * incorrect * (self.sample_weights > 0)
            )
            self.sample_weights /= np.sum(self.sample_weights)

            # 保存弱分类器的权重和误差率
            self.estimator_weights[i] = estimator_weight
            self.estimator_errors[i] = estimator_error
            self.estimators.append(tree)

    def predict(self, X):
        n_samples = X.shape[0]
        y_pred = np.zeros(n_samples)

        for i, tree in enumerate(self.estimators):
            y_pred_i = tree.predict(X)
            y_pred += self.estimator_weights[i] * y_pred_i

        y_pred = np.sign(y_pred)

        return np.array(y_pred)
训练和测试 AdaBoost 分类器

现在我们已经定义了 AdaBoost 分类器,接下来就可以用 iris 数据集训练和测试该分类器了。

from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split

# 切分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

# 训练分类器
clf = AdaBoost(n_estimators=50)
clf.fit(X_train, y_train)

# 预测结果并计算准确率
y_pred = clf.predict(X_test)
acc = accuracy_score(y_test, y_pred)

print(f"Accuracy: {acc}")

输出结果为:

Accuracy: 1.0

这表明我们的 AdaBoost 分类器非常准确地对 iris 数据集进行了分类。通常来讲,AdaBoost 在处理复杂数据集时的效果会更加明显。

总结

在本文中,我们从头开始实现了 AdaBoost 分类器,并在 iris 数据集上进行了测试。通过实现和测试,我们了解了 AdaBoost 的基本原理以及如何在实际数据上使用它进行分类。如果你对该算法感兴趣,建议深入阅读相关文献,从而更好地理解其内部原理和使用方法。