CART决策树算法

article/2025/9/24 15:59:53

在进行自动识别窃漏电用户分析实战时,用到了CART决策树算法,所以整理记录该算法的内容。内容整理参考文档决策树——CART算法及其后的参考文章。

一、CART(classification and regression tree)分类与回归树,既可用于分类,也可用于回归。
CART分类树生成
CART分类树算法使用基尼系数来选择特征。基尼系数Gini(D)表示集合D的不确定性(纯度),Gini(D,A)表示根据特征A的某个值a分割后集合D的不确定性(纯度)。基尼系数数值越小,样本纯度越高。对于给定的样本D,假设有K个类别,第k个类别的数量为 C k C_{k} Ck,则样本D的基尼系数表达式为: G i n i ( D ) = 1 − ∑ k = 1 K ( ∣ C k ∣ ∣ D ∣ ) 2 Gini\left ( D \right )=1-\sum_{k=1}^{K}\left ( \frac{|C_{k}|}{|D|} \right )^{2} Gini(D)=1k=1K(DCk)2
对于样本D,如果根据特征A的某个值a,把D分成D1和D2两部分,则在特征A的条件下,D的基尼系数表达式为: G i n i ( D , A ) = ∣ D 1 ∣ ∣ D ∣ G i n i ( D 1 ) + ∣ D 2 ∣ ∣ D ∣ G i n i ( D 2 ) Gini\left ( D,A \right )=\frac{|D_{1}|}{|D|}Gini\left ( D_{1} \right )+\frac{|D_{2}|}{|D|}Gini\left ( D_{2} \right ) Gini(D,A)=DD1Gini(D1)+DD2Gini(D2)
CART分类树建立算法的具体流程
算法输入是训练集D、基尼系数的阈值、样本个数阈值,输出是决策树T。从根节点开始:
1、对于当前节点的数据集D,如果样本个数小于阈值或者没有特征,则返回决策子树,当前节点停止递归。
2、计算样本集D的基尼系数,如果基尼系数小于阈值,则返回决策树子树,当前节点停止递归。
3、计算当前节点现有的各个特征的各个特征值对数据集D的基尼系数,选择基尼系数最小的特征A和对应的特征值a。根据这个最优特征和最优特征值,把数据集划分成两部分D1和D2,同时建立当前节点的左右节点,左节点的数据集D为D1,右节点的数据集D为D2。
4、对左右的子节点递归调用1-3步,生成决策树。
CART回归树生成
CART回归树和CART分类树的建立算法大部分是类似的,不同的地方有:
1、样本输出:分类树输出离散值,回归树输出连续值。
2、划分点选择方法:分类树使用基尼系数,回归树使用误差平方最小化。
3、预测方式:分类树采用叶子节点里概率最大的类别作为当前节点的预测类别,回归树采用最终叶子的均值或者中位数来预测输出结果。
CART回归树的度量目标是,对于任意划分特征A,对应的任意划分点s两边划分成的数据集D1和D2,求出使D1和D2各自集合的均方差最小,同时D1和D2的均方差之和最小所对应的特征和特征值划分点。表达式为:
在这里插入图片描述
其中,c1为D1数据集的样本输出均值,c2为D2数据集的样本输出均值。
CART树算法的剪枝
CART剪枝采用CCP(Cost Complexity Pruning)代价复杂剪枝法,从决策树低端剪去一些子树,使得决策树变小变简单,从而防止过拟合。其剪枝算法可以概括为两步,第一步是从原始决策树生成各种剪枝效果的决策树,第二步是用交叉验证来检验剪枝后的预测能力,选择泛化预测能力最好的剪枝后的树作为最终的CART树。在剪枝的过程中,对于任意一棵子树T,其损失函数为: C α ( T t ) = C ( T t ) + α ∣ T t ∣ C_{\alpha }\left ( T_{t} \right )=C\left ( T_{t} \right )+\alpha |T_{t}| Cα(Tt)=C(Tt)+αTt
其中,α为正则化参数, C ( T t ) C\left ( T_{t} \right ) C(Tt)为训练数据的预测误差,分类树是用基尼系数度量,回归树是均方差。 ∣ T t ∣ |T_{t}| Tt是子树T的叶子节点的数量。如果将任意一棵子树T剪枝,仅保留根节点,则损失是: C α ( T ) = C ( T ) + α C_{\alpha }\left ( T \right )=C\left ( T \right )+\alpha Cα(T)=C(T)+α
如果 T t T_{t} Tt与T有同样的损失,且T的节点更少,那么T比 T t T_{t} Tt更可取,所以剪掉 T t T_{t} Tt。此时 α = C ( T ) − C ( T t ) ∣ T t ∣ − 1 \alpha =\frac{C\left ( T \right )-C\left ( T_{t} \right )}{|T_{t}|-1} α=Tt1C(T)C(Tt)
这表示剪枝后的误差增加率。其中 C ( T ) = c ( t ) ∗ p ( t ) C\left ( T \right )=c\left ( t \right )*p\left ( t \right ) C(T)=c(t)p(t),c(t)是节点的误差率,p(t)是节点上的数据占所有数据的比例。
具体剪枝过程:
1、自下而上计算每个内部结点的误差增加率,选择最小的来剪枝,生成新的树。
2、如果新的树不是由根节点及两个叶节点构成的树,则递归上一步。
3、采用交叉验证法在上述两步中选择最优的子树作为最后的结果。

