sklearn|机器学习:决策树(一)

news2024/11/7 21:11:21

文章目录

  • sklearn|机器学习:决策树(一)
    • (一)概述
    • (二)实战
      • 1. 环境配置
      • 2. sklearn 中的决策树
        • (1)模块 `sklearn.tree`
        • (2)`sklearn` 基本建模流程
        • (3)`DecisionTreeClassifier` 与红酒数据集
          • a. `criterion`
            • - 信息熵 vs 基尼系数
            • - 参数选取
            • - 决策树基本流程
            • - 代码示例
          • b. `random_state` & `splitter`
          • c. 剪枝参数
            • - `max_depth`
            • - `min_samples_leaf` & `min_samples_split`
            • - `max_features` & `min_impurity_decrease`
            • - 最优剪枝参数选择
          • d. 目标权重参数
            • - `class_weight` & `min_weight_fraction_leaf`
        • (4)重要属性和接口
        • (5)补充

sklearn|机器学习:决策树(一)

本部分为基于**《菜菜的 sklearn 机器学习》课程的学习笔记,理论部分结合了周志华《机器学习》**来进行补充,scikit-learn 作为一个开源的 python 机器学习工具包,通过 Numpy, SciPy 和 Matploylib 等 python 数值计算的库实现高效的算法应用,涵盖了几乎所有主流机器学习算法。本课程主要介绍了 sklearn 的全面应用,具体包括 sklearn 中对算法的说明,调参,属性,接口,以及实例应用。

官网:https://scikit-learn.org/stable/index.html

(一)概述

决策树(Decision Tree)是一种非参数的有监督学习方法,非参数指不限制数据的结构和类型,有监督学习则指必须具有标签。决策树能够从一系列有特征和标签的数据中总结出决策规则,并用树状图的结构来呈现,可用于解决分类和回归问题,其算法本质是一种图结构。

其他以树模型为核心的集成算法还有随机森林、AdaBoost

image-20241028203748467

以上为基于西瓜好坏问题构建的决策树,其中最初问题所在地方为根结点(没有进边,有出边,包含最初针对特征的提问),得到结论前的每一个问题为中间节点(既有进边也有出边,进边只有一条,出边可以有多条,均为针对特征的提问),而得到的每一个结论为叶子结点(只有进边,没有出边,每个叶节点都是一个类别标签)。

子节点父节点:在两个相连的节点中,更接近根节点的是父节点,另一个为子节点。

一般而言,决策树由一个根节点、若干个中间节点和若干个叶节点组成,叶节点对应于决策结果。

决策树算法核心问题

  • 如何从数据表中找出最佳节点最佳分枝

  • 如何让决策树停止生长,防止过拟合

(二)实战

1. 环境配置

本部分环境的安装主要参考了菜菜的开发环境:

image-20241024144440167

此处能够使用 Anaconda,就不推荐使用 pip,因为 pip 安装一部分库的时候可能会出现异常,其默认下载的一部分库的版本可能只适用于 linux 系统,而 Anaconda 的安装一般不会有这个问题。

pip install numpy
pip install pandas
pip install scipy
pip install matplotlib
pip install -U scikit-learn
conda install python-graphviz

注意:Anaconda 的安装和 pip 的安装尽量不要混用,由 Anaconda 安装的库在使用 pip 卸载或是更新的时候,可能出现无法卸载干净,无法正常更新,或更新后一部分库变得无法运行的情况。

2. sklearn 中的决策树

(1)模块 sklearn.tree

sklearn 中决策树的类都在 tree 这个模块下,该模块共包含五类:

tree.DecisionTreeClassifier分类树
tree.DecisionTreeRegressor回归树
tree.export_graphviz将生成的决策树导出为DOT格式,画图专用
tree.ExtraTreeClassifier高随机版本的分类树
tree.ExtraTreeRegressor高随机版本的回归树
(2)sklearn 基本建模流程

sklearn 具有对所有模型都通用的建模流程,总有以下三步:

image-20241028210000139

其对应分类树的代码为:

