【机器学习】决策树

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

决策树的基本原理

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

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

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

决策树的分割准则

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

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

相关推荐
that's boy5 分钟前
突围边缘:OpenAI开源实时嵌入式API,AI触角延伸至微观世界
人工智能·gpt·chatgpt·开源·openai·midjourney
司南OpenCompass8 分钟前
顶会评测集解读-AlignBench: 大语言模型中文对齐基准
人工智能·语言模型·自然语言处理·大模型评测
杨浦老苏11 分钟前
开源PDF翻译工具PDFMathTranslate
人工智能·docker·ai·pdf·群晖·翻译
地中海~20 分钟前
DENIAL-OF-SERVICE POISONING ATTACKS ON LARGE LANGUAGE MODELS
人工智能·语言模型·自然语言处理
边缘计算社区1 小时前
首个!艾灵参编的工业边缘计算国家标准正式发布
大数据·人工智能·边缘计算
游客5201 小时前
opencv中的各种滤波器简介
图像处理·人工智能·python·opencv·计算机视觉
一位小说男主1 小时前
编码器与解码器:从‘乱码’到‘通话’
人工智能·深度学习
深圳南柯电子2 小时前
深圳南柯电子|电子设备EMC测试整改:常见问题与解决方案
人工智能
Kai HVZ2 小时前
《OpenCV计算机视觉》--介绍及基础操作
人工智能·opencv·计算机视觉