当前位置: 首页 > news >正文

决策树基础

决策树

定义

从根节点开始,也就是拥有全部的数据,找一个维度对根节点开始划分,

划分后希望数据整体的信息熵是最小的,

针对划分出来的两个节点,我们继续重复刚才的划分方式寻找信息熵最小的维度和阈值。

递归这个过程就形成了决策树。

特点

非参数学习算法

可以解决分类问题

天然可以解决多分类问题

非常好的可解释性

代码实现

sklearn封装的方式

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.tree import DecisionTreeClassifier
# 学习使用数据集,去后两个维度,便于可视化
iris = datasets.load_iris()
X = iris.data[:, 2:]
y = iris.target

dt_clf = DecisionTreeClassifier(max_depth=2, criterion="entropy", random_state=42)
dt_clf.fit(X, y)

# 画图函数
def plot_decision_boundary(model, axis):
    x0, x1 = np.meshgrid(
        np.linspace(axis[0], axis[1], int((axis[1] - axis[0]) * 100)).reshape(-1, 1),
        np.linspace(axis[2], axis[3], int((axis[3] - axis[2]) * 100)).reshape(-1, 1),
    )
    X_new = np.c_[x0.ravel(), x1.ravel()]
    y_predict = model.predict(X_new)
    zz = y_predict.reshape(x0.shape)
    from matplotlib.colors import ListedColormap
    custom_cmap = ListedColormap(["#EF9A9A", "#FFF59D", "#90CAF9"])
    plt.contourf(x0, x1, zz, cmap=custom_cmap)

plot_decision_boundary(dt_clf, axis=[0.5, 7.5, 0, 3])
# X[y==0,0]表示样本target为0的,第一个维度,其余类推
plt.scatter(X[y == 0, 0], X[y == 0, 1])
plt.scatter(X[y == 1, 0], X[y == 1, 1])
plt.scatter(X[y == 2, 0], X[y == 2, 1])
plt.show()

在这里插入图片描述

信息熵(重要知识)

熵在信息论中代表:随机变量不确定度的度量。

熵越大,数据的不确定性越高;熵越小,数据的不确定性越低,公式如下:
H = − ∑ i − 1 k p i log ⁡ ( p i ) p i 类别  i  的概率 H = -\sum^{k}_{i-1} p_{i}\log(p_{i}) \\ p_{i} 类别\ i \ 的概率 H=i1kpilog(pi)pi类别 i 的概率
如以下两组数据的随机分布如下:
{ 1 3 , 1 3 , 1 3 } H = − 1 3 log ⁡ 1 3 − 1 3 log ⁡ 1 3 − 1 3 log ⁡ 1 3 = 1.0986 { 1 10 , 2 10 , 7 10 } H = − 1 10 log ⁡ 1 10 − 2 10 log ⁡ 2 10 − 7 10 log ⁡ 7 10 = 0.8018 \{\frac{1}{3},\frac{1}{3},\frac{1}{3}\} \\ H = -\frac{1}{3}\log{\frac{1}{3}}-\frac{1}{3}\log{\frac{1}{3}}-\frac{1}{3}\log{\frac{1}{3}} = 1.0986 \\ \\ \{\frac{1}{10},\frac{2}{10},\frac{7}{10}\} \\ H = -\frac{1}{10}\log{\frac{1}{10}}-\frac{2}{10}\log{\frac{2}{10}}-\frac{7}{10}\log{\frac{7}{10}} = 0.8018 \\ {31,31,31}H=31log3131log3131log31=1.0986{101,102,107}H=101log101102log102107log107=0.8018

二分类问题信息熵的公式可化简为:
H = − x log ⁡ ∗ ( x ) − ( 1 − x ) log ⁡ ( 1 − x ) H = -x\log*(x) - (1-x)\log(1-x) H=xlog(x)(1x)log(1x)

import numpy as np
import matplotlib.pyplot as plt
def entropy(p):
    return -p * np.log(p) - (1-p) * np.log(1-p)
x = np.linspace(0.01, 0.99, 200)
plt.plot(x, entropy(x))
plt.show()

在这里插入图片描述

最小化信息熵划分数据维度和阈值,模拟sklearn中的封装方法

import numpy as np
from collections import Counter
from math import log
from sklearn import datasets

iris = datasets.load_iris()
X = iris.data[:, 2:]
y = iris.target

def split(X, y, d, value):
    """
    函数功能:根据给定的特征维度d和阈值value,将数据集进行划分
    X、y分别是数据样本和标签
    d是数据的某一个维度
    value是d维度上的一个阈值
    """
    # 寻找所有数据集中维度为d且小于等于value的bool向量
    index_a = X[:, d] <= value
    index_b = X[:, d] > value
    return X[index_a], X[index_b], y[index_a], y[index_b]

def entropy(y):
    """
    计算信息熵
    y:类别标签, 类似[0,0,1,1,2,2,2,2]
    """
    counter = Counter(y)
    res = 0.0
    for num in counter.values():
        p_i = num / len(y)  # 计算每个类别的概率
        res += -p_i * log(p_i)
    return res

