决策树集成学习实战:基于鸢尾花数据集的分类问题解析

1次阅读
没有评论

共计 3254 个字符,预计需要花费 9 分钟才能阅读完成。

image.webp

背景介绍

鸢尾花数据集是机器学习领域的经典数据集,包含三种鸢尾花的 150 个样本,每个样本有 4 个特征(萼片长度、萼片宽度、花瓣长度、花瓣宽度)。这个数据集的特点是特征维度低、样本量适中,非常适合初学者练习分类算法。

决策树集成学习实战:基于鸢尾花数据集的分类问题解析

虽然数据集看起来简单,但分类任务仍面临一些挑战:

  1. 不同种类的特征分布有重叠区域
  2. 单个决策树容易过拟合
  3. 需要找到区分 versicolor 和 virginica 这两个相似类别的有效方法

技术对比:单决策树 vs 集成方法

单决策树的优缺点

  • 优点:
  • 易于理解和解释
  • 计算速度快
  • 不需要特征缩放

  • 缺点:

  • 容易过拟合
  • 对数据微小变化敏感
  • 预测准确率通常不如集成方法

集成方法的优势

  1. Bagging(如 Random Forest):
  2. 通过自助采样降低方差
  3. 并行训练多个树
  4. 天然抗过拟合

  5. Boosting(如 AdaBoost):

  6. 顺序训练弱学习器
  7. 聚焦难分类样本
  8. 通常比 Bagging 准确率更高

完整实现

下面是使用 scikit-learn 的完整代码实现:

# 导入必要库
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier, AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import matplotlib.pyplot as plt
import numpy as np

# 加载数据
iris = load_iris()
X, y = iris.data, iris.target

# 划分训练测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 单决策树
single_tree = DecisionTreeClassifier(max_depth=3, random_state=42)
single_tree.fit(X_train, y_train)
single_pred = single_tree.predict(X_test)
print(f"Single Tree Accuracy: {accuracy_score(y_test, single_pred):.2f}")

# 随机森林
rf = RandomForestClassifier(n_estimators=100, max_depth=3, random_state=42)
rf.fit(X_train, y_train)
rf_pred = rf.predict(X_test)
print(f"Random Forest Accuracy: {accuracy_score(y_test, rf_pred):.2f}")

# AdaBoost
ada = AdaBoostClassifier(DecisionTreeClassifier(max_depth=1),
    n_estimators=50,
    learning_rate=1.0,
    random_state=42
)
ada.fit(X_train, y_train)
ada_pred = ada.predict(X_test)
print(f"AdaBoost Accuracy: {accuracy_score(y_test, ada_pred):.2f}")

参数调优指南

关键参数解析

  1. max_depth:
  2. 控制树的深度
  3. 值太小会欠拟合,太大会过拟合
  4. 建议从 3 开始尝试

  5. n_estimators:

  6. 集成中树的数量
  7. 越多效果通常越好,但计算成本增加
  8. 随机森林建议 100-200,AdaBoost 建议 50-100

  9. min_samples_split:

  10. 节点分裂所需最小样本数
  11. 防止过拟合
  12. 常用值 2 -10

调优示例代码

from sklearn.model_selection import GridSearchCV

# 定义参数网格
param_grid = {'max_depth': [2, 3, 5, 7],
    'n_estimators': [50, 100, 200],
    'min_samples_split': [2, 5, 10]
}

# 网格搜索
grid_search = GridSearchCV(RandomForestClassifier(random_state=42),
    param_grid,
    cv=5,
    n_jobs=-1
)
grid_search.fit(X_train, y_train)

print(f"Best params: {grid_search.best_params_}")
print(f"Best score: {grid_search.best_score_:.2f}")

避坑指南

常见问题及解决方案

  1. 数据泄露:
  2. 错误:在预处理时对整个数据集进行标准化
  3. 正确:只在训练集上拟合 scaler,然后转换测试集

  4. 过拟合:

  5. 现象:训练集准确率高,测试集低
  6. 解决:减小 max_depth,增加 min_samples_split

  7. 类别不平衡:

  8. 现象:少数类识别率低
  9. 解决:使用 class_weight=’balanced’

  10. 随机性导致结果不稳定:

  11. 现象:每次运行结果不同
  12. 解决:设置 random_state 固定随机种子

性能分析与可视化

准确率对比

# 模型比较
models = {
    'Single Tree': single_tree,
    'Random Forest': rf,
    'AdaBoost': ada
}

for name, model in models.items():
    pred = model.predict(X_test)
    print(f"{name} Accuracy: {accuracy_score(y_test, pred):.2f}")

决策边界可视化

# 可视化函数
def plot_decision_boundary(model, X, y, title):
    # 只使用前两个特征
    X = X[:, :2]
    model.fit(X, y)

    # 创建网格
    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, 0.02),
                         np.arange(y_min, y_max, 0.02))

    # 预测
    Z = model.predict(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)

    # 绘图
    plt.contourf(xx, yy, Z, alpha=0.8)
    plt.scatter(X[:, 0], X[:, 1], c=y, edgecolor='k')
    plt.title(title)
    plt.xlabel(iris.feature_names[0])
    plt.ylabel(iris.feature_names[1])
    plt.show()

# 绘制比较
plot_decision_boundary(single_tree, X_train, y_train, "Single Tree")
plot_decision_boundary(rf, X_train, y_train, "Random Forest")
plot_decision_boundary(ada, X_train, y_train, "AdaBoost")

延伸思考

  1. 如果数据集特征更多(比如几十个),哪些集成方法会表现更好?为什么?
  2. 对于类别极度不平衡的数据集(如欺诈检测),如何调整集成学习方法?
  3. 除了准确率,还有哪些指标更适合评估多分类问题?如何用 scikit-learn 计算这些指标?

通过这个实战练习,我们可以看到集成学习方法相比单决策树确实能够提高分类准确率,尤其是在区分相似类别时。建议读者尝试调整不同参数,观察模型性能变化,并扩展到其他数据集上应用这些技术。

正文完
 0
评论(没有评论)