机器学习 - 自助聚合 (Bagging)
在本页中,W3schools.com 与 纽约数据科学学院 合作,为我们的学生提供数字培训内容。
Bagging
诸如决策树之类的算法,可能会在训练集上过度拟合,这会导致对新数据的预测错误。
自助聚合 (bagging) 是一种集成方法,旨在解决分类或回归问题的过度拟合。 Bagging 的目标是提高机器学习算法的准确性和性能。 它通过从原始数据集中有放回地随机抽取子集来实现这一点,并为每个子集拟合分类器(用于分类)或回归器(用于回归)。 然后通过多数投票(用于分类)或平均值(用于回归)对每个子集的预测进行聚合,从而提高预测准确性。
评估基本分类器
为了了解 Bagging 如何提高模型性能,我们首先需要评估基础分类器在数据集上的表现。如果你还不了解决策树,请在继续学习之前回顾决策树的课程,因为 Bagging 是决策树概念的延续。
我们将尝试识别 Sklearn 的葡萄酒数据集中的不同葡萄酒类别。
让我们从导入必要的模块开始。from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.tree import DecisionTreeClassifier
接下来,我们需要加载数据并将其存储到 X(输入特征)和 y(目标)中。参数 as_frame 设置为 True,这样我们在加载数据时不会丢失特征名称。(sklearn
版本早于 0.23 必须跳过 as_frame
参数,因为它不受支持)
data = datasets.load_wine(as_frame = True)
X = data.data
y = data.target
为了在未见数据上正确评估我们的模型,我们需要将 X 和 y 分割成训练集和测试集。有关分割数据的更多信息,请参阅训练/测试课程。
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25, random_state = 22)
数据准备就绪后,我们现在可以实例化一个基础分类器并将其拟合到训练数据。
dtree = DecisionTreeClassifier(random_state = 22)
dtree.fit(X_train,y_train)
结果
DecisionTreeClassifier(random_state=22)
现在我们可以预测未见测试集的葡萄酒类别并评估模型性能。
y_pred = dtree.predict(X_test)
print("训练数据准确率:",accuracy_score(y_true = y_train, y_pred = dtree.predict(X_train)))
print("测试数据准确率:",accuracy_score(y_true = y_test, y_pred = y_pred))
结果
训练数据准确率:1.0
测试数据准确率:0.8222222222222222
示例
导入必要的数据并评估基础分类器的性能。
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.tree import DecisionTreeClassifier
data = datasets.load_wine(as_frame = True)
X = data.data
y = data.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25, random_state = 22)
dtree = DecisionTreeClassifier(random_state = 22)
dtree.fit(X_train,y_train)
y_pred = dtree.predict(X_test)
print("训练数据准确率:",accuracy_score(y_true = y_train, y_pred = dtree.predict(X_train)))
print("测试数据准确率:",accuracy_score(y_true = y_test, y_pred = y_pred))
运行示例 »
基础分类器在数据集上的表现相当不错,在测试数据集上获得了 82% 的准确率,目前的参数是(如果你没有设置 random_state
参数,可能会得到不同的结果)。
现在我们有了测试数据集的基线准确率,我们可以看看 Bagging 分类器如何胜过单个决策树分类器。
广告
创建 Bagging 分类器
对于 Bagging,我们需要设置参数 n_estimators,这是我们的模型要聚合在一起的基础分类器的数量。
对于这个示例数据集,估计器的数量相对较少,通常情况下会探索更大的范围。超参数调优通常使用 网格搜索 完成,但现在我们将使用一组选定的估计器数量的值。
我们首先导入必要的模型。
from sklearn.ensemble import BaggingClassifier
现在让我们创建一系列值,这些值代表我们想要在每个集成中使用的估计器数量。
estimator_range = [2,4,6,8,10,12,14,16]
为了了解 Bagging 分类器在不同的 n_estimators 值上的表现,我们需要一种方法来迭代这些值范围并存储每个集成的结果。为此,我们将创建一个 for 循环,将模型和分数存储在单独的列表中,以便以后进行可视化。
注意:BaggingClassifier
中基础分类器的默认参数是 DicisionTreeClassifier
,因此我们在实例化 Bagging 模型时不需要设置它。
models = []
scores = []
for n_estimators in estimator_range
# 创建 Bagging 分类器
clf = BaggingClassifier(n_estimators = n_estimators, random_state = 22)
# 拟合模型
clf.fit(X_train, y_train)
# 将模型和分数追加到它们各自的列表中
models.append(clf)
scores.append(accuracy_score(y_true = y_test, y_pred = clf.predict(X_test)))
模型和分数存储完毕后,我们现在可以可视化模型性能的改进。
import matplotlib.pyplot as plt
# 生成分数与估计器数量的图表
plt.figure(figsize=(9,6))
plt.plot(estimator_range, scores)
# 调整标签和字体(使之可见)
plt.xlabel("n_estimators", fontsize = 18)
plt.ylabel("score", fontsize = 18)
plt.tick_params(labelsize = 16)
# 可视化图表
plt.show()
示例
导入必要的数据并评估 BaggingClassifier
的性能。
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.ensemble import BaggingClassifier
data = datasets.load_wine(as_frame = True)
X = data.data
y = data.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25, random_state = 22)
estimator_range = [2,4,6,8,10,12,14,16]
models = []
scores = []
for n_estimators in estimator_range
# 创建 Bagging 分类器
clf = BaggingClassifier(n_estimators = n_estimators, random_state = 22)
# 拟合模型
clf.fit(X_train, y_train)
# 将模型和分数追加到它们各自的列表中
models.append(clf)
scores.append(accuracy_score(y_true = y_test, y_pred = clf.predict(X_test)))
# 生成分数与估计器数量的图表
plt.figure(figsize=(9,6))
plt.plot(estimator_range, scores)
# 调整标签和字体(使之可见)
plt.xlabel("n_estimators", fontsize = 18)
plt.ylabel("score", fontsize = 18)
plt.tick_params(labelsize = 16)
# 可视化图表
plt.show()
结果
运行示例 »结果解释
通过迭代不同的估计器数量值,我们可以看到模型性能从 82.2% 提高到 95.5%。在 14 个估计器之后,准确率开始下降,同样,如果你设置了不同的 random_state
,你看到的值也会有所不同。这就是为什么最好使用 交叉验证 来确保稳定的结果。
在这种情况下,我们看到识别葡萄酒类型的准确率提高了 13.3%。
另一种评估形式
由于 Bootstrap 选择观测值的随机子集来创建分类器,因此在选择过程中会遗漏一些观测值。这些“袋外”观测值可以用来评估模型,类似于测试集。请记住,袋外估计可能会高估二元分类问题的误差,并且只应该用作其他指标的补充。
我们在上一个练习中看到,12 个估计器产生了最高的准确率,因此我们将使用它来创建我们的模型。这次我们将参数 oob_score
设置为 true,以便使用袋外分数评估模型。
示例
创建一个带有袋外指标的模型。
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.ensemble import BaggingClassifier
data = datasets.load_wine(as_frame = True)
X = data.data
y = data.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25, random_state = 22)
oob_model = BaggingClassifier(n_estimators = 12, oob_score = True,random_state = 22)
oob_model.fit(X_train, y_train)
print(oob_model.oob_score_)
运行示例 »
由于 OOB 和测试集中使用的样本不同,并且数据集相对较小,因此准确率存在差异。它们很少完全相同,同样,OOB 应该被用作快速评估误差的方法,但它不是唯一的评估指标。
从 Bagging 分类器生成决策树
正如在 决策树 课程中所见,可以绘制模型创建的决策树。也可以看到构成聚合分类器的单个决策树。这有助于我们更直观地了解 Bagging 模型如何得出预测结果。
注意:这仅适用于较小的数据集,其中树木相对较浅且较窄,便于可视化。
我们需要从 sklearn.tree
中导入 plot_tree
函数。可以通过更改想要可视化的估计器来绘制不同的树。
示例
从 Bagging 分类器生成决策树
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.ensemble import BaggingClassifier
from sklearn.tree import plot_tree
X = data.data
y = data.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25, random_state = 22)
clf = BaggingClassifier(n_estimators = 12, oob_score = True,random_state = 22)
clf.fit(X_train, y_train)
plt.figure(figsize=(30, 20))
plot_tree(clf.estimators_[0], feature_names = X.columns)
结果
运行示例 »这里我们可以看到用来对最终预测进行投票的第一个决策树。同样,通过更改分类器的索引,我们可以看到每个被聚合的树。