【机器学习】决策树

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

决策树的基本原理

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

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

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

决策树的分割准则

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

  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 中使用决策树的便捷方式。决策树算法易于理解且解释性强,在多种任务中应用广泛,适合初学者掌握和使用。

相关推荐
阡之尘埃2 小时前
Python数据分析案例61——信贷风控评分卡模型(A卡)(scorecardpy 全面解析)
人工智能·python·机器学习·数据分析·智能风控·信贷风控
孙同学要努力4 小时前
全连接神经网络案例——手写数字识别
人工智能·深度学习·神经网络
Eric.Lee20214 小时前
yolo v5 开源项目
人工智能·yolo·目标检测·计算机视觉
其实吧35 小时前
基于Matlab的图像融合研究设计
人工智能·计算机视觉·matlab
丕羽5 小时前
【Pytorch】基本语法
人工智能·pytorch·python
ctrey_5 小时前
2024-11-1 学习人工智能的Day20 openCV(2)
人工智能·opencv·学习
SongYuLong的博客5 小时前
Air780E基于LuatOS编程开发
人工智能
Jina AI5 小时前
RAG 系统的分块难题:小型语言模型如何找到最佳断点?
人工智能·语言模型·自然语言处理
-派神-5 小时前
大语言模型(LLM)量化基础知识(一)
人工智能·语言模型·自然语言处理
johnny_hhh5 小时前
AI大模型重塑软件开发流程:定义、应用场景、优势、挑战及未来展望
人工智能