机器学习 | 决策树 Decision Tree

—— 分而治之,逐个击破

                把特征空间划分区域

                每个区域拟合简单模型

                分级分类决策


1、核心思想和原理

  • 举例:
    • 特征选择、节点分类、阈值确定


2、信息嫡

       

        熵本身代表不确定性,是不确定性的一种度量。

        熵越大,不确定性越高,信息量越高。

       

        为什么用log?—— 两种解释,可能性的增长呈指数型;log可以将乘法变为加减法。

        

        联合熵 的物理意义:观察一个多变量系统获得的信息量。

        条件熵 的物理意义:知道其中一个变量的信息后,另一个变量的信息量。

                给定了训练样本 X ,分类标签中包含的信息量是什么。

         

        

        信息增益(互信息)

                代表了一个特征能够为一个系统带来多少信息。

        

        

        熵的分类

        

        

        熵的本质:特殊的衡量分布的混乱程度与分散程度的距离

        

        

        二分类信息熵:

二分类信息熵

import numpy as np
import matplotlib.pyplot as plt
def entropy(p):
    return -(p * np.log2(p) + (1 - p) * np.log2(1 - p))
plot_x = np.linspace(0.001, 0.999, 100)
plt.plot(plot_x, entropy(plot_x))
plt.show()

        

 

         决策树的本质

        


 3、决策树分类代码实现

 

数据集

from sklearn.datasets import load_iris

iris = load_iris()
x = iris.data[:, 1:3]
y = iris.target
plt.scatter(x[:,0], x[:,1], c = y)
plt.show()

 

3.1、sklearn中的决策树

from sklearn.tree import DecisionTreeClassifier
clf = DecisionTreeClassifier(max_depth=2, criterion='entropy')
clf.fit(x, y)

DecisionTreeClassifier

DecisionTreeClassifier(criterion='entropy', max_depth=2)

决策边界绘制的代码: 

def decision_boundary_plot(X, y, clf):
    axis_x1_min, axis_x1_max = X[:,0].min() - 1, X[:,0].max() + 1
    axis_x2_min, axis_x2_max = X[:,1].min() - 1, X[:,1].max() + 1
    
    x1, x2 = np.meshgrid( np.arange(axis_x1_min,axis_x1_max, 0.01) , np.arange(axis_x2_min,axis_x2_max, 0.01))
    z = clf.predict(np.c_[x1.ravel(),x2.ravel()])
    z = z.reshape(x1.shape)
    
    from matplotlib.colors import ListedColormap
    custom_cmap = ListedColormap(['#F5B9EF','#BBFFBB','#F9F9CB'])

    plt.contourf(x1, x2, z, cmap=custom_cmap)
    plt.scatter(X[:,0], X[:,1], c=y)
    plt.show()
decision_boundary_plot(x, y, clf)

from sklearn.tree import plot_tree
plot_tree(clf)
[Text(0.4, 0.8333333333333334, 'X[1] <= 2.45\nentropy = 1.585\nsamples = 150\nvalue = [50, 50, 50]'),
 Text(0.2, 0.5, 'entropy = 0.0\nsamples = 50\nvalue = [50, 0, 0]'),
 Text(0.6, 0.5, 'X[1] <= 4.75\nentropy = 1.0\nsamples = 100\nvalue = [0, 50, 50]'),
 Text(0.4, 0.16666666666666666, 'entropy = 0.154\nsamples = 45\nvalue = [0, 44, 1]'),
 Text(0.8, 0.16666666666666666, 'entropy = 0.497\nsamples = 55\nvalue = [0, 6, 49]')]

 


 

3.2、最优划分条件

from collections import Counter
Counter(y)
Counter({0: 50, 1: 50, 2: 50})
def calc_entropy(y):
    counter = Counter(y)
    sum_ent = 0
    for i in counter:
        p = counter[i] / len(y)
        sum_ent += (-p * np.log2(p))
    return sum_ent
calc_entropy(y)
1.584962500721156
def split_dataset(x, y, dim, value):
    index_left = (x[:, dim] <= value)
    index_right = (x[:, dim] > value)
    return x[index_left], y[index_left], x[index_right], y[index_right]
