一、决策树定义

决策树是一种监督学习算法,可用于**分类(Classification)回归(Regression)**任务。

它的结构类似树状结构:

  • 内部节点:特征条件(如X > 2
  • 叶子节点:输出类别或数值
  • 路径:对应一系列条件组合

二、决策树的基本概念

1. 信息熵(Entropy)

衡量样本集合的不确定性:

H(D)=−∑k=1Kpklog⁡2pk H(D) = - \sum_{k=1}^{K} p_k \log_2 p_k H(D)=k=1Kpklog2pk

其中:

  • DDD:样本集合
  • pkp_kpk:类别 kkk 的概率

2. 信息增益(Information Gain)

衡量某特征对信息熵的降低程度:

IG(D,A)=H(D)−∑v=1V∣Dv∣∣D∣H(Dv) IG(D, A) = H(D) - \sum_{v=1}^{V} \frac{|D^v|}{|D|} H(D^v) IG(D,A)=H(D)v=1VDDvH(Dv)

  • DvD^vDv:按特征 AAA 值划分的子集
  • 常用于 ID3 算法

3. 信息增益率(Gain Ratio)

用于 C4.5 算法,避免信息增益偏好取值多的特征:

GainRatio(D,A)=IG(D,A)IV(A) \text{GainRatio}(D, A) = \frac{IG(D, A)}{IV(A)} GainRatio(D,A)=IV(A)IG(D,A)

  • IV(A)=−∑v=1V∣Dv∣∣D∣log⁡2∣Dv∣∣D∣IV(A) = -\sum_{v=1}^V \frac{|D^v|}{|D|} \log_2 \frac{|D^v|}{|D|}IV(A)=v=1VDDvlog2DDv

4. Gini系数(Gini Impurity)

CART 分类算法使用的分裂标准:

Gini(D)=1−∑k=1Kpk2 Gini(D) = 1 - \sum_{k=1}^{K} p_k^2 Gini(D)=1k=1Kpk2

越小表示纯度越高。


5. 均方误差(MSE)

用于决策树回归:

MSE=1N∑i=1N(yi−y^)2 MSE = \frac{1}{N} \sum_{i=1}^N (y_i - \hat{y})^2 MSE=N1i=1N(yiy^)2

其中 y^\hat{y}y^ 是某叶子节点上的预测值。


三、决策树的算法流程(以分类为例)

  1. 选择最优划分特征

    • 使用信息增益 / 信息增益率 / Gini 系数
  2. 划分数据集

    • 递归构建子树
  3. 停止条件

    • 数据已纯净 / 特征用尽 / 达到最大深度
  4. 剪枝(可选)

    • 预剪枝 / 后剪枝,防止过拟合

四、实际示例

我们用一个简单的例子说明:

天气温度湿度打球
正常
正常
正常

目标是预测“是否打球”。


五、代码实现

示例使用 Python + scikit-learn 实现

(1)决策树分类 + 可视化

from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier, plot_tree
import matplotlib.pyplot as plt# 加载数据
X, y = load_iris(return_X_y=True)# 创建模型
clf = DecisionTreeClassifier(criterion='entropy', max_depth=3)
clf.fit(X, y)# 预测
y_pred = clf.predict(X[:5])
print("预测结果:", y_pred)# 可视化
plt.figure(figsize=(12, 8))
plot_tree(clf, filled=True, feature_names=load_iris().feature_names, class_names=load_iris().target_names)
plt.show()

(2)决策树回归 + 可视化

from sklearn.tree import DecisionTreeRegressor
import numpy as np
import matplotlib.pyplot as plt# 模拟数据
X = np.sort(5 * np.random.rand(80, 1), axis=0)
y = np.sin(X).ravel() + np.random.normal(0, 0.1, X.shape[0])# 模型训练
reg = DecisionTreeRegressor(max_depth=4)
reg.fit(X, y)# 可视化预测
X_test = np.arange(0.0, 5.0, 0.01)[:, np.newaxis]
y_pred = reg.predict(X_test)plt.figure(figsize=(10, 6))
plt.scatter(X, y, s=20, edgecolor="black", c="darkorange", label="data")
plt.plot(X_test, y_pred, color="cornflowerblue", label="prediction")
plt.legend()
plt.title("Decision Tree Regression")
plt.show()

六、超参数 & 控制项

参数说明
criterion划分标准(gini, entropy, squared_error
max_depth最大深度
min_samples_split内部节点最小样本数
min_samples_leaf叶子节点最小样本数
max_features用于划分的特征数

七、剪枝技巧

决策树容易过拟合训练数据,特别是当树结构过深时。剪枝用于控制模型复杂度,提高泛化能力。


1、剪枝类型概览

类型说明
预剪枝(Pre-Pruning)在构建过程中限制深度、叶子样本数等
后剪枝(Post-Pruning)构建完决策树后,自底向上裁剪不必要的分支

本内容聚焦在 后剪枝实现


2、后剪枝算法思想

基本流程:

  1. 从叶子节点向上回溯每个子树
  2. 判断当前子树(有分支) vs 将其剪成叶子节点谁的准确率更高(或损失更小)
  3. 若剪枝后效果更好 ⇒ 剪枝(用子树上样本的多数类替代)

3、后剪枝代码实现(基于自己实现的决策树)

下面是一个简洁的 ID3 决策树分类 + 后剪枝的完整实现:

1. 数据准备
from collections import Counter# 简化示例数据
data = [['晴', '高', '弱', '否'],['晴', '高', '强', '否'],['阴', '高', '弱', '是'],['雨', '中', '弱', '是'],['雨', '低', '弱', '是'],['雨', '低', '强', '否'],['阴', '低', '强', '是']
]# 特征名称
features = ['天气', '温度', '风']

2. 构建决策树(ID3)
def entropy(data):labels = [row[-1] for row in data]counter = Counter(labels)total = len(data)return -sum((count/total) * (count/total).bit_length() for count in counter.values())def split_dataset(data, axis, value):return [row[:axis] + row[axis+1:] for row in data if row[axis] == value]def choose_best_feature(data):base_entropy = entropy(data)best_gain = 0best_feature = -1num_features = len(data[0]) - 1for i in range(num_features):values = set(row[i] for row in data)new_entropy = 0for val in values:subset = split_dataset(data, i, val)prob = len(subset) / len(data)new_entropy += prob * entropy(subset)gain = base_entropy - new_entropyif gain > best_gain:best_gain = gainbest_feature = ireturn best_featuredef majority_class(data):labels = [row[-1] for row in data]return Counter(labels).most_common(1)[0][0]def build_tree(data, features):labels = [row[-1] for row in data]if labels.count(labels[0]) == len(labels):return labels[0]if len(features) == 0:return majority_class(data)best_feat = choose_best_feature(data)best_feat_name = features[best_feat]tree = {best_feat_name: {}}feat_values = set(row[best_feat] for row in data)sub_features = features[:best_feat] + features[best_feat+1:]for val in feat_values:subset = split_dataset(data, best_feat, val)tree[best_feat_name][val] = build_tree(subset, sub_features)return tree

3. 后剪枝实现
def classify(tree, features, sample):if not isinstance(tree, dict):return treeroot = next(iter(tree))sub_tree = tree[root]idx = features.index(root)value = sample[idx]subtree = sub_tree.get(value)if not subtree:return Nonereturn classify(subtree, features, sample)def accuracy(tree, features, data):correct = 0for row in data:if classify(tree, features, row[:-1]) == row[-1]:correct += 1return correct / len(data)def prune_tree(tree, features, data):if not isinstance(tree, dict):return treeroot = next(iter(tree))idx = features.index(root)new_tree = {root: {}}for val, subtree in tree[root].items():subset = [row for row in data if row[idx] == val]if not subset:new_tree[root][val] = subtreeelse:pruned_subtree = prune_tree(subtree, features[:idx] + features[idx+1:], split_dataset(data, idx, val))new_tree[root][val] = pruned_subtree# 尝试剪枝为单叶节点flat_labels = [row[-1] for row in data]majority = majority_class(data)# 原树精度original_acc = accuracy(new_tree, features, data)# 剪枝后精度(所有预测为多数类)pruned_acc = flat_labels.count(majority) / len(flat_labels)if pruned_acc >= original_acc:return majorityelse:return new_tree

4. 使用示例
# 构建树
tree = build_tree(data, features)
print("原始决策树:", tree)# 后剪枝
pruned = prune_tree(tree, features, data)
print("剪枝后树:", pruned)

4、剪枝效果展示(示意)

原始决策树:
{'天气': {'雨': {'风': {'弱': '是', '强': '否'}},'阴': '是','晴': {'风': {'弱': '否', '强': '否'}}
}}剪枝后树:
{'天气': {'雨': '是','阴': '是','晴': '否'
}}

八、优缺点总结

优点:

  • 易理解,树结构直观
  • 可处理分类与回归
  • 可解释性强

缺点:

  • 容易过拟合
  • 对小变化敏感
  • 对连续变量划分不如 ensemble 方法鲁棒

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/91745.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/91745.shtml
英文地址,请注明出处:http://en.pswp.cn/web/91745.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis集群分布式(Redis Cluster)底层实现原理详细介绍

文章目录一、Redis集群概念二、集群节点1. 节点如何启动2. 节点的集群数据结构2.1 clusterNode结构2.2 clusterLink结构2.3 clusterState结构3. 节点如何加入集群三、数据分片机制1. 记录节点的槽指派信息2. 传播节点的槽指派信息3. 记录集群所有槽的指派信息4. 节点的槽指派命…

【走遍美国精讲笔记】第 1 课:林登大街 46 号

ACT 1-1 “我可以给您和您的小男孩拍张照吗?” 【故事梗概】 自由摄影艺术家 Richard Stewart,正在为编出自己的影集《走遍美国》到处拍照。今天他在由纽约市曼哈顿区到斯塔滕岛的渡船上工 作,回程中遇到了来自加州的一位黑人妇女 Martha Van…

Java中Lambda 表达式的解释

从 Java 8 开始,Lambda 表达式成为 Java 的一等公民。它不仅让代码更简洁,还为函数式编程打开了大门。如果你还没真正理解或使用过 Lambda,这篇文章就是为你写的。一、什么是 Lambda 表达式?Lambda 表达式是 Java 中的一种匿名函数…

Spring AI调用Embedding模型返回HTTP 400:Invalid HTTP request received分析处理

调用Embedding模型失败 Spring AI项目使用的Embedding模型是公司平台部署的,请求模型服务的时候报错,返回了HTTP 400 - Invalid HTTP request received错误。然后换成云厂商在线Embedding模型地址,正常调通。我用Apifox直接调用公司的模型服务…

Pytorch-02数据集和数据加载器的基本原理和基本操作

1. 为什么要有数据集类和数据加载器类? 一万个人会有一万种获取并处理原始数据样本的代码,这会导致对数据的操作代码标准不一,并且很难复用。为了解决这个问题,Pytorch提供了两种最基本的数据相关类: torch.utils.data…

无图形界面的CentOS 7网络如何配置

进入虚拟机输入ip addr命令:从 ip addr命令的输出可以明确看出 ​​lo和 ens33是两个不同的网络接口(网卡)lo(回环接口)​​​​作用​​:虚拟的本地回环网卡,用于本机内部通信(如 1…

机器学习之线性回归的入门学习

线性回归是一种监督学习算法,用于解决回归问题。它的目标是找到一个线性关系(一条直线或一个超平面),能够最好地描述一个或多个自变量(特征)与一个因变量(目标)之间的关系。利用回归…

2-5 Dify案例实践—利用RAG技术构建企业私有知识库

目录 一、RAG技术的定义与作用 二、RAG技术的关键组件 三、RAG技术解决的问题 四、RAG技术的核心价值与应用场景 五、如何实现利用RAG技术构建企业私有知识库 六、Dify知识库实现详解 七、创建知识库 1、创建知识库 2、上传文档 3、文本分段与清洗 4、索引方式 5、…

断路器瞬时跳闸曲线数据获取方式

断路器瞬时短路电流时,时间是在60ms内的,仿真器去直接捕获电流有效值很难。按照电流互感器的电流曲线特性,电流越大,由于互感器饱和,到达一定电流值的时候,电流会趋于平稳不再上升,ADC-I曲线由线…

技巧|SwanLab记录混淆矩阵攻略

绘制混淆矩阵(Confusion Matrix),用于评估分类模型的性能。混淆矩阵展示了模型预测结果与真实标签之间的对应关系,能够直观地显示各类别的预测准确性和错误类型。 混淆矩阵是评估分类模型性能的基础工具,特别适用于多…

HTTPS的工作原理

文章目录HTTP有什么问题?1. 明文传输,容易被窃听2. 无法验证通信方身份3. 数据完整性无法保证HTTPS是如何解决这些问题的?HTTPS的工作原理1. SSL/TLS握手2. 数据加密传输3. 完整性保护4. 连接关闭总结HTTP有什么问题? 1. 明文传输…

ECMAScript2020(ES11)新特性

概述 ECMAScript2020于2020年6月正式发布, 本文会介绍ECMAScript2020(ES11),即ECMAScript的第11个版本的新特性。 以下摘自官网:ecma-262 ECMAScript 2020, the 11th edition, introduced the matchAll method for Strings, to produce an …

机器视觉引导机器人修磨加工系统助力芯片封装

芯片制造中,劈刀同轴度精度对封装质量至关重要。传统加工在精度、效率、稳定性、良率及操作便捷性上存在不足:精度不足:劈刀同轴度需控在 0.003mm 内,传统手段难达标,致芯片封装良率低;效率良率低 &#xf…

Python编程基础与实践:Python模块与包入门实践

Python模块与包的深度探索 学习目标 通过本课程的学习,学员将掌握Python中模块和包的基本概念,了解如何导入和使用标准库中的模块,以及如何创建和组织自己的模块和包。本课程将通过实际操作,帮助学员加深对Python模块化编程的理解…

【Django】-4- 数据库存储和管理

一、关于ORM ORM 是啥呀ORM 就是用 面向对象 的方式,把数据库里的数据还有它们之间的关系映射起来~就好像给数据库和面向对象之间搭了一座小桥梁🎀对应关系大揭秘面向对象和数据库里的东西,有超有趣的对应呢👇类 → 数…

深入 Go 底层原理(四):GMP 模型深度解析

1. 引言在上一篇文章中,我们宏观地了解了 Go 的调度策略。现在,我们将深入到构成这个调度系统的三大核心组件:G、M、P。理解 GMP 模型是彻底搞懂 Go 并发调度原理的关键。本文将详细解析 G、M、P 各自的职责以及它们之间是如何协同工作的。2.…

AI赋能测试:技术变革与应用展望

AI 在测试中的应用:技术赋能与未来展望 目录 AI 在测试中的应用:技术赋能与未来展望 1. 引言 1.1 测试在软件开发中的重要性 1.2 AI 技术如何改变传统测试模式 1.3 文章结构概述 2. AI 在测试中的核心应用场景 2.1 自动化测试优化 2.1.1 智能测…

Mujoco(MuJoCo,全称Multi - Joint dynamics with Contact)一种高性能的物理引擎

Mujoco(MuJoCo,全称Multi - Joint dynamics with Contact)是一种高性能的物理引擎,主要用于模拟多体动力学系统,广泛应用于机器人仿真、运动学研究、人工智能等领域。以下是关于Mujoco仿真的一些详细介绍: …

winform-窗体应用的功能介绍(部分)

1--Point实现在窗口(Form)中一个按钮(控件)的固定位置(所在位置)一个按钮(控件)的位置一般是固定的,另一个按钮在窗口中位置是随机产生的Location属性:Location new Point(X,Y);在C#的Winform应用程序里,Button控件的鼠标悬标悬浮事件是不存在内置延迟时间的。当鼠标指针进入按…

最新Windows11系统镜像,23H2 64位ISO镜像

Windows 11 主要分为 Consumer Editions(消费者版)和 Business Editions(商业版)两大类别 。消费者版主要面向家庭和个人用户,商业版则侧重于企业和商业用户。这两大类别中存在部分重叠的版本,比如专业版和…