决策树节点分裂:探索不同的标准与方法

news2024/9/9 1:18:05

决策树节点分裂:探索不同的标准与方法

决策树是一种广泛用于分类和回归任务的机器学习算法。其核心思想是通过一系列简单的规则(即节点分裂)将数据集划分为不同的子集,直到满足某种停止条件为止。在节点分裂过程中,选择最优的分裂标准和方法是构建高效决策树的关键。本文将详细介绍决策树节点分裂的不同标准与方法,具体到源码示例,帮助您深入理解和应用这些技术。

一、决策树的基本概念

决策树是一种树形结构,其中每个内部节点表示一个特征(属性)上的测试,每个分支表示测试结果的一个值,每个叶节点表示一个类别或数值(决策结果)。决策树的构建过程通常包括以下几个步骤:

  1. 选择最优分裂特征和分裂点:在每个节点选择一个最优的特征及其相应的分裂点,以最大化子集的纯度。
  2. 递归地构建子树:对每个子集递归地应用上述步骤,直到满足停止条件(如最大树深、最小样本数等)。

二、常见的节点分裂标准

在决策树中,节点分裂标准是衡量分裂后子集纯度的指标。常见的节点分裂标准包括:

  1. 信息增益(Information Gain):衡量通过分裂某个特征能够减少多少不确定性。基于熵(Entropy)的概念。
  2. 信息增益比(Information Gain Ratio):对信息增益进行归一化处理,以避免偏向多值特征。
  3. 基尼指数(Gini Index):衡量一个样本随机分类到某个类别的概率。
  4. 方差减少(Variance Reduction):主要用于回归树,衡量分裂后目标变量的方差减少量。

1. 信息增益

信息增益是基于熵的概念来衡量特征分裂前后信息的不确定性减少程度。熵的定义如下:

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

其中,(p_i) 是类别 (i) 的概率。信息增益定义为:

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

其中,(D) 是数据集,(A) 是特征,(V) 是特征 (A) 的取值集合,(D_v) 是特征 (A) 取值为 (v) 的子集。

2. 信息增益比

信息增益比对信息增益进行归一化处理,以减少其对多值特征的偏向。定义为:

[ GR(D, A) = \frac{IG(D, A)}{H(A)} ]

其中,(H(A)) 是特征 (A) 的固有值(Intrinsic Value),定义为:

[ H(A) = - \sum_{v \in V} \frac{|D_v|}{|D|} \log_2 \left( \frac{|D_v|}{|D|} \right) ]

3. 基尼指数

基尼指数用于衡量数据集的不纯度,定义为:

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

其中,(p_i) 是类别 (i) 的概率。特征 (A) 的基尼指数定义为:

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

4. 方差减少

方差减少主要用于回归树,用于衡量目标变量的方差减少量,定义为:

[ \Delta Var = Var(D) - \sum_{v \in V} \frac{|D_v|}{|D|} Var(D_v) ]

其中,(Var(D)) 是数据集 (D) 中目标变量的方差。

三、决策树的实现

接下来,我们将通过 Python 代码实现一个简单的决策树算法,探索不同的分裂标准和方法。

1. 数据集准备

首先,我们准备一个示例数据集用于测试。这里使用经典的鸢尾花数据集(Iris Dataset)。

from sklearn.datasets import load_iris
import pandas as pd

# 加载鸢尾花数据集
iris = load_iris()
df = pd.DataFrame(data=iris.data, columns=iris.feature_names)
df['target'] = iris.target

2. 决策树节点类

我们定义一个决策树节点类,用于存储节点信息和实现节点分裂逻辑。

import numpy as np

class DecisionTreeNode:
    def __init__(self, gini=None, num_samples=None, num_samples_per_class=None, predicted_class=None):
        self.gini = gini
        self.num_samples = num_samples
        self.num_samples_per_class = num_samples_per_class
        self.predicted_class = predicted_class
        self.feature_index = 0
        self.threshold = 0
        self.left = None
        self.right = None

    def __str__(self):
        return f"DecisionTreeNode(gini={self.gini}, num_samples={self.num_samples}, num_samples_per_class={self.num_samples_per_class}, predicted_class={self.predicted_class})"

