经典决策树分类实战:从原理到Python实现

1次阅读
没有评论

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

image.webp

背景痛点分析

决策树作为机器学习中最直观的算法之一,初学者常会遇到两个关键问题:

经典决策树分类实战:从原理到 Python 实现

  1. 特征选择困惑 :信息增益(ID3)和基尼系数(CART)都是常用标准,但新手往往不理解它们的数学本质差异。信息增益倾向于选择取值多的特征,而基尼系数对类别分布更敏感。

  2. 过拟合问题 :未经剪枝的决策树会生成复杂的树结构,在训练集上表现完美但测试集性能骤降。典型表现是决策边界出现不合理的锯齿状分裂。

算法对比

算法 分裂标准 支持特征类型 适用场景
ID3 信息增益 仅分类特征 小规模离散数据
C4.5 信息增益比 分类 + 连续 存在噪声数据
CART 基尼系数 / 方差 分类 + 连续 回归和分类任务

核心原理实现

信息增益计算

信息熵定义:

$$H(D) = -\sum_{k=1}^K p_k \log_2 p_k$$

特征 A 对数据集 D 的信息增益:

$$Gain(D,A) = H(D) – \sum_{v=1}^V \frac{|D^v|}{|D|}H(D^v)$$

Python 代码实现

from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

def train_decision_tree(
    criterion: str = 'gini', 
    max_depth: int = 3
) -> DecisionTreeClassifier:
    """
    训练决策树分类器

    Parameters
    ----------
    criterion : str
        分裂标准 ('gini'/'entropy')
    max_depth : int
        树的最大深度

    Returns
    -------
    DecisionTreeClassifier
        训练好的模型实例
    """
    X, y = load_iris(return_X_y=True)
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

    clf = DecisionTreeClassifier(
        criterion=criterion,
        max_depth=max_depth,
        random_state=42
    )
    clf.fit(X_train, y_train)
    return clf

# 示例调用
model = train_decision_tree(criterion='entropy', max_depth=3)

生产实践技巧

预剪枝效果演示

通过调整 max_depth 参数观察模型复杂度变化:

import matplotlib.pyplot as plt
from sklearn.metrics import accuracy_score

depths = range(1, 10)
train_scores = []
test_scores = []

for depth in depths:
    model = train_decision_tree(max_depth=depth)
    train_scores.append(accuracy_score(y_train, model.predict(X_train)))
    test_scores.append(accuracy_score(y_test, model.predict(X_test)))

plt.plot(depths, train_scores, label='Train')
plt.plot(depths, test_scores, label='Test')
plt.xlabel('Max Depth')
plt.ylabel('Accuracy')
plt.legend()

特征重要性可视化

importances = model.feature_importances_
features = ['sepal length', 'sepal width', 'petal length', 'petal width']

plt.barh(features, importances)
plt.xlabel('Feature Importance')
plt.ylabel('Features')

避坑指南

  1. 类别不平衡处理 :
  2. 使用 class_weight 参数调整类别权重
  3. 对少数类样本进行过采样

  4. 深度调试经验 :

  5. 二分类问题建议初始尝试深度 3 -5
  6. 特征较多时可设置 max_leaf_nodes 控制复杂度

延伸思考

  1. 超参数优化 :

    from sklearn.model_selection import GridSearchCV
    
    params = {'max_depth': [3,5,7],
        'min_samples_split': [2,5,10]
    }
    grid_search = GridSearchCV(DecisionTreeClassifier(), params, cv=5)

  2. 连续特征处理 :

  3. CART 算法通过排序后寻找最佳分裂点
  4. 实际应用中建议先做分箱处理
正文完
 0
评论(没有评论)