from sklearn import tree  # 导入所需要的模块

clf = tree.DecisionTreeClassifier()  # 实例化模型,需要知道所使用的参数,并将其填充在()内
clf = clf.fit(X_train, y_train)  # 用训练集数据训练模型,几乎所有模型均可以用fit来训练
result = clf.score(X_test, y_test)  # 导入测试集,从接口中调用需要的信息,如score来获取分类模型的accuracy
(3)DecisionTreeClassifier 与红酒数据集
class DecisionTreeClassifier(criterion='gini', splitter='best', max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features=None, random_state=None, max_leaf_nodes=None, min_impurity_decrease=0.0, class_weight=None, ccp_alpha=0.0)
a. criterion

决策树使用“不纯度”来确定最佳节点和最佳分枝方法,通常来说,“不纯度”越低说明决策树对训练集的拟合越好。不纯度基于节点计算,树中每个节点都有一个不纯度,每一层都有一个加权的不纯度。

在同一棵决策树上,子节点的不纯度一定低于父节点,且叶子结点的不纯度一定是最低的。

criterion 则是用来决定不纯度的计算方法的,其中 sklearn 提供了两种选择,默认使用基尼系数 :

  • 输入 entropy ,使用信息熵(Entropy)
    E n t r o p y ( t ) = − ∑ i = 0 c − 1 p ( i ∣ t ) l o g 2 p ( i ∣ t ) Entropy(t)=-\sum_{i=0}^{c-1}p(i|t)log_2p(i|t) Entropy(t)=i=0c1p(it)log2p(it)

  • 输入 gini,使用基尼系数(Gini Impurity)
    G i n i ( t ) = 1 − ∑ i = 0 c − 1 p ( i ∣ t ) 2 Gini(t)=1-\sum_{i=0}^{c-1}p(i|t)^2 Gini(t)=1i=0c1p(it)2

其中,t代表给定节点,i代表标签的任意分类,p(i|t) 表示标签分类 i 在节点 t 上所占的比例。

当使用信息熵时,sklearn 实际计算的是基于信息上的信息增益,即父节点的信息熵和子节点的信息熵之差,在实际使用中,两者效果相当。

- 信息熵 vs 基尼系数
  • 信息熵对不纯度更加敏感,对不纯度的惩罚最强,决策树的生长更精细,但对于高维数据或噪音较多的数据容易过拟合。
  • 基尼系数计算更快,因为不涉及对数。
- 参数选取
  • 通常使用基尼系数
  • 数据维度较大,噪音较大时使用基尼系数
  • 纬度低,数据较清晰时,信息熵与基尼系数没有区别
  • 当决策树的拟合程度不够(欠拟合)时,使用信息熵
  • 两者尝试选择更佳的
- 决策树基本流程

image-20241031152630043

当没有更多特征可用或整体不纯度指标已达到最优时,决策树停止生长。

- 代码示例
# 导入模块和算法库
from sklearn import tree
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split

# 载入数据集
wine = load_wine()
wine # 字典
wine.data  # 提取wine中的特征矩阵
wine.data.shape # 查看数据集格式,共有13个特征,178个样本
wine.target  # 提取wine中的标签矩阵
# 如果不输入特征名和标签名,会输出对应的列数,不够直观
wine.feature_names # 查看特征名
wine.target_names # 查看标签名

# 将字典变为表,前13列为特征,最后一列为标签
import pandas as pd
pd.concat([pd.DataFrame(wine.data), pd.DataFrame(wine.target)], axis=1)

# 随机划分训练集和测试集,30%为测试集,70%为训练集,此处需要注意顺序为xxyy
Xtrain, Xtest, Ytrain, Ytest = train_test_split(wine.data, wine.target, test_size=0.3)
Xtrain # 查看划分后的训练集
Xtrain.shape # 查看划分后的训练集的结构,(124, 13)
Xtest # 查看划分后的测试集
Xtest.shape # 查看划分后的测试集的结构,(54, 13)