def find_best_split(x, y):
    best_dim = -1
    best_value = -1
    best_entropy = np.inf
    best_entropy_left, best_entropy_right = -1, -1
    for dim in range(x.shape[1]):
        sorted_index = np.argsort(x[:, dim])
        for i in range(x.shape[0] - 1): # x列数
            value_left, value_right = x[sorted_index[i], dim], x[sorted_index[i + 1], dim]
            if value_left != value_right:
                value = (value_left + value_right) / 2
                x_left, y_left, x_right, y_right = split_dataset(x, y, dim, value)
                entropy_left, entropy_right = calc_entropy(y_left), calc_entropy(y_right)
                entropy = (len(x_left) * entropy_left + len(x_right) * entropy_right) / x.shape[0]
                if entropy < best_entropy:
                    best_dim = dim
                    best_value = value
                    best_entropy = entropy
                    best_entropy_left, best_entropy_right = entropy_left, entropy_right
    return best_dim, best_value, best_entropy, best_entropy_left, best_entropy_right
            
find_best_split(x, y)
(1, 2.45, 0.6666666666666666, 0.0, 1.0)
x_left, y_left, x_right, y_right = split_dataset(x, y, 1, 2.45)
find_best_split(x_right, y_right)
(1, 4.75, 0.34262624992678425, 0.15374218032876188, 0.4971677614160753)


4、基尼系数

        

        基尼系数运算稍快;

        物理意义略有不同,信息熵表示的是随机变量的不确定度;

                基尼系数表示在样本集合中一个随机选中的样本被分错的概率,也就是纯度。

                基尼系数越小,纯度越高。

        模型效果上差异不大。

        

二分类信息熵和基尼系数代码实现:

import numpy as np
import matplotlib.pyplot as plt
def entropy(p):
    return -(p * np.log2(p) + (1 - p) * np.log2(1 - p))
def gini(p):
    return 1 - p ** 2 - (1 - p) ** 2
plot_x = np.linspace(0.001, 0.999, 100)
plt.plot(plot_x, entropy(plot_x), color = 'blue')
plt.plot(plot_x, gini(plot_x), color = 'red')
plt.show()


5、决策树剪枝

Chapter-07/7-6 决策树剪枝.ipynb · 梗直哥/Machine-Learning - Gitee.com

为什么要剪枝?

                复杂度过高。

                        预测复杂度:O(logm)

                        训练复杂度:O(n x m x logm)

                        logm为数的深度,n为数据的维度。

                容易过拟合

                        为非参数学习方法。

 目标:

                降低复杂度

                解决过拟合

 手段:

                限制深度(结点层数)

                限制广度(叶子结点个数)

   —— 设置超参数

                        


6、决策树回归

        基于一种思想:相似输入必会产生相似输出。

        取节点平均值。

        

6.1、决策树回归代码实现

import matplotlib.pyplot as plt
import numpy as np
from sklearn import datasets
from sklearn.model_selection import train_test_split
import warnings
warnings.filterwarnings('ignore')

boston = datasets.load_boston()
x = boston.data
y = boston.target
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=233)
from sklearn.tree import DecisionTreeRegressor

reg = DecisionTreeRegressor()
reg.fit(x_train,y_train)

DecisionTreeRegressor

DecisionTreeRegressor()
reg.score(x_test,y_test)
0.7410680140563546
reg.score(x_train,y_train)
1.0

6.2、绘制学习曲线

from sklearn.metrics import r2_score

plt.rcParams["figure.figsize"] = (12, 8)
max_depth = [2, 5, 10, 20]
    
for i, depth in enumerate(max_depth):
    
    reg = DecisionTreeRegressor(max_depth=depth)
    train_error, test_error = [], []
    for k in range(len(x_train)):
        reg.fit(x_train[:k+1], y_train[:k+1])
        
        y_train_pred = reg.predict(x_train[:k + 1])
        train_error.append(r2_score(y_train[:k + 1], y_train_pred))
        
        y_test_pred = reg.predict(x_test)
        test_error.append(r2_score(y_test, y_test_pred))
    
    plt.subplot(2, 2, i + 1)
    plt.ylim(0, 1.1)
    plt.title("Depth: {0}".format(depth))
    plt.plot([k + 1 for k in range(len(x_train))], train_error, color = "red", label = 'train')
    plt.plot([k + 1 for k in range(len(x_train))], test_error, color = "blue", label = 'test')
    plt.legend()

plt.show()

6.3、网格搜索

from sklearn.model_selection import GridSearchCV

params = {
    'max_depth': [n for n in range(2, 15)],
    'min_samples_leaf': [sn for sn in range(3, 20)],
}

grid = GridSearchCV(
    estimator = DecisionTreeRegressor(), 
    param_grid = params, 
    n_jobs = -1
)
grid.fit(x_train,y_train)