二、建立模型实现后,评估模型用到了ROC曲线,所以整理ROC相关内容。
ROC曲线如下所示,设置了两个指标:分别是TPR与FPR,它是以TPR为纵坐标,FPR为横坐标画出的曲线。TPR是正例的覆盖率(正确预测到的正例数/实际正例总数​),FPR是将实际的0错误地预测为1的概率(预测错误的正例数/实际负例总数)。
在这里插入图片描述
ROC曲线越远离对角线,模型效果越好。曲线下的面积可以定量地评价模型的效果,记作AUC,AUC代表着分类器预测精度。
AUC>0.9,说明模型有较高准确性;
0.7≤AUC≤0.9,说明模型有一定准确性;
0.5≤AUC<0.7,说明模型有较低准确性。

三、进行自动识别窃漏电用户实战,建模的目标是归纳出窃漏电用户的关键特征,构建窃漏电用户的识别模型。
首先进行搭建数据模型准备:
1、数据筛选,可以将用户进行分类(如按规模、性质),可能某些种类用户不存在窃漏电行为,可以将这些类别用户剔除。
2、数据探索,总结窃漏电用户的行为规律,再从数据中提炼出窃漏电用户的特征指标。
根据数据探索及业务理解,最终构建的窃漏电评价指标体系如下:
(1)电量趋势下降指标,以前后几天作为统计窗口期,利用电量做直线拟合得到的斜率衡量,如果斜率随时间不断下降,那用户的窃漏电可能性就很大。
(2)线损指标,用户发生窃漏电时,线损率会上升。可以计算前后几天(如前5天、后5天)的线损率平均值,判断增长率是否大于给定阈值。
(3)告警类指标,计算发生与窃漏电相关的终端报警的总次数。
接着收集指标样本数据,案例得到的样本共291条,部分如下所示:
在这里插入图片描述
窃漏电用户识别可以通过构建分类预测模型来实现,实践中选择了逻辑回归模型和CART决策树模型分别实现,通过ROC曲线进行模型评估,相关代码如下:

import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
import numpy as np
from sklearn.metrics import roc_curve, auc
import matplotlib.pyplot as plt
from sklearn.tree import DecisionTreeClassifier#ROC曲线绘制
def roc(test,predict):	#test是实际类别数据,predict是预测类别数据fpr, tpr, thresholds = roc_curve(test, predict, pos_label=1)  #获得FPR、TPR,pos_label=1是指在预测值中标签为1的是标准阳性,其余值是阴性。roc_auc = auc(fpr, tpr) #计算AUCplt.plot(fpr, tpr, 'b', label='auc=%0.2f' % roc_auc)    #绘制ROC曲线plt.legend(loc='lower right')   #设置图例位置plt.plot([0, 1], [0, 1], 'r--') #绘制对角线plt.xlim([0.0, 1.0])    #设置坐标轴范围plt.ylim([0.0, 1.0])plt.xlabel("fpr")   #设置坐标轴名称plt.ylabel("tpr")plt.show()data = pd.read_csv('CART.csv',encoding='gbk')  #读取源数据
#print(data.shape)
array = data.values  #转化为多维数组
p=0.7    #训练数据占总数据量的0%
train=array[:int(len(array)*p),:]   #获得训练数据
test=array[int(len(array)*p):,:]    #获得测试数据
X_train = train[:, 2:5] #分离特征和类别
Y_train = train[:, 5].astype('int')
X_test = test[:, 2:5]
Y_test = test[:, 5].astype('int')model = LogisticRegression()    #加载逻辑回归模型
model.fit(X_train, Y_train)  #训练数据
scores = cross_val_score(model, X_train, Y_train, cv=10)    #交叉验证评估模型的预测性能
print("准确率", np.mean(scores)) #交叉验证准确率
predictions = model.predict(X_test) #预测数据
roc(Y_test,predictions) #绘制ROC曲线tree=DecisionTreeClassifier()  #加载决策树
tree.fit(X_train,Y_train)  #训练数据
scores = cross_val_score(tree, X_train, Y_train, cv=10) #交叉验证评估模型的预测性能
print("准确率", np.mean(scores))    #交叉验证准确率
predict_result=tree.predict(X_test)    #预测数据
roc(Y_test,predict_result)	#绘制ROC曲线