# Step1:实例化
clf = tree.DecisionTreeClassifier(criterion="entropy")
# Step2:带入训练数据集进行训练
clf.fit(Xtrain, Ytrain)
# Step3:导入测试集计算模型得分
score = clf.score(Xtest, Ytest) # 返回预测的准确度accuracy
score # 0.9814814814814815,每次训练准确度都不一样

# 可视化
import graphviz
feature_name = wine.feature_names # 可自定义
dot_data = tree.export_graphviz(clf,
                               feature_names = feature_name,
                               class_names = ["琴酒","雪莉","贝尔摩德"], # 标签名
                               filled = True, # 是否填充颜色,颜色越深不纯度越低
                               rounded = True) # 方框是否圆角 
graph = graphviz.Source(dot_data)
graph

节点越往下,不纯度(entropy)越低,当不纯度为0时就可以选出一个标签类别,每个中间节点代表一个特征选择。其中,samples表示样本数,value表示三种label对应的样本数,class表示支持样本数最多的标签,且并非所有特征都会被使用。

# 查看feature的贡献度,贡献度越高值越大,根节点对于决策树的贡献永远最高
clf.feature_importances_

# 将feature贡献度与feature name相对应,形成元组
[*zip(feature_name, clf.feature_importances_)]

image-20241031172824815

b. random_state & splitter

无论决策树模型如何进化,在分枝上的本质都还是追求某个不纯度相关指标的优化,决策树在建树时靠优化节点来追求一颗优化的树,但最优的节点并不能保证最优的树,因此sklearn使用了集成算法来解决该问题,即在每次分枝时,不使用全部特征,而是随机选取一部分特征,再从中选取不纯度相关指标最优的作为分枝用的节点,所以每次生成的树也不同。

random_state 用来设置分枝中的随机模式的参数,默认None,在高维度时随机性会更明显,低维度的数据中随机性几乎不会显现。

# 解决随机性问题,random_state 默认为 None
clf = tree.DecisionTreeClassifier(criterion="entropy", random_state=30)
clf = clf.fit(Xtrain, Ytrain)
score = clf.score(Xtest, Ytest)
score

splitter 也可以控制决策树中的随机选项,有两种输入值:

  • 输入"best",决策树在分枝时虽然随机,但是会优先选择更重要的特征进行分枝;
  • 输入"random",决策树在分枝时更加随机,树会更深,对训练集的拟合将会降低,可以防止过拟合。
clf = tree.DecisionTreeClassifier(criterion="entropy", 
                                  random_state=30,
                                  splitter="random")
clf = clf.fit(Xtrain, Ytrain)
score = clf.score(Xtest, Ytest)
score

# 可视化
import graphviz
feature_name = wine.feature_names # 可自定义
dot_data = tree.export_graphviz(clf,
                               feature_names = feature_name,
                               class_names = ["琴酒","雪莉","贝尔摩德"], # 标签名
                               filled = True, # 是否填充颜色,颜色越深不纯度越低
                               rounded = True) # 方框是否圆角 
graph = graphviz.Source(dot_data)
graph

注意:如果模型特征较多,可以使用以上两个参数来降低过拟合的可能性。

c. 剪枝参数
# 查看模型对训练集的拟合程度
score_train = clf.score(Xtrain, Ytrain)
score_train

image-20241031180731814

如果模型在训练集上的拟合程度比在测试集上要好得多,则认为存在过拟合的问题,为了使决策树具有更好的泛化能力,需要对决策树进行剪枝。

- max_depth

限制树的最大深度,超过设定深度的树枝全部剪掉(使用最广泛),通常在高纬度低样本量时非常有效,决策树多生长一层,对样本量的需求会增加一倍,所以限制树深度能够有效地限制过拟合,其在集成算法中也非常实用。

实际使用时,建议从=3开始尝试,再根据拟合的效果决定是否增加设定深度。

- min_samples_leaf & min_samples_split