GridSearchCV

GridSearchCV(estimator=DecisionTreeRegressor(), n_jobs=-1,
             param_grid={'max_depth': [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
                                       14],
                         'min_samples_leaf': [3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
                                              13, 14, 15, 16, 17, 18, 19]})

estimator: DecisionTreeRegressor

DecisionTreeRegressor()

DecisionTreeRegressor

DecisionTreeRegressor()
grid.best_params_
{'max_depth': 5, 'min_samples_leaf': 3}
grid.best_score_
0.7327442904059717
reg = grid.best_estimator_
reg.score(x_test, y_test)
0.781690085676063

7、优缺点和适用条件

优点:

        符合人类直观思维

        可解释性强

        能够处理数值型数据和分类型数据

        能够处理多输出问题

缺点:

        容易产生过拟合

        决策边界只能是水平或竖直方向

                

        不稳定,数据的微小变化可能生成完全不同的树


参考于

Chapter-07/7-4 决策树分类.ipynb · 梗直哥/Machine-Learning - Gitee.com

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

IDEA2023 + spring cloud 工程热部署设置方法

基于spring cloud 工程进行热部署 &#xff0c;实现每次修改工程源文件&#xff0c;后台自动启动&#xff0c;方便开发测试工作。具体分为5步骤即可&#xff1a; 1、修改工程的pom文件&#xff0c;增加adding devtools 工具包。 <dependency> <groupId>org.s…

olap/clickhouse-编译器优化与向量化

本文主要结合15721和clickhouse源码来聊聊向量化&#xff0c;正好我最近也在用Eigen做算子加速&#xff0c;了解下还是有好处的。 提示编译器 提示编译器而不是复杂化简单的代码 什么时候使用汇编&#xff0c;什么时候使用SIMD&#xff1f;下面有几个基本原则&#xff1a; …

用23种设计模式打造一个cocos creator的游戏框架----(十九)备忘录模式

1、模式标准 模式名称&#xff1a;备忘录模式 模式分类&#xff1a;行为型 模式意图&#xff1a;在不破坏封装性的前提下捕获一个对象的内部状态&#xff0c;并在对象之外保存这个状态。这样以后就可以将对象恢复到原先保存的状态 结构图&#xff1a; 适用于&#xff1a; …

DMA传输中的中断处理在STM32中的应用

DMA&#xff08;Direct Memory Access&#xff09;是一种在数字系统中进行数据传输的技术&#xff0c;它可以在不依赖CPU的情况下直接从内存中读取或写入数据。在STM32微控制器中&#xff0c;DMA控制器可以与外设进行数据传输&#xff0c;减轻了CPU的负担&#xff0c;提高了数据…

DFT音频还原及降噪实战

傅里叶变换与信息隐写术(二) 声音数据 ​ 声音可以用连续的波形来表示 ​ 声音在计算机中的存储是离散的 ​ 计算机中存储的是声音的几个采样点的数据&#xff0c;1 秒钟采样 5 个点就表示采样频率是 5 Hz&#xff08;每隔 0.25 秒取一个点&#xff0c;注意第 0 秒也取&#…

python:import自定义包或py文件时,pyCharm正常但终端运行提示ModuleNotFoundError: No module named错误

问题 示例项目引用items.py&#xff0c;项目在pycharm开发工具中可以正常运行&#xff0c;但使用终端直接运行会报错ModuleNotFoundError: No module named。如下图。 原因 pycharm开发工具运行正常&#xff0c;说明目录和引用模块是没问题的。问题在于终端的运行环境只搜索文…

链表基础知识(二、双向链表头插、尾插、头删、尾删、查找、删除、插入)

目录 一、双向链表的概念 二、 双向链表的优缺点分析​与对比 2.1双向链表特点&#xff1a; 2.2双链表的优劣&#xff1a; 2.3循环链表的优劣 2.4 顺序表和双向链表的优缺点分析​ 三、带头双向循环链表增删改查实现 3.1SList.c 3.2创建一个新节点、头节点 3.3头插 3.…

手拉手EasyExcel极简实现web上传下载(全栈)

环境介绍 技术栈 springbootmybatis-plusmysqleasyexcel 软件 版本 mysql 8 IDEA IntelliJ IDEA 2022.2.1 JDK 1.8 Spring Boot 2.7.13 mybatis-plus 3.5.3.2 EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。 他能让你在不用考虑性…

华为鸿蒙应用--欢迎页SplashPage+倒计时跳过(自适应手机和平板)-ArkTs