3. 决策树类

接下来,我们定义一个决策树类,包含构建树的逻辑和节点分裂标准的实现。

class DecisionTreeClassifier:
    def __init__(self, max_depth=None):
        self.max_depth = max_depth
        self.tree = None

    def 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 _gini(self, y):
        m = len(y)
        return 1.0 - sum((np.sum(y == c) / m) ** 2 for c in np.unique(y))

    def _grow_tree(self, X, y, depth=0):
        num_samples_per_class = [np.sum(y == i) for i in range(self.n_classes_)]
        predicted_class = np.argmax(num_samples_per_class)
        node = DecisionTreeNode(
            gini=self._gini(y),
            num_samples=len(y),
            num_samples_per_class=num_samples_per_class,
            predicted_class=predicted_class,
        )

        if depth < self.max_depth:
            idx, thr = self._best_split(X, y)
            if idx is not None:
                indices_left = X[:, idx] < thr
                X_left, y_left = X[indices_left], y[indices_left]
                X_right, y_right = X[~indices_left], y[~indices_left]
                node.feature_index = idx
                node.threshold = thr
                node.left = self._grow_tree(X_left, y_left, depth + 1)
                node.right = self._grow_tree(X_right, y_right, depth + 1)
        return node

    def _best_split(self, X, y):
        m, n = X.shape
        if m <= 1:
            return None, None

        num_parent = [np.sum(y == c) for c in range(self.n_classes_)]
        best_gini = 1.0 - sum((num / m) ** 2 for num in num_parent)
        best_idx, best_thr = None, None

        for idx in range(n):
            thresholds, classes = zip(*sorted(zip(X[:, idx], y)))
            num_left = [0] * self.n_classes_
            num_right = num_parent.copy()
            for i in range(1, m):
                c = classes[i - 1]
                num_left[c] += 1
                num_right[c] -= 1
                gini_left = 1.0 - sum((num_left[x] / i) ** 2 for x in range(self.n_classes_))
                gini_right = 1.0 - sum((num_right[x] / (m - i)) ** 2 for x in range(self.n_classes_))
                gini = (i * gini_left + (m - i) * gini_right) / m
                if thresholds[i] == thresholds[i - 1]:
                    continue
                if gini < best_gini:
                    best_gini = gini
                    best_idx = idx
                    best_thr = (thresholds[i] + thresholds[i - 1]) / 2

        return best_idx, best_thr

    def _predict(self, inputs):
        node = self.tree
        while node.left:
            if inputs[node.feature_index] < node.threshold:
                node = node.left
            else:
                node = node.right
        return node.predicted_class

4

. 测试决策树

我们使用鸢尾花数据集来测试我们实现的决策树。

from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# 划分训练集和测试集
X = df.iloc[:, :-1].values
y = df.iloc[:, -1].values
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 训练决策树
tree = DecisionTreeClassifier(max_depth=3)
tree.fit(X_train, y_train)

# 预测并评估
y_pred = tree.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy: {accuracy * 100:.2f}%")

5. 可视化决策树

为了更直观地展示决策树的结构,我们可以使用图形化工具来可视化决策树。这里使用 graphviz 库。

import graphviz

def export_graphviz(tree, feature_names):
    dot_data = []
    def recurse(node, depth):
        indent = "  " * depth
        if node.left:
            dot_data.append(f"{indent}{feature_names[node.feature_index]} < {node.threshold:.2f}")
            recurse(node.left, depth + 1)
            dot_data.append(f"{indent}else {feature_names[node.feature_index]} >= {node.threshold:.2f}")
            recurse(node.right, depth + 1)
        else:
            dot_data.append(f"{indent}class = {node.predicted_class}")

    recurse(tree.tree, 0)
    return "\n".join(dot_data)

dot_data = export_graphviz(tree, iris.feature_names)
print(dot_data)

四、总结

在本文中,我们详细探讨了决策树节点分裂的不同标准与方法,包括信息增益、信息增益比、基尼指数和方差减少,并通过具体的代码示例展示了如何实现和应用这些标准。希望这些内容能帮助您更好地理解和使用决策树算法,为您的数据分析和机器学习任务提供支持。

