【机器学习】决策树

决策树是一种用于分类和回归任务的监督学习算法,它以树形结构递归地将数据分割成不同区域,使得最终的预测值尽可能纯净(即减少分类问题中的混杂度,或回归问题中的误差)。决策树算法简单直观、易于理解、解释性强,广泛应用于各类场景。本教程将详细介绍决策树的原理,重点解析构建决策树过程中的关键概念及其实现。

决策树的基本原理

决策树基于"树"结构构建模型,其中:

  • 根节点代表整个数据集。
  • 分支表示不同的特征条件分割路径。
  • 叶节点是最终的类别(或预测值)。

决策树的构建过程通过递归地选择最佳特征来分割数据,直到满足某个终止条件(如达到最大深度或叶节点纯度)。在决策树中,每次分割的数据称为"分支",直到数据被分割成多个不相交的区域为止。

决策树的分割准则

常用的决策树分割准则包括:

  1. 分类问题 中常用的指标:
    • 信息增益:基于信息熵计算,用于评估特征对数据的纯度贡献。
    • 基尼系数:用于衡量数据集的混乱程度。
  2. 回归问题 中常用的指标:
    • 均方误差(MSE):用于最小化预测值与实际值的平方差。
    • 均绝对误差(MAE):用于最小化预测值与实际值的绝对差。

构建决策树的步骤

  1. 选择最优特征进行分裂:根据指标(如信息增益或基尼系数)选择最优特征分割数据。
  2. 递归分割:对子节点继续分割,直到满足停止条件。
  3. 生成叶节点:一旦满足停止条件,不再继续分割,将该节点标记为叶节点。

信息增益与基尼系数的计算

信息熵和信息增益

**信息熵(Entropy)**衡量了数据的纯度或混乱度,熵越小数据越纯。对于一个二分类问题的标签 ( Y ),若其取值为 ( 0 ) 和 ( 1 ) 的概率分别为 ( p ) 和 ( 1 - p ),信息熵公式如下:
H ( Y ) = − ∑ p i log ⁡ 2 p i H(Y) = - \sum p_i \log_2 p_i H(Y)=−∑pilog2pi
信息增益表示分割前后信息熵的减少量,用于选择最佳分割特征。

基尼系数(Gini Impurity)

基尼系数 是另一种衡量混乱度的方法,其公式如下:
G ( Y ) = 1 − ∑ p i 2 G(Y) = 1 - \sum p_i^2 G(Y)=1−∑pi2

其中 ( p_i ) 为第 ( i ) 类的概率。基尼系数越小,数据集的纯度越高。

用 Numpy 实现决策树(分类)

以下代码展示了如何用 Numpy 实现简单的决策树,基于基尼系数选择最优分裂特征。

python 复制代码
import numpy as np
import matplotlib.pyplot as plt

# 定义基尼系数计算函数
def gini_impurity(y):
    _, counts = np.unique(y, return_counts=True)
    probabilities = counts / counts.sum()
    return 1 - np.sum(np.square(probabilities))

# 基于特征划分数据集
def split_dataset(X, y, feature, threshold):
    left_mask = X[:, feature] <= threshold
    right_mask = ~left_mask
    return X[left_mask], y[left_mask], X[right_mask], y[right_mask]

# 查找最佳分割点
def best_split(X, y):
    best_gini = 1
    best_feature, best_threshold = None, None
    for feature in range(X.shape[1]):
        thresholds = np.unique(X[:, feature])
        for threshold in thresholds:
            _, y_left, _, y_right = split_dataset(X, y, feature, threshold)
            if len(y_left) == 0 or len(y_right) == 0:
                continue
            gini_left = gini_impurity(y_left)
            gini_right = gini_impurity(y_right)
            gini_split = (len(y_left) * gini_left + len(y_right) * gini_right) / len(y)
            if gini_split < best_gini:
                best_gini = gini_split
                best_feature = feature
                best_threshold = threshold
    return best_feature, best_threshold, best_gini

# 决策树类
class DecisionTree:
    def __init__(self, max_depth=3):
        self.max_depth = max_depth
        self.tree = None

    def fit(self, X, y, depth=0):
        feature, threshold, gini = best_split(X, y)
        if feature is None or depth >= self.max_depth:
            return np.argmax(np.bincount(y))
        left_X, left_y, right_X, right_y = split_dataset(X, y, feature, threshold)
        left_node = self.fit(left_X, left_y, depth + 1)
        right_node = self.fit(right_X, right_y, depth + 1)
        self.tree = {"feature": feature, "threshold": threshold, "left": left_node, "right": right_node}
        return self.tree

    def predict_sample(self, x, tree):
        if not isinstance(tree, dict):
            return tree
        if x[tree["feature"]] <= tree["threshold"]:
            return self.predict_sample(x, tree["left"])
        else:
            return self.predict_sample(x, tree["right"])

    def predict(self, X):
        return np.array([self.predict_sample(x, self.tree) for x in X])

# 数据生成
X = np.array([[2, 3], [1, 1], [3, 2], [4, 3], [3, 4]])
y = np.array([0, 0, 1, 1, 0])

# 训练决策树
tree = DecisionTree(max_depth=3)
tree.fit(X, y)

# 预测并可视化
preds = tree.predict(X)
print("预测结果:", preds)

# 可视化决策边界
plt.scatter(X[:, 0], X[:, 1], c=y, cmap='coolwarm')
plt.xlabel("特征 1")
plt.ylabel("特征 2")
plt.title("决策树分割示意图")
plt.show()

在 Sklearn 中使用决策树

在 Sklearn 中,我们可以直接使用 DecisionTreeClassifierDecisionTreeRegressor 来进行分类和回归任务,简化了构建和预测流程。

python 复制代码
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score

# 训练决策树
clf = DecisionTreeClassifier(max_depth=3)
clf.fit(X, y)

# 预测
preds_sklearn = clf.predict(X)
print("Sklearn 预测结果:", preds_sklearn)

# 计算准确率
accuracy = accuracy_score(y, preds_sklearn)
print("准确率:", accuracy)

总结

本文从基本原理出发,详细介绍了决策树的分割准则及构建流程,并使用 Numpy 实现了一个基础的决策树分类器,最后展示了在 Sklearn 中使用决策树的便捷方式。决策树算法易于理解且解释性强,在多种任务中应用广泛,适合初学者掌握和使用。

相关推荐
勾股导航17 小时前
大模型Skill
人工智能·python·机器学习
卷福同学19 小时前
【养虾日记】Openclaw操作浏览器自动化发文
人工智能·后端·算法
春日见19 小时前
如何入门端到端自动驾驶?
linux·人工智能·算法·机器学习·自动驾驶
光锥智能19 小时前
从自动驾驶到 AI 能力体系,元戎启行 GTC 发布基座模型新进展
人工智能
luoganttcc19 小时前
自动驾驶 世界模型 有哪些
人工智能·机器学习·自动驾驶
潘高19 小时前
10分钟教你手撸一个小龙虾(OpenClaw)
人工智能
禁默19 小时前
光学与机器视觉:解锁“机器之眼”的核心密码-《第五届光学与机器视觉国际学术会议(ICOMV 2026)》
人工智能·计算机视觉·光学
2401_8769075219 小时前
Python机器学习实践指南
开发语言·python·机器学习
深小乐20 小时前
不是DeepSeek V4!这两个神秘的 Hunter 模型竟然来自小米
人工智能
laozhao43220 小时前
科大讯飞中标教育管理应用升级开发项目
大数据·人工智能