min_samples_leaf 限定一个节点在分枝后的每个子节点都必须包含至少 min_samples leaf 个训练样本,否则分枝就不会发生,分枝会朝着满足每个子节点都包含 min_samples_leaf 个样本的方向去发生;一般搭配max_depth 使用,可以让模型变得更加平滑,且可以保证每个叶子的最小尺寸,能够在回归问题中避免低方差、过拟合的叶子节点出现。

注意min_samples_leaf 设置过小会引起过拟合,设置过大会阻止模型学习数据。一般来说,建议从=5开始使用;如果叶节点中含有的样本量变化很大,建议输入浮点数作为样本量的百分比来使用。对于类别不多的分类问题,=1通常就是最佳选择。

min_samples_split 限定一个节点必须要包含至少 min_samples_split 个训练样本才允许被分枝,否则分枝就不会发生。

clf = tree.DecisionTreeClassifier(criterion="entropy", 
                                  random_state=30,
                                  splitter="random",
                                  max_depth=3,
                                  min_samples_leaf=10,
                                  min_samples_split=10)
clf = clf.fit(Xtrain, Ytrain)
dot_data = tree.export_graphviz(clf,
                               feature_names = feature_name,
                               class_names = ["琴酒","雪莉","贝尔摩德"], 
                               filled = True,
                               rounded = True) 
graph = graphviz.Source(dot_data)
graph
- max_features & min_impurity_decrease

max_features 限制分枝时考虑的特征个数,超过限制个数的特征都会被舍弃,是用来限制高维度数据的过拟合的剪枝参数,直接限制可以使用的特征数量而强行使决策树停下。在不知道决策树中的各个特征的重要性的情况下,强行设定可能会导致模型学习不足。

如果希望通过降维的方式防止过拟合,建议使用PCA,ICA或者特征选择模块中的降维算法。

min_impurity_decrease 限制信息增益的大小,信息增益小于设定数值的分枝不会发生,信息增益越大代表该层分枝对于决策树的贡献越大。

- 最优剪枝参数选择

超参数的学习曲线是一条以超参数的取值为横坐标,模型的度量指标为纵坐标的曲线,用来衡量不同超参数取值下模型的表现。

import matplotlib.pyplot as plt

test = []
for i in range(10):
    clf = tree.DecisionTreeClassifier(max_depth=i+1,
                                    criterion="entropy",
                                    random_state=30,
                                    splitter="random")
    clf = clf.fit(Xtrain, Ytrain)
    score = clf.score(Xtest, Ytest)
    test.append(score)
plt.plot(range(1,11),test,color="red",label="max_depth")
plt.legend()
plt.show()

image-20241031191317412

注意:调参并非一定能够提升模型在测试集上的表现,当数据集非常大时,建议提前设定剪枝参数来控制树的复杂性和大小,以免内存消耗过大。

d. 目标权重参数
- class_weight & min_weight_fraction_leaf

当样本存在不平衡,即标签中的某一类天生占有很大的比例,那么构建出的决策树会不可避免地向大比例的部分偏移,如银行在判断”一个办了信用卡的人是否会违约"时是vs否 (1%:99%)的比例,此时即便模型什么也不做,全把结果预测成“否",正确率也能有99%。因此需要使用 class_weight 参数对样本标签进行均衡,给少量的标签更多的权重,该参数默认None,表示自动给与数据集中的所有标签相同的权重。

设定权重后的剪枝将不仅仅只是单纯记录支持样本数,需要搭配 min_weight_fraction_leaf 基于权重来剪枝。

注意:基于权重的剪枝参数(如 min_weightfraction leaf )将比不知道样本权重的标准(如 min_samples leaf)更少偏向主导类;如果样本是加权的,使用基于权重的预修剪标准更容易优化树结构,确保叶节点至少包含样本权重的总和的一小部分。

(4)重要属性和接口

在 sklearn 中,除了 fitscore 几乎可以对每个算法使用,还有两个常用的接口:

  • apply :输入测试集返回每个测试样本所在叶子结点的索引
  • predict :输入测试集返回每个测试样本的标签

