决策树基础:深入理解其核心工作原理

决策树基础:深入理解其核心工作原理

目录

  1. 引言
  2. 决策树的基本概念
    • 什么是决策树
    • 决策树的组成部分
  3. 决策树的工作原理
    • 特征选择
    • 信息增益
    • 基尼指数
  4. 决策树的生成
    • ID3 算法
    • C4.5 算法
    • CART 算法
  5. 决策树的剪枝
    • 预剪枝
    • 后剪枝
  6. 决策树的优缺点
    • 优点
    • 缺点
  7. 决策树的实现
    • Python 代码实现
    • Scikit-learn 实现
  8. 决策树的应用
  9. 总结

1. 引言

决策树是一种重要的机器学习算法,广泛应用于分类和回归任务。它通过构建一个树形模型,从而将输入特征空间划分成不同的类别或预测数值。本指南将详细介绍决策树的核心工作原理、生成算法、剪枝策略以及其实现方法,并结合实际案例和源码解析,帮助读者深入理解决策树的应用与实现。


2. 决策树的基本概念

什么是决策树

决策树是一种树状结构的模型,用于将数据集划分为更小的子集,并在这些子集中递归地进行决策。每个内部节点表示一个特征,每个分支表示一个特征值的划分,最终的叶节点表示一个类别或回归值。

决策树的组成部分

  1. 根节点(Root Node):决策树的顶点,表示整个数据集。
  2. 内部节点(Internal Nodes):每个内部节点代表一个特征,并根据该特征划分数据集。
  3. 叶节点(Leaf Nodes):最终的决策结果,表示类别标签或回归值。
  4. 分支(Branches):连接节点之间的路径,表示特征值的划分。

3. 决策树的工作原理

决策树通过递归地选择最优特征,将数据集划分为多个子集,并在这些子集上继续进行划分,直到满足停止条件为止。最优特征的选择通常基于某种度量标准,如信息增益或基尼指数。

特征选择

特征选择是决策树生成过程中最关键的一步。不同的特征选择方法会导致不同的树结构,从而影响模型的性能。常用的特征选择标准包括信息增益和基尼指数。

信息增益

信息增益是基于熵的概念来衡量特征的重要性。熵表示数据集的纯度,信息增益则表示通过划分数据集可以提升的纯度。

熵的定义为:

[ H(D) = - \sum_{i=1}^{k} p_i \log_2 p_i ]

其中,( p_i ) 表示类别 ( i ) 的概率。

信息增益的计算公式为:

[ IG(D, A) = H(D) - \sum_{v \in Values(A)} \frac{|D_v|}{|D|} H(D_v) ]

其中,( D ) 表示数据集,( A ) 表示特征,( D_v ) 表示特征 ( A ) 的值为 ( v ) 的子集。

基尼指数

基尼指数是另一种衡量数据集纯度的方法,广泛应用于分类与回归树(CART)算法中。基尼指数越小,数据集越纯。

基尼指数的定义为:

[ Gini(D) = 1 - \sum_{i=1}^{k} p_i^2 ]

其中,( p_i ) 表示类别 ( i ) 的概率。

特征 ( A ) 的基尼指数为:

[ Gini_A(D) = \sum_{v \in Values(A)} \frac{|D_v|}{|D|} Gini(D_v) ]


4. 决策树的生成

决策树的生成算法主要包括 ID3、C4.5 和 CART。它们在特征选择、处理缺失值和剪枝策略上有所不同。

ID3 算法

ID3 算法由 Ross Quinlan 提出,使用信息增益作为特征选择标准。以下是 ID3 算法的步骤:

  1. 计算数据集的熵。
  2. 计算每个特征的信息增益。
  3. 选择信息增益最大的特征作为节点,划分数据集。
  4. 对每个子集递归地应用上述步骤,直到所有特征都使用完或子集纯度达到阈值。

C4.5 算法

C4.5 是 ID3 的改进版本,解决了 ID3 的一些缺点,如处理连续值、缺失值和剪枝策略。C4.5 使用增益率(Gain Ratio)作为特征选择标准:

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

其中,信息值(IV)定义为:

[ IV(A) = - \sum_{v \in Values(A)} \frac{|D_v|}{|D|} \log_2 \frac{|D_v|}{|D|} ]

CART 算法

分类与回归树(CART)算法由 Leo Breiman 提出,使用基尼指数作为特征选择标准,适用于分类和回归任务。CART 生成的是二叉树,每个节点只根据一个特征划分数据集。


5. 决策树的剪枝

决策树容易过拟合,因此需要通过剪枝来控制树的复杂度。剪枝策略分为预剪枝和后剪枝。