两个模型的ROC曲线分别如下:
在这里插入图片描述
在这里插入图片描述
查看训练集上的交叉验证准确率,逻辑回归模型为0.892,CART决策树模型为0.887,两者差别不大。但是从ROC曲线可以看出,CART模型的曲线更加靠近左上角,AUC值直接表明了这一点,逻辑回归模型为0.78,CART决策树模型为0.87,说明CART决策树模型预测效果更好。


http://chatgpt.dhexx.cn/article/X4qi2Hg9.shtml

相关文章

CART树算法解析加举例

算法步骤 CART假设决策树是二叉树&#xff0c;内部结点特征的取值为“是”和“否”&#xff0c;左分支是取值为“是”的分支&#xff0c;右分支是取值为“否”的分支。这样的决策树等价于递归地二分每个特征&#xff0c;将输入空间即特征空间划分为有限个单元&#xff0c;并在…

ID3、C4.5与CART树的联系与区别

ID3、C4.5与CART树的联系与区别&#xff1a; 参考博客&#xff1a; 链接1 链接2 特征选择准则&#xff1a; ID3的特征选择准则为信息增益&#xff0c;即集合D的经验熵H(D)与给定特征A下条件经验熵H(D|A)之差&#xff0c;即&#xff1a; H(D)表现了数据集D进行分类的不确定性…

决策树构建算法—ID3、C4.5、CART树

决策树构建算法—ID3、C4.5、CART树 决策树构建算法—ID3、C4.5、CART树 构建决策树的主要算法ID3C4.5CART三种算法总结对比 决策树构建算法—ID3、C4.5、CART树 构建决策树的主要算法 ID3C4.5CART &#xff08;Classification And Rsgression Tree&#xff09; ID3 ID3算法…

3-6 决策树、CART树、GBDT、xgboost、lightgbm一些关键点梳理

目录 1、决策树 2、CART树 2.1 CART分类树-输入样本特征&#xff1b;输出样本对应的类别(离散型) 2.2 CART回归树-输入样本特征&#xff1b;输出样本的回归值(连续型) 3、GBDT 3.1 提升树 3.2 GBDT 4、xgboost 4.1 损失函数及节点展开 4.2 精确贪心算法及相关近似算法…

CART树回归

说明&#xff1a;本博客是学习《python机器学习算法》赵志勇著的学习笔记&#xff0c;其图片截取也来源本书。 基于树的回归算法是一类基于局部的回归算法&#xff0c;通过将数据集切分成多份&#xff0c;在每一份数据中单独建模。与局部加权线性回归不同的是&#xff0c;基于…

剪枝、cart树

一、剪枝 1. 为什么要剪枝 在决策树生成的时候&#xff0c;更多考虑的是训练数据&#xff0c;而不是未知数据&#xff0c;这会导致过拟合&#xff0c;使树过于复杂&#xff0c;对于未知的样本不准确。 2. 剪枝的依据——通过极小化决策树的损失函数 损失函数的定义为&#x…

【机器学习】决策树——CART分类回归树(理论+图解+公式)

&#x1f320; 『精品学习专栏导航帖』 &#x1f433;最适合入门的100个深度学习实战项目&#x1f433;&#x1f419;【PyTorch深度学习项目实战100例目录】项目详解 数据集 完整源码&#x1f419;&#x1f436;【机器学习入门项目10例目录】项目详解 数据集 完整源码&…

CART树(分类回归树)

主要内容 &#xff08;1&#xff09;CART树简介 &#xff08;2&#xff09;CART树节点分裂规则 &#xff08;3&#xff09;剪枝 --------------------------------------------------------------------------------------------------------------------- 一、简介 CART…

CART树