所有接口中要求输入 Xtrain 和 Xtest 的部分,其输入的特征矩阵必须至少是一个二维矩阵,即至少有两个特征。

注意:sklearn 不接受任何一维矩阵作为特征矩阵被输入,如果只有一个特征,则需要用reshape(-1,1) 给矩阵增维;如果只有一个特征和一个样本,则需要使用 reshape(1,-1) 来增维。

# apply 返回每个测试样本所在叶子结点的索引
clf.apply(Xtest)

# predict 返回每个测试样本的标签
clf.predict(Xtest)

image-20241031194039651

(5)补充

分类树天生不擅长环形数据,每个模型都有自己的决策上限,当一个模型怎么调整都不行的时候,可以选择换其他的模型使用,最擅长月亮型数据的是最近邻算法,RBF支持向量机和高斯过程;最擅长环形数据的是最近邻算法和高斯过程;最擅长对半分的数据的是朴素贝叶斯,神经网络和随机森林。

KNN算法对月亮型和环型数据都具有很好的表现,但可调试范围较小,且计算量较大。

image-20241031195433997

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

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

相关文章

服务器Linux系统网络重启失败 Restarting network (via systemctl):......

网络重启时报错: Linux 网络服务重启失败可能由网络配置工具冲突或配置错误引起。 冲突问题:在 Linux 中,network 和 NetworkManager 这两个工具可能会冲突,禁用 NetworkManager 可以尝试解决该问题。 先停止服务 systemctl s…

域控操作二十四:主域故障辅域接替

模拟环境:上海DC1故障无法开机,导致只有一个DNS的电脑无法上网(实际可以添加DC2但是为了实验就不说了) FSMO还在DC1上 使用powershell把角色迁移到DC2 ntdsutil roles connections connect to server DC2SHA.whbk.cn quitSeize …

边缘AI计算技术应用-实训解决方案

一、解决方案架构 1.1 来自产业的项目 实训项目全部是基于产业的商业化项目,经过角色拆解、任务拆解、代码拆解、部署流程拆解等过程,讲其标准化为教师可以带领学生完成的实训内容,真正帮助学生接触产业前沿技术和工作内容,提升就…

贪心算法习题其二【力扣】【算法学习day.18】

前言 ###我做这类文档一个重要的目的还是给正在学习的大家提供方向(例如想要掌握基础用法,该刷哪些题?)我的解析也不会做的非常详细,只会提供思路和一些关键点,力扣上的大佬们的题解质量是非常非常高滴&am…

【Axure原型分享】颜色选择器——填充颜色

今天和大家分享颜色选择器——填充颜色的原型模板,点击颜色区域可以弹出颜色选择器,点击可以选择对应颜色,颜色区域会变色我们选择的颜色,具体效果可以观看下方视频或者打开预览地址体验。 【原型效果】 【Axure高保真原型】颜色…

SQL实战训练之,力扣:1843. 可疑银行账户

目录 一、力扣原题链接 二、题目描述 三、建表语句 四、题目分析 五、SQL解答 六、最终答案 七、验证 八、知识点 一、力扣原题链接 1843. 可疑银行账户 二、题目描述 表: Accounts ---------------------- | Column Name | Type | ---------------------- | acco…

软件系统交付阶段必备文档,验收体系配套资料,软件系统各阶段各步骤相关配套资料,各类软件建设方案(word,ppt)

软件文档交付清单是指在软件开发项目完成后,开发团队需要准备的一份详细清单,用于确保交付的软件产品符合客户需求并达到预期的质量标准。以下是软件文档交付清单中可能包含的一些关键要素 软件资料清单列表部分文档清单:工作安排任务书&…

Day07爬楼梯

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? class Solution {public int climbStairs(int n) {if (n 1) return 1;if (n 2) return 2;return climbStairs(n - 1) climbStairs(n - 2);} }用…

【51单片机】串口通信原理 + 使用

学习使用的开发板:STC89C52RC/LE52RC 编程软件:Keil5 烧录软件:stc-isp 开发板实图: 文章目录 串口硬件电路UART串口相关寄存器 编码单片机通过串口发送数据电脑通过串口发送数据控制LED灯 结束语 串口 串口是一种应用十分广泛…