预剪枝

预剪枝是在生成决策树的过程中,通过设定停止条件来避免生成过于复杂的树。这些条件可以是最大深度、最小样本数或信息增益阈值。

后剪枝

后剪枝是在生成完整决策树后,逐步去掉对模型贡献不大的节点。常用的后剪枝方法包括错误复杂度剪枝和代价复杂度剪枝。


6. 决策树的优缺点

优点

  1. 易于理解和解释:决策树结构直观,决策过程透明。
  2. 无需数据预处理:可以处理连续和离散数据,处理缺失值。
  3. 计算成本低:训练和预测的时间复杂度较低。
  4. 适用性广:适用于分类和回归任务。

缺点

  1. 容易过拟合:决策树容易生成过于复杂的模型,导致泛化性能差。
  2. 不稳定性:小的变化可能导致树结构的显著变化。
  3. 偏向多值特征:信息增益容易偏向取值较多的特征。

7. 决策树的实现

Python 代码实现

以下是使用 Python 从零实现决策树分类器的代码示例:

import numpy as np
import pandas as pdclass DecisionTreeClassifier:def __init__(self, max_depth=None):self.max_depth = max_depthdef fit(self, X, y):self.n_classes_ = len(set(y))self.n_features_ = X.shape[1]self.tree_ = self._grow_tree(X, y)def predict(self, X):return [self._predict(inputs) for inputs in X]def _grow_tree(self, X, y, depth=0):n_samples, n_features = X.shapeif depth >= self.max_depth or n_samples < 2:leaf_value = self._most_common_label(y)return Node(value=leaf_value)rnd_feats = np.random.choice(n_features, self.n_features_, replace=False)best_feat, best_thresh = self._best_criteria(X, y, rnd_feats)left_idxs, right_idxs = self._split(X[:, best_feat], best_thresh)left = self._grow_tree(X[left_idxs, :], y[left_idxs], depth + 1)right = self._grow_tree(X[right_idxs, :], y[right_idxs], depth + 1)return Node(best_feat, best_thresh, left, right)def _best_criteria(self, X, y, rnd_feats):best_gain = -1split_idx, split_thresh = None, Nonefor feat_idx in rnd_feats:X_column = X[:, feat_idx]thresholds = np.unique(X_column)for threshold in thresholds:gain = self._information_gain(y, X_column, threshold)if gain > best_gain:best_gain = gainsplit_idx = feat_idxsplit_thresh = thresholdreturn split_idx, split_threshdef _information_gain(self, y, X_column, split_thresh):parent_entropy = self._entropy(y)left_idxs, right_idxs = self._split(X_column, split_thresh)n, n_left, n_right = len(y), len(left_idxs), len(right_idxs)if n_left == 0 or n_right == 0:return 0e_left, e_right = self._entropy(y[left_idxs]), self._entropy(y[right_idxs])child_entropy = (n_left / n) * e_left + (n_right / n) * e_rightig = parent_entropy - child_entropyreturn igdef _split(self, X_column, split_thresh):left_idxs = np.argwhere(X_column <= split_thresh).flatten()right_idxs = np.argwhere(X_column > split_thresh).flatten()return left_idxs, right_idxsdef _entropy(self, y):hist = np.bincount(y)ps = hist / len(y)return -np.sum([p * np.log2(p) for p in ps if p > 0])def _most_common_label(self, y):hist = np.bincount(y)return np.argmax(hist)class Node:def __init__(self, feature=None, threshold=None, left=None, right=None, *, value=None):self.feature = featureself.threshold = thresholdself.left = leftself.right = rightself.value = valuedef is_leaf_node(self):return self.value is not None# 示例用法
if __name__ == "__main__":from sklearn.model_selection import train_test_splitfrom sklearn.datasets import load_irisfrom sklearn.metrics import accuracy_scoredata = load_iris()X, y = data.data, data.targetX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)clf = DecisionTreeClassifier(max_depth=10)clf.fit(X_train, y_train)y_pred = clf.predict(X_test)print("Accuracy:", accuracy_score(y_test, y_pred))

Scikit-learn 实现

Scikit-learn 提供了高效且易用的决策树实现,使用起来非常方便。以下是使用 Scikit-learn 实现决策树分类的示例:

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score# 加载数据集
data = load_iris()
X, y = data.data, data.target# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# 创建并训练决策树分类器
clf = DecisionTreeClassifier(max_depth=10)
clf.fit(X_train, y_train)# 预测
y_pred = clf.predict(X_test)# 计算准确率
print("Accuracy:", accuracy_score(y_test, y_pred))