算法概述 CART(Classification And Regression Tree)算法是一种决策树分类方法。 它采用一种二分递归分割的技术&#xff0c;分割方法采用基于最小距离的基尼指数估计函数&#xff0c;将当前的样本集分为两个子样本集&#xff0c;使得生成的的每个非叶子节点都有两个分支。因此…

Pytorch之view,reshape,resize函数

对于深度学习中的一下数据&#xff0c;我们通常是要变成tensor格式&#xff0c;并且需要对其调整形状&#xff0c;很多时候我们往往只关注view之后的结果&#xff08;比如输出的尺寸&#xff09;&#xff0c;而不关心过程。但有时候还是要关注一下这个到底是怎么变换过来的&…

OpenCV-Python图像处理:插值方法及使用resize函数进行图像缩放

☞ ░ 前往老猿Python博客 https://blog.csdn.net/LaoYuanPython ░ 图像缩放用于对图像进行缩小或扩大&#xff0c;当图像缩小时需要对输入图像重采样去掉部分像素&#xff0c;当图像扩大时需要在输入图像中根据算法生成部分像素&#xff0c;二者都会利用插值算法来实现。 一…

vector的resize函数和reserve函数

博客原文&#xff1a;C基础篇 -- vector的resize函数和reserve函数_VampirEM_Chosen_One的博客-CSDN博客&#xff0c;写的特别好&#xff0c;谢谢原博主。 正文&#xff1a; 对于C的vector容器模板类&#xff0c;存在size和capacity这样两个概念&#xff0c;可以分别通过vect…

OpenCV 图片尺寸缩放——resize函数

文章目录 OpenCV中的缩放&#xff1a;resize函数代码案例 OpenCV中的缩放&#xff1a; 如果要放大或缩小图片的尺寸&#xff0c;可以使用OpenCV提供的两种方法&#xff1a; resize函数&#xff0c;是最直接的方式&#xff1b;pyrUp&#xff0c;pyrDown函数&#xff0c;即图像…

OpenCV的resize函数优化

背景 在使用OpenCV做图像处理的时候&#xff0c;最常见的问题是c版本性能不足&#xff0c;以resize函数为例来说明&#xff0c;将size为[864,1323,3]的函数缩小一半&#xff1a; Mat img0;gettimeofday(&t4, NULL);cv::resize(source, img0, cv::Size(cols_out,rows_out)…

C++ | resize函数的用法

最近在leetcode用C刷题&#xff0c;刚遇到一题需要给重新弄一个容器&#xff0c;并给容器初始化。新建容器要在private类中声明resize函数用来初始化preSum容器。 resize函数是C中序列式容器的一个共性函数&#xff0c;vv.resize(int n,element)表示调整容器vv的大小为n&#x…

opencv的resize函数

一、Opencv官方文档中resize的描述&#xff1a; resize Resizes an image. C: void resize(InputArray src, OutputArray dst, Size dsize, double fx0, double fy0, int interpolationINTER_LINEAR ) Python: cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]]) …

resize()函数

resize()&#xff0c;设置大小&#xff08;size&#xff09;; reserve()&#xff0c;设置容量&#xff08;capacity&#xff09;; size()是分配容器的内存大小&#xff0c;而capacity()只是设置容器容量大小&#xff0c;但并没有真正分配内存。 打个比方&#xff1a;正在建造…

OpenCV 图像缩放:cv.resize() 函数详解

目录 系列前言API函数详解参数列表缩放方式其一缩放方式其二两种方式的优先级关于插值方式 扩展 —— 相关函数 系列前言 这个系列是我第一个想要更下去的系列。每篇会全面介绍一个 OpenCV 函数&#xff0c;会给出 API 和示例。示例主要是用 Python 去写&#xff0c;但是 Open…

安卓中的几种线程间通信方式

一&#xff1a;Handler实现线程间的通信 andriod提供了 Handler 和 Looper 来满足线程间的通信。例如一个子线程从网络上下载了一副图片&#xff0c;当它下载完成后会发送消息给主线程&#xff0c;这个消息是通过绑定在主线程的Handler来传递的。 在Android&#xff0c;这里的…

Java中的线程通信的几种方式

Java中的线程间通信是指不同线程之间相互协作&#xff0c;以完成一些复杂的任务或实现某些功能的过程。线程间通信主要包括两个方面&#xff1a;线程之间的互斥和同步&#xff0c;以及线程之间的数据共享和通信。Java提供了多种方式来实现线程间通信&#xff0c;本文将介绍Java…