c盘满了怎么清理垃圾而不误删?6招轻松清理C盘,快来试试

c盘满了怎么清理垃圾而不误删?相信平时工作生活中离不开电脑,随着使用电脑时间就了,C 盘的空间会不断被占据,进而致使系统运行变得迟缓,甚至出现卡顿现象。因此,定期清理 C 盘的是非常重要的。很多电脑小白…

Android 托管 Github Action 发布 Github Packages ,实现 Mvn 免费自动化托管

自从多年前 JCenter 关闭服务之后,GSY 项目版本就一直发布在 Jitpack 上,如今每个月也都有大概 10w 左右下载,但是近年来时不时就会出现历史版本丢失的问题,而且有时候还不是某个具体版本丢失,而是版本里的某几个依赖突…

MATLAB中pinv函数用法

目录 语法 说明 示例 使用伪逆求解线性方程组 pinv的功能是得到矩阵的Moore-Penrose 伪逆。 语法 B pinv(A) B pinv(A,tol) 说明 B pinv(A) 返回矩阵 A 的 Moore-Penrose 伪逆。 B pinv(A,tol) 指定容差的值。pinv 将 A 中小于容差的奇异值视为零。 示例 使用伪逆…

DP31 买卖股票的最好时机(二)

DP31 买卖股票的最好时机(二) import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main {public static void main(String[] args) {Scanner in new Scanner(System.in);int n in.nextInt();int [] p new int[n];int sum 0;for…

.NET Core WebApi第5讲:接口传参实现、数据获取流程、204状态码问题

一、接口传参实现 1、引入:通过网址上两个参数mod...和FID....,区分开要的是哪个板块里面的数据​​​​​ 2、传参实现:在方法的参数处定义STRING字符串 (1)传1个参数 2>运行代码,在网页上输入以“点…

为什么一定要学AI(Stable Diffusion)做设计?

在当今数字化时代,人工智能技术正在以前所未有的速度和规模改变着各行各业的工作方式和流程。 更多实操教程可以扫描下方,免费获取 而室内设计领域中,AI技术也正在迅速崛起,为设计师们带来了前所未有的便利和创作可能性&#xff0…

mysql密码过期问题处理

链接mysql报错 Your password has expired. To log in you must change it using a client that supports expired passwords; 1、打开mysql链接工具 LINUV bin目录 windows 打开mysql client 2、进入mysql命令框 输入旧密码 3、执行 mysql> set passwordpassword(12345…

灵动AI视频 —— 创意无界,视频新生

在这个瞬息万变的数字时代,每一帧画面都蕴含着无限可能。灵动AI视频,作为一款集智能、高效、创意于一体的视频编辑神器,正引领着视频创作的新潮流。 灵动ai视频用户端:灵动 AI-新一代AI创意生产力平台​编辑https://one.genceai.…

SPA——MVC 与 MVVM - 2024最新版前端秋招面试短期突击面试题【100道】

SPA——MVC 与 MVVM - 2024最新版前端秋招面试短期突击面试题【100道】 🌐 在现代前端开发中,单页面应用(SPA)以及不同的架构模式(如MVC和MVVM)是实现用户交互的关键概念。了解它们的优缺点以及如何应用&a…

Vue3+TypeScript+Vite 后台管理项目

一、前言 我将使用当前最新版本完成项目搭建,我会尽量将每个操作细节记录下来,并且解释原因,标明依据出处,这样即使大家脱离当前这个版本,跟着文章依然可以完成项目搭建,这篇文章也依然有他的价值&#xf…

知识竞赛活动用什么样的话筒或麦克风好呢

搞知识竞赛活动,话筒一般是需要的,从选手到主持人、评委甚至有些观众,每场活动用量不少。 市场上的麦克风五花八门,从价格低廉的入门款到高端专业设备,不胜枚举。这让很多用户在选择时感到无从下手。如何在众多产品中…