8. 决策树的应用

决策树广泛应用于各个领域,包括但不限于:

  1. 医学诊断:通过分析病患的症状和体检结果,决策树可以帮助医生做出诊断决策。
  2. 金融风控:用于评估贷款申请者的信用风险,决策树可以根据申请者的历史记录和财务状况进行风险评估。
  3. 市场营销:用于客户细分和市场分析,决策树可以帮助企业确定目标客户群体并制定相应的营销策略。
  4. 图像识别:在图像分类任务中,决策树可以用来识别图像中的不同对象。
  5. 自然语言处理:用于文本分类和情感分析,决策树可以根据文本特征进行分类。

9. 总结

决策树是一种强大且易于理解的机器学习算法,广泛应用于分类和回归任务。本文详细介绍了决策树的基本概念、工作原理、生成算法、剪枝策略以及优缺点,并通过 Python 代码和 Scikit-learn 实现了决策树分类器。通过对决策树的深入理解和实际应用,您可以更好地利用这一工具解决各种实际问题。希望本指南能帮助您掌握决策树的核心工作原理,并在实际项目中应用这一强大的算法。

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

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

相关文章

AJAX(1)——axios库的使用

什么是AJAX? AJAX是异步的JavaScript和XML。简单来说&#xff0c;就是使用XMLHttpRequest对象与服务器通信。它可以使用JSON,XML,HTML和text文本等格式发送和接收数据。AJAX最吸引人的就是它异步的特性&#xff0c;也就是说它可以在不重新刷新页面的情况下与服务器通信&#…

昇思25天学习打卡营第25天|LLM应用-基于MindNLP+MusicGen生成自己的个性化音乐

打卡 目录 打卡 应用任务简介 生成音乐 预训练权重模型下载 无提示生成 文本提示生成 音频提示生成 生成配置 应用任务简介 MusicGen 来自 Meta AI 的 Jade Copet 等人提出的基于单个语言模型&#xff08;LM&#xff09;的音乐生成模型&#xff0c;能够根据文本描述或…

CompletableFuture异步编程多任务执行和简单场景使用

CompletableFuture提供了许多回调函数&#xff0c;来处理异步编程 获取任务结果方法 // 如果完成则返回结果&#xff0c;否则就抛出具体的异常 public T get() throws InterruptedException, ExecutionException // 最大时间等待返回结果&#xff0c;否则就抛出具体异常 publ…

NFS服务器环境搭建

1、什么是NFS ● 定义&#xff1a; NFS是一种在计算机系统之间共享文件和目录的协议&#xff0c;最初由Sun Microsystems开发&#xff0c;现在已经成为广泛使用的网络文件系统之一。 ● 核心功能&#xff1a; 通过网络&#xff08;特别是TCP/IP网络&#xff09;实现文件共享…

探索Conda环境的迷宫:conda env list命令全解析

&#x1f4dc; 探索Conda环境的迷宫&#xff1a;conda env list命令全解析 Conda不仅是Python编程生态中强大的包管理器&#xff0c;还是一个高效的环境管理器。它允许用户创建隔离的环境&#xff0c;每个环境可以拥有不同版本的库和工具&#xff0c;从而避免版本冲突并提高开…

微信小程序配置访问服务器失败所发现的问题及解决方案

目录 事前现象问题1&#xff1a;问题现象&#xff1a;问题分析&#xff1a; 问题2&#xff1a;问题现象&#xff1a;问题分析&#xff1a;解决方案&#xff1a; 事后现象 事前现象 问题1&#xff1a; 问题现象&#xff1a; 在本地调试时&#xff0c;一切顺利&#xff0c;但一…

MySQL:送分or送命 varchar(30) 与 int(10)

摘要&#xff1a; VARCHAR(30) 和 INT(10) 在MySQL中代表两种不同类型的字段&#xff0c;它们之间的主要区别在于它们存储的数据类型、存储方式以及显示宽度的含义。 正文&#xff1a; INT(10) 在MySQL中&#xff0c;当你看到INT(10)这样的数据类型定义时&#xff0c;可能会…

LeetCode707 设计链表

前言 题目&#xff1a; 707. 设计链表 文档&#xff1a; 代码随想录——设计链表 编程语言&#xff1a; C 解题状态&#xff1a; 代码功底不够&#xff0c;只能写个大概 思路 主要考察对链表结构的熟悉程度&#xff0c;对链表的增删改查&#xff0c;比较考验代码功底以及对链表…

Flink Doirs Connector 常见问题:Doris目前不支持流读