鸿蒙ArkTS 开发欢迎页SplashPage倒计时跳过&#xff0c;可自适应平板和手机&#xff1a; 一、SplashPage.ts import { BreakpointSystem, BreakPointType, Logger, PageConstants, StyleConstants } from ohos/common; import router from ohos.router;Entry Component struct…

数据结构之<树>的介绍

树的基本概念 在数据结构中&#xff0c;树&#xff08;Tree&#xff09;是一种层次结构&#xff0c;由节点和边组成。树的基本概念包括根节点、子节点、父节点、兄弟节点等。节点拥有零个或多个子节点&#xff0c;除了根节点外&#xff0c;每个节点有且仅有一个父节点。树的层…

数据结构-猴子吃桃问题

一、需求分析 有一群猴子摘了一堆桃子&#xff0c;他们每天都吃当前桃子的一半且再多吃一个&#xff0c;到了第10天就只余下一个桃子。用多种方法实现求出原来这群猴子共摘了多少个桃子。要求&#xff1a; 1)采用数组数据结构实现上述求解&#xff1b; 2)采用链数据结构实现上述…

13、Kafka副本机制详解

Kafka 副本机制详解 1、副本定义2、副本角色3、In-sync Replicas&#xff08;ISR&#xff09;4、Unclean 领导者选举&#xff08;Unclean Leader Election&#xff09; 所谓的副本机制&#xff08;Replication&#xff09;&#xff0c;也可以称之为备份机制&#xff0c;通常是指…

离线编译安装opencv库及多版本切换[ubuntu]

系统版本&#xff1a;ubuntu18.04 库版本&#xff1a;opencv4.6.0 & opencv3.6.0 一、多版本安装前准备 1. 卸载已经安装的opencv版本[可选] 1.1 卸载从软件仓库中安装的opencv sudo apt-get purge libopencv* 1.2 卸载使用source自行编译安装的opencv 首先进入原先编译…

人生感悟 | 又是一年,眼看要2024了

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 刚过完大雪节气没两天&#xff0c;气温开始急转直下&#xff0c;走在路上明显感觉冷了许多。看天气预报很多地区已经开始下雪了。 看日历已经12月9号了&#xff0c;12月份&#xff0c;一年的最后一个月&#xff0c;2…

自然语言处理阅读第二弹

HuggingFace 镜像网站模型库 NLP中的自回归模型和自编码模型 自回归&#xff1a;根据上文内容预测下一个可能的单词&#xff0c;或者根据下文预测上一个可能的单词。只能利用上文或者下文的信息&#xff0c;不能同时利用上文和下文的信息。自编码&#xff1a;对输入的句子随…

【TB作品】STM32 PWM之实现呼吸灯,STM32F103RCT6,晨启

文章目录 完整工程参考资料实验过程 实验任务&#xff1a; 1&#xff1a;实现PWM呼吸灯&#xff0c;定时器产生PWM&#xff0c;控制实验板上的LED灯亮灭&#xff1b; 2&#xff1a;通过任意两个按键切换PWM呼吸灯输出到两个不同的LED灯&#xff0c;实现亮灭效果&#xff1b; 3&…

FRP 内网穿透工具部署

FRP 介绍 frp 是一个专注于内网穿透的高性能反向代理应用&#xff0c;支持 TCP、UDP、HTTP、HTTPS 等多种协议&#xff0c;且支持 P2P 通信。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。 官方网站&#xff1a;https://gofrp.org/zh-cn/ 项目地…

ARS430毫米波雷达标定步骤

工具准备&#xff1a;CANoe&#xff0c; 标定工程文件&#xff0c;雷达标定板&#xff0c;三脚架&#xff0c;激光器&#xff0c;平口钳&#xff0c;气泡水平仪&#xff0c;小镜子&#xff0c;双面胶。 将车辆放置在车辆前方至少有20米空白视野的场地上。使用气泡水平仪大概使…

谈一谈网络协议中的传输层

文章目录 UDPTCPTCP为什么可靠 UDP 传输层的作用是负责能够从发送端到传输端。 我们的主机上有多个程序&#xff0c;那么怎么分辨哪个信息是发给哪个程序的呢&#xff1f;—端口号。其是一个16位的无符号整型&#xff0c;端口号分为知名端口号&#xff08;0-1023&#xff09;和…

基于YOLOv8深度学习的路面标志线检测与识别系统【python源码+Pyqt5界面+数据集+训练代码】目标检测、深度学习实战

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…