如果您有任何问题或需要进一步的帮助,请随时与我联系。

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

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

相关文章

25.惰性队列

介绍 消费者由于各种原因而致使长时间不能消费消息造成堆积。比如有一百万条消息发送到mq中&#xff0c;消费者这时宕机了不能消费消息&#xff0c;造成了消息堆积。惰性队列就有必要了。 正常情况下&#xff0c;消息保存在内存中。消费者从内存中读取消息消费&#xff0c;速…

【设计模式】代理模式详解

1.简介 代理模式是常用的Java设计模式&#xff0c;该模式的特点是代理类与委托类共享相同的接口。代理类主要负责预处理消息、过滤消息、将消息转发给委托类&#xff0c;并在事后处理消息等。代理类与委托类之间通常存在关联关系&#xff0c;一个代理类对象与一个委托类对象关…

TPM管理咨询公司在项目实施过程中提供哪些培训和支持?

在竞争激烈的市场环境中&#xff0c;企业项目的成功实施不仅是技术的较量&#xff0c;更是管理智慧的体现。而TPM管理咨询公司&#xff0c;作为提升企业运营效率与竞争力的专业伙伴&#xff0c;深知在项目推进的每一步中&#xff0c;专业的培训与强大的支持体系对于确保项目顺利…

shell脚本编写、一键安装nginx、条件语句、 检测网段脚本、 打印九九乘法表、

1.shell脚本 1.编写及运行脚本 [root13git ~]# vim hello.sh [root13git ~]# bash hello.sh [root13git ~]# sh hello.sh [root13git ~]# source hello.sh //在当前进程执行 [root13git ~]# chmod x hello.sh [root13git ~]# ./hello.sh 2.一键安装nginx [root13g…

小红书笔记评论采集全攻略:三种高效方法教你批量导出

摘要&#xff1a; 本文将深入探讨如何利用Python高效采集小红书平台上的笔记评论&#xff0c;通过三种实战策略&#xff0c;手把手教你实现批量数据导出。无论是市场分析、竞品监测还是用户反馈收集&#xff0c;这些技巧都将为你解锁新效率。 一、引言&#xff1a;小红书数据…

芋道源码/yudao-cloud二次开发日记(商品sku数据归类为规格属性)

商品的每一条规格和属性在数据库里都是单一的一条数据&#xff0c;从数据库里查出来后&#xff0c;该怎么归类为对应的规格和属性值&#xff1f;如下图&#xff1a; 在商城模块&#xff0c;商品的单规格、多规格、单属性、多属性功能可以说是非常完整&#xff0c;如下图&#x…

Github2024-07-29 开源项目周报Top15

根据Github Trendings的统计,本周(2024-07-29统计)共有15个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目2Java项目2HTML项目2C项目2TypeScript项目2JavaScript项目2非开发语言项目1Vue项目1Go项目1Dart项目1C++项目1Rust项目1Jupyter Note…

项目计划书编制方案(DOC)

项目开发计划包括项目描述、项目组织、成本预算、人力资源估算、设备资源计划、沟通计划、采购计划、风险计划、项目过程定义及项目的进度安排和里程碑、质量计划、数据管理计划、度量和分析计划、监控计划和培训计划等。 软件资料清单列表部分文档&#xff1a; 工作安排任务书…

Temporal(时效)模式01

Andy Carlson, Sharon Estepp, Martin Fowler 著&#xff0c;透明 译 抽象 在面向对象设计中&#xff0c;我们不断使用“对象”&#xff08;object&#xff09;这个词。对象不仅仅用来表现真实世界中存在的物件&#xff0c;它们也被用来表现那些曾经存在但已经消失了的物件&…

关于Docker Engine AuthZ 插件授权绕过漏洞 (CVE-2024-41110)

一、漏洞概述 漏洞名称&#xff1a;Docker Engine AuthZ 插件授权绕过漏洞 &#xff08;CVE-2024-41110&#xff09; 漏洞等级&#xff1a;高危 漏洞描述&#xff1a;DockerEngine是Docker的核心组件&#xff0c;是一 个开源的容器引擎&#xff0c;负责构建、运行和管理容器…

