在机器学习领域,集成树模型是一种强大的分类器,它通过组合多个决策树来提高预测的准确性。本文将探讨如何使用Python中的scikit-learn库来训练不同的集成树模型,并在鸢尾花数据集上绘制它们的决策面。鸢尾花数据集是一个经典的多类分类问题,包含了150个样本,每个样本有4个特征:萼片长度、萼片宽度、花瓣长度和花瓣宽度。
首先导入必要的库,包括matplotlib用于绘图,numpy用于数值计算,以及scikit-learn中的决策树、随机森林、极限树和AdaBoost分类器。接着,加载鸢尾花数据集,并定义了一些参数,如类别数、估计器数量、颜色映射等。还设置了随机种子以确保结果的可重复性。
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import ListedColormap
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier, ExtraTreesClassifier, AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
接下来,定义了四个不同的集成树模型:一个决策树分类器、一个随机森林分类器、一个极限树分类器和一个AdaBoost分类器。将使用这些模型来训练数据,并在不同的特征对上绘制决策面。
# 参数定义
n_classes = 3
n_estimators = 30
cmap = plt.cm.RdYlBu
plot_step = 0.02 # 决策面轮廓的细步长
plot_step_coarser = 0.5 # 粗分类器猜测的步长
RANDOM_SEED = 13 # 每次迭代固定种子
# 加载数据
iris = load_iris()
plot_idx = 1
models = [
DecisionTreeClassifier(max_depth=None),
RandomForestClassifier(n_estimators=n_estimators),
ExtraTreesClassifier(n_estimators=n_estimators),
AdaBoostClassifier(DecisionTreeClassifier(max_depth=3), n_estimators=n_estimators),
]
选择了三对特征来训练模型:萼片宽度和萼片长度、花瓣长度和萼片长度、花瓣宽度和花瓣长度。对于每一对特征,都训练了四个模型,并计算了它们的分数。在训练过程中,注意到极限树和随机森林在所有特征上的表现最好,而AdaBoost在某些特征对上的表现稍逊一筹。
此外,还尝试了不同的参数设置,例如改变决策树的最大深度和估计器的数量。发现,对于AdaBoost分类器,增加最大深度可以降低分数的标准差,但平均分数并没有提高。
在绘制决策面时,使用了细网格作为输入,以填充等高线图。对于单个决策树分类器,直接预测网格点的类别。对于集成树模型,对每个树的预测结果进行alpha混合,以显示不同估计器的影响。此外,还绘制了一组粗网格点,以展示集成分类器的预测结果与决策面的差异。最后,绘制了训练点,这些点聚集在一起,并有黑色轮廓。
# 绘制决策面
for pair in ([0, 1], [0, 2], [2, 3]):
for model in models:
# 只取对应的两个特征
X = iris.data[:, pair]
y = iris.target
# 随机打乱
idx = np.arange(X.shape[0])
np.random.seed(RANDOM_SEED)
np.random.shuffle(idx)
X = X[idx]
y = y[idx]
# 标准化
mean = X.mean(axis=0)
std = X.std(axis=0)
X = (X - mean) / std
# 训练
model.fit(X, y)
scores = model.score(X, y)
# 创建每个列的标题和控制台输出
model_title = str(type(model)).split(".")[-1][:-2][:-len("Classifier")]
model_details = model_title
if hasattr(model, "estimators_"):
model_details += " with {} estimators".format(len(model.estimators_))
print(model_details + " with features", pair, "has a score of", scores)
plt.subplot(3, 4, plot_idx)
if plot_idx <= len(models):
plt.title(model_title, fontsize=9)
# 绘制决策边界
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, plot_step), np.arange(y_min, y_max, plot_step))
if isinstance(model, DecisionTreeClassifier):
Z = model.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
cs = plt.contourf(xx, yy, Z, cmap=cmap)
else:
estimator_alpha = 1.0 / len(model.estimators_)
for tree in model.estimators_:
Z = tree.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
cs = plt.contourf(xx, yy, Z, alpha=estimator_alpha, cmap=cmap)
# 绘制粗网格点
xx_coarser, yy_coarser = np.meshgrid(np.arange(x_min, x_max, plot_step_coarser), np.arange(y_min, y_max, plot_step_coarser))
Z_points_coarser = model.predict(np.c_[xx_coarser.ravel(), yy_coarser.ravel()]).reshape(xx_coarser.shape)
cs_points = plt.scatter(xx_coarser, yy_coarser, s=15, c=Z_points_coarser, cmap=cmap, edgecolors="none")
# 绘制训练点
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=ListedColormap(["r", "y", "b"]), edgecolor="k", s=20)
plot_idx += 1
# 绘制标题和布局
plt.suptitle("Classifiers on feature subsets of the Iris dataset", fontsize=12)
plt.axis("tight")
plt.tight_layout(h_pad=0.2, w_pad=0.2, pad=2.5)
plt.show()
通过这个实验,可以看到集成树模型在处理鸢尾花数据集时的强大能力。随机森林和极限树在大多数情况下都能取得很好的效果,而AdaBoost虽然在某些特征对上表现稍差,但通过调整参数,仍然可以提高其性能。此外,通过绘制决策面,可以直观地理解模型是如何在特征空间中进行分类的。