def try_split(X, y):
    """
    寻找传入数据的最优划分方案(信息熵最小)
    最优的维度和划分阈值
    """
    # 最优信息熵
    best_entropy = float("inf")
    best_d, best_v = -1, -1
    # 搜索过程:从d=0以及d这个维度升序后的相邻样本的均值开始
    for d in range(X.shape[1]):
        # 返回排序(升序)后索引
        sorted_index = np.argsort(X[:, d])
        for i in range(1, len(X)):
            if X[sorted_index[i], d] != X[sorted_index[i - 1], d]:
                # 候选阈值value的确认方式,且相邻的两个值不相等(剪枝)
                v = (X[sorted_index[i], d] + X[sorted_index[i - 1], d]) / 2
                X_l, X_r, y_l, y_r = split(X, y, d, v)

                p_l, p_r = len(X_l) / len(X), len(X_r) / len(X)  # 可以删除占比
                e = p_l * entropy(y_l) + p_r * entropy(y_r)
                if e < best_entropy:  # 更新最小熵、最优维度d以及该维度上的最优阈值v
                    best_entropy, best_d, best_v = e, d, v

    return best_entropy, best_d, best_v

best_entropy, best_d, best_v = try_split(X, y)
print("best_entropy =", best_entropy)
print("best_d =", best_d)
print("best_v =", best_v)
# best_entropy = 0.46209812037329684
# best_d = 0
# best_v = 2.45
# 解释:第一次划分在第0个维度上,阈值为2.45,信息熵最优

# 根据第一次的最优划分条件,对数据集进行划分
X1_l, X1_r, y1_l, y1_r = split(X, y, best_d, best_v)
entropy(y1_l)  # 0.0 y1_l信息熵为0,对应X1_l节点无需再划分
entropy(y1_r)  # y1_r信息熵0.6931471805599453,继续划分X1_r节点

best_entropy2, best_d2, best_v2 = try_split(X1_r, y1_r)
print("best_entropy =", best_entropy2)
print("best_d =", best_d2)
print("best_v =", best_v2)
# best_entropy = 0.2147644654371359
# best_d = 1
# best_v = 1.75

X2_l, X2_r, y2_l, y2_r = split(X1_r, y1_r, best_d2, best_v2)
entropy(y2_l) # 0.30849545083110386
entropy(y2_r)  # 0.10473243910508653
# 信息熵不为0还可以继续划分,此时深度为2

基尼系数

基尼系数公式如下:
G = 1 − ∑ i = 1 k p i 2 G = 1-\sum^{k}_{i=1}p_{i}^2 G=1i=1kpi2
基尼系数和信息熵拥有同样的性质。

基尼系数代码实现

from collections import Counter

def gini(y):
    counter = Counter(y)
    res = 1.0
    for num in counter.values():
        p = num / len(y)
        res -= p**2
    return res

CART

决策树又称:Classification And Regression Tree

复杂度分析:

预测: O ( l o g m ) O(logm) O(logm)

预测: O ( n ∗ m ∗ l o g m ) O(n*m*logm) O(nmlogm)

n 、 m n、m nm 分别是样本数量和数据维度。

决策树的局限性

1、决策数是在某一个维度上进行划分,所以产生的决策边界都是和数据维度平行的,并不会产生倾斜的边界,有时真实数据可能并非如此。

在这里插入图片描述

2、决策树会对个别的样本点是非常敏感的,某一个特殊的样本点可能都会改变决策树的决策边界。

相关文章:

  • 代码随想录算法训练营第38天 | 322. 零钱兑换 279.完全平方数 139.单词拆分 背包问题总结
  • “跨越时代的技术进步:CPU缓存如何塑造了智能手机和智能家居的未来?
  • 【2025】基于ssm+jsp的二手商城系统设计与实现(源码、万字文档、图文修改、调试答疑)
  • go-zero学习笔记
  • 第39章:CSI插件开发与定制化存储需求
  • Django框架视图与路由(一)
  • 我的Go学习路线概览
  • 关于 URH(Universal Radio Hacker) 的详细介绍、安装指南、配置方法及使用说明
  • Java 的 AutoCloseable 接口
  • 警翼(Pe)执法记录仪格式化后的恢复方法
  • 分类预测 | Matlab实现BO-GRU-Attention贝叶斯优化门控循环单元融合注意力机制多特征分类预测
  • 【系统稳定性】1.13 解析gcore
  • 京东一面:MySQL 主备延迟有哪些坑?主备切换策略
  • 【AI模型】深度解析:DeepSeek的联网搜索的实现原理与认知误区
  • 运功学-【机械臂】
  • 1.设备电气设计、装配的注意事项
  • C语言入门教程100讲(19)do-while 循环
  • 动态规划完全背包系列一>完全平方数
  • android......
  • Python学习笔记(4)
  • 解放日报:服务国家战略,加快建成科技创新高地
  • 周劼已任中国航天科技集团有限公司董事、总经理、党组副书记
  • 五部门:开展新就业形态劳动者劳动权益保障水平提升专项行动
  • 量子传感新技术“攻克”退相干难题
  • 俄罗斯纪念卫国战争胜利80周年阅兵式首次彩排在莫斯科举行
  • 力箭二号火箭成功进行满载起竖试验,计划今年首飞发射轻舟飞船