又一新AI搜索工具,OpenAI 推出新的搜索方式 SearchGPT

系列文章目录 每天推荐AI工具系列文章回顾&#xff1a; 选择 haiyi海艺图像生成、LoRA、模型的使用和训练网站 tusiart吐司艺术图像生成、LoRA 模型的使用和训练网站 解锁AI创造力的无限可能&#xff1a;探索Vivago.ai的革命性功能 文章目录 系列文章目录前言一、SearchGPT…

html+css+js前端作业和平精英6个页面页面带js

htmlcssjs前端作业和平精英6个页面页面带js 下载地址 https://download.csdn.net/download/qq_42431718/89595600 目录1 目录2 项目视频 htmlcssjs前端作业和平精英6个页面带js 页面1 页面2 页面3 页面4 页面5 页面6

锐捷RCNA | RGOS日常管理操作和Windows常用命令

RGOS操作系统最主要的三大特性是模块化、安全性、开放性。 RGOS平台登陆方式 平台概述 RGOS全称“锐捷通用操作系统”&#xff0c;即网络设备的操作系统 基于RGOS开发的软件版本目前为11.x&#xff0c;又被称为11.x平台优势 模块化设计&#xff0c;方便运维管理故障隔离&…

[ARC105E] Keep Graph Disconnected题解

题目 考虑加任意一条边时都会输的图的状态&#xff1a;图被分成两个强联通分量&#xff0c;每一个强联通分量都是一个完全图。 也就是说&#xff0c;假设一开始节点 1 1 1 和节点 n n n 不联通&#xff0c;那么还可以加 n ( n − 1 ) 2 − m − c n t 1 ( n − c n t 1 ) \…

78.SAP ME - SAP ME和SAP NetWeaver log files的位置

目录 1.defaultTrace files 内容 文件位置 2.dev_server files 内容 文件位置 3.dev_icm files 内容 文件位置 4.responses.trc files 内容 文件位置 1.defaultTrace files You should always check this log first when any system issue is reported 内容 包含…

经典文献阅读之--GraphAD(端到端自动驾驶的交互场景图)

Tip: 如果你在进行深度学习、自动驾驶、模型推理、微调或AI绘画出图等任务&#xff0c;并且需要GPU资源&#xff0c;可以考虑使用UCloud云计算旗下的Compshare的GPU算力云平台。他们提供高性价比的4090 GPU&#xff0c;按时收费每卡2.6元&#xff0c;月卡只需要1.7元每小时&…

什么是项目计划?项目计划如何制定?

做不好项目计划的项目管理&#xff0c;注定会失败&#xff01; 项目计划是帮助管理人员有效实现目标的非常重要的一环&#xff0c;在开始任何项目之前&#xff0c;制定一份详细的计划作为所有参与者的指导性文件非常重要。那么什么是项目计划&#xff1f;项目计划又该如何制定…

springboot集成thymeleaf实战

引言 笔者最近接到一个打印标签的需求&#xff0c;由于之前没有做过类似的功能&#xff0c;所以这也是一次学习探索的机会了&#xff0c;打印的效果图如下&#xff1a; 这个最终的打印是放在58mm*58mm的小标签纸上&#xff0c;条形码就是下面的35165165qweqweqe序列号生成的&…

民大食堂用餐小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;商家管理&#xff0c;档口号管理&#xff0c;商家餐品管理&#xff0c;餐品种类管理&#xff0c;购物车管理&#xff0c;订单信息管理 微信端账号功能包括&#xff1a;系统首页&a…

pytorch-迁移学习

目录 1. 宝可梦数据集训练的问题2. 迁移学习3. 迁移学习实现4. 完整代码 1. 宝可梦数据集训练的问题 宝可梦数据总共有1000多张&#xff0c;对于resnet18网络来说数据量是不够的&#xff0c;训练时很容易出现过拟合&#xff0c;那么如何解决这个问题呢&#xff1f; 宝可梦数据…