常见问题 Doris Source 在数据读取完成后&#xff0c;流为什么就结束了&#xff1f; 目前 Doris Source 是有界流&#xff0c;不支持 CDC 方式读取。 问题&#xff1a;对于 Flink Doris DataStream&#xff0c;Flink 想要在 流式读取 Doirs / 实时读 Doris&#xff0c;目前读…

03--KVM虚拟化

前言&#xff1a;这里开始涉及到云计算内容&#xff0c;虚拟化使云计算发展&#xff0c;云计算推动虚拟化进步&#xff0c;两者相辅相成&#xff0c;这一章总结一下kvm虚拟化的解决方案。 1、基础概念 1.1、云计算 以前要完成信息处理, 是需要在一个客观存在的计算机上完成的…

Node.js版本管理工具之NVM

目录 一、NVM介绍二、NVM的下载安装1、NVM下载2、卸载旧版Node.js3、安装 三、NVM配置及使用1、设置nvm镜像源2、安装Node.js3、卸载Node.js4、使用或切换Node.js版本5、设置全局安装路径和缓存路径 四、常用命令技术交流 博主介绍&#xff1a; 计算机科班人&#xff0c;全栈工…

卷积神经网络(一)---原理和结构

在介绍卷积神经网络之前&#xff0c;先提出三个观点&#xff0c;正是这三个观点使得卷积神经网络能够真正起作用。 1. 局部性 对于一张图片而言&#xff0c;需要检测图片中的特征来决定图片的类别&#xff0c;通常情况下这些特征都不是由整张图片决定的&#xff0c;而是由一些…

vscode 环境

这张截图显示的是在VS Code&#xff08;Visual Studio Code&#xff09;中选择Python解释器的界面。不同的Python解释器及其虚拟环境列出了可选项&#xff0c;用户可以根据需要选择合适的解释器来运行Python代码。以下是对截图中信息的详细解释&#xff1a; 解释器选择界面 当…

构造方法 继续学习~

python类可以使用&#xff1a;__init__()方法&#xff0c;称为构造方法。 可以实现&#xff1a; 在创建类对象时&#xff0c;会自动执行 在创建类对象时&#xff0c;将传入参数自动传递给__init__()方法使用 # 构造方法的名称:__init__ class Student:name Noneage Nonet…

前后端分离真的好吗?

我们经常看到一些页面很卡&#xff0c;是由于前后断分离技术导致的&#xff0c;大量数据都由后端提供&#xff0c;甚至包括字体大小&#xff0c;边距。 每次后端都要搬一个大箱子过来&#xff0c;能不慢吗&#xff1f;如果出现这种问题&#xff0c;怎么解决呢&#xff1f; 首先…

Chrome浏览器设置暗黑模式 - 护眼模式 - 亮度调节 - DarkReader - 地址栏和书签栏设置为黑色背景

效果图 全黑 浅灰 &#xff08;DarkReader设置开启亮色亮度-25&#xff09; 全白 前言 主要分两部分需要操作&#xff0c; 1&#xff09;地址栏和书签栏 》 需要修改浏览器的外观模式 2&#xff09;页面主体 》 需要安装darkreader插件进行设置 步骤 1&#xff09;地址栏和…

spring 中的注解操作

在 spring 中&#xff0c;对注解的操作&#xff0c;都位于 spring-core 模块下的 org.springframework.core.annotation 包中。通过 annotation 包中定义的相关类&#xff0c;完成对类型、方法、字段等元素上注解的操作。 主要类介绍 MergedAnnotations 接口&#xff0c;为 …

Java21的主要新特性总结

目录 概述 变动说明 重要变更和信息 下载地址 Java21新特性总结 1、JEP 441: Switch 的模式匹配&#xff08;正式特性&#xff09; 功能进化 Switch 模式匹配 类型标签 null标签 守卫标签 使用enum常量作值 语法总结 2、JEP 440&#xff1a;Record模式&#xff08…

常用工具类

常用工具类 date类 日期设置方法 方法 描述 setDate() 以数值&#xff08;1-31&#xff09;设置日 setFullYear() 设置年&#xff08;可选月和日&#xff09; setHours() 设置小时&#xff08;0-23&#xff09; setMilliseconds() 设置毫秒&#xff08;0-999&#x…

AOP面向切面编程和log4j的使用(Java版)

什么是面向切面编程 在传统的面向对象编程中&#xff0c;程序的功能被模块化成各个类和方法&#xff0c;这些类和方法分别处理特定的功能。然而&#xff0c;有些功能可能涉及到多个类、多个方法&#xff0c;例如日志记录、事务管理、性能监控等&#xff0c;这些功能可能在不同…