【1 - 决策树 - 原理部分】菜菜sklearn机器学习

news2024/9/25 23:15:25

课程地址:《菜菜的机器学习sklearn课堂》_哔哩哔哩_bilibili

  • 第一期:sklearn入门 & 决策树在sklearn中的实现
  • 第二期:随机森林在sklearn中的实现
  • 第三期:sklearn中的数据预处理和特征工程
  • 第四期:sklearn中的降维算法PCA和SVD
  • 第五期:sklearn中的逻辑回归
  • 第六期:sklearn中的聚类算法K-Means
  • 第七期:sklearn中的支持向量机SVM(上)
  • 第八期:sklearn中的支持向量机SVM(下)
  • 第九期:sklearn中的线性回归大家族
  • 第十期:sklearn中的朴素贝叶斯
  • 第十一期:sklearn与XGBoost
  • 第十二期:sklearn中的神经网络

目录

sklearn入门

决策树(Decision Tree,DT) 

(一)决策树是如何工作的 

(二)sklearn中的决策树

分类树DecisionTreeClassifier与红酒数据集

重要参数

(一)criterion:用来决定不纯度的计算方法

(二)random_state & splitter:控制随机性

(三)剪枝参数(5个)

(四)目标权重参数(完成样本标签平衡的参数,不常用) 

重要属性和接口

总结 

回归树DecisionTreeRegressor与波士顿房价数据集

重要参数、属性及接口 

(一)criterion(回归树衡量分枝质量的指标)

(二)属性

(三)接口

(四)交叉验证 

实例:一维回归的图像绘制 

决策树的优缺点


sklearn入门

scikit-learn是一个开源的基于Python的机器学习工具包

分析采集到的数据,根据数据特征选择适合的算法,在工具包中调用算法,调整算法的参数,获取需要的信息,从而实现算法效率和效果之间的平衡

解析sklearn的全面应用,了解不同机器学习算法有哪些可调参数、有哪些可用接口,这些接口和参数对算法来说有什么含义,又会对算法的性能及准确性有什么影响 —— 讲解sklearn中对算法的说明、调参、属性、接口,以及实例应用

sklearn官网:scikit-learn: machine learning in Python — scikit-learn 1.2.0 documentation 

  • 分类、回归、聚类、降维、模型选择、数据预处理 


决策树(Decision Tree,DT) 

(一)决策树是如何工作的 

是一种非参数(不限制数据的结构和类型,几乎可以用它来处理各种各样的数据)的有监督学习(要给标签)方法,能够从一系列有特征和标签的数据中总结出决策规则,并用树状图的结构来呈现这些规则,以解决分类和回归问题

  • 以树模型为核心的各种集成算法(如Adaboost、随机森林)
  • 本质是一种图结构,只需要问一系列问题就可以对数据进行分类了

决策树算法的核心是要解决两个问题:

  1. 如何从数据表中找出最佳节点和最佳分枝?
  2. 如何让决策树停止生长,防止过拟合?

(二)sklearn中的决策树

模块sklearn.tree,包含五个类(还有两个类分别是高随机版本的分类树和回归树,不常用):

  • tree.DecisionTreeClassifier:分类树
  • tree.DecisionTreeRegressor:回归树
  • tree.export_graphviz:将生成的决策树导出为DOT格式,画图专用

sklearn的基本建模流程:

在这个流程下,分类树对应的代码是:

from sklearn import tree

clf = tree.DecisionTreeClassifier()   # 实例化
clf = clf.fit(X_train,y_train)   # 用训练集数据训练模型
result = clf.score(X_test,y_test)   # 导入测试集,从接口中调用需要的信息(对分类模型来说就是accuracy)

分类树DecisionTreeClassifier与红酒数据集

重要参数

(一)criterion:用来决定不纯度的计算方法

为了要将表格转化成一棵树,决策树需要找出最佳节点和最佳分枝方法。对分类树来说,衡量这个最佳的指标是不纯度

  • 不纯度越低,决策树对训练集的拟合越好
  • 基于节点来计算,子节点的不纯度一定低于父节点
  • 在同一棵决策树上,叶子节点的不纯度一定最低 

sklearn提供了两种选择:

  1. entropy:信息熵(实际计算的是基于信息熵的信息增益,即父节点的信息熵和子节点的信息熵之差。子节点的信息熵一定小于父节点,所以信息增益越大,这一层分枝对决策树的贡献就越大),取值范围为0~1
  2. gini:基尼系数(默认),取值范围为0~0.5

  

对比:

  • 信息熵对不纯度更加敏感,所以信息熵作为指标时,决策树的生长会更加精细,因此对于高维数据或噪音很多的数据,信息熵很容易过拟合,基尼系数在这种情况下效果往往比较好
  • 当模型拟合程度不足时,即当模型在训练集和测试集上都表现不太好时,使用信息熵

决策树的基本流程可以简单概括为:

计算全部特征的不纯度指标 ——> 选取不纯度指标最优的特征来分枝 ——> 在第一个特征的分枝下,计算全部特征的不纯度指标 ——> 选取不纯度指标最优的特征继续分枝... ——> 直到没有更多的特征可用,或整体的不纯度指标已经最优,决策树就会停止生长

from sklearn import tree
from sklearn.datasets import load_wine  # datasets是sklearn自带的含有各种各样数据的库,包含波士顿房价、鸢尾花、红酒数据等
from sklearn.model_selection import train_test_split

wine = load_wine()  # 数据实例化

# wine是一个字典,wine.data取数据,wine.target取标签
wine.data.shape  # 13个特征
wine.target  # 三分类

# 将wine变成一张表
import pandas as pd
pd.concat([pd.DataFrame(wine.data),pd.DataFrame(wine.target)],axis=1)

wine.feature_names
wine.target_names

# 分训练集和测试集
Xtrain, Xtest, Ytrain, Ytest = train_test_split(wine.data,wine.target,test_size=0.3)

# 建立模型
clf = tree.DecisionTreeClassifier(criterion="entropy")  # 实例化,criterion默认为gini
clf = clf.fit(Xtrain, Ytrain)   # 把数据带进去训练
score = clf.score(Xtest, Ytest)   # 返回预测的准确度accuracy

score

# 画树
feature_name = ['酒精','苹果酸','灰','灰的碱性','镁','总酚','类黄酮','非黄烷类酚类','花青素','颜色强度','色调','od280/od315稀释葡萄酒','脯氨酸']

import graphviz
dot_data = tree.export_graphviz(clf   # 已经训练好的模型
                                ,feature_names = feature_name
                                ,class_names=["琴酒","雪莉","贝尔摩德"]
                                ,filled=True   # 填充颜色(不纯度越低,颜色越深)
                                ,rounded=True  # 框的形状
                               ) 

graph = graphviz.Source(dot_data)  # 越往下,不纯度entropy越低。不纯度为0时,就可以选出标签类别了
graph

# 特征重要性(没有使用的特征,为0)
clf.feature_importances_    # 对决策树贡献越大的,重要性越高(根节点对特征重要性的贡献一定是最大的)

[*zip(feature_name,clf.feature_importances_)]

上述代码每次运行得到的结果都不一样,这是为什么?

  • 无论决策树模型如何进化,在分枝上的本质都还是追求某个不纯度相关指标的优化
  • 不纯度是基于节点来计算的,即决策树在建树时,是靠优化节点来追求一棵优化的树,但最优的节点不能保证一定是最优的树
  • sklearn基本思想则是,既然一棵树不能保证最优,那就建更多不同的树,然后从中取最好的
  • 怎样从一组数据集中建不同的树?在每次分枝时,不使用全部特征,而是随机选取一部分特征,从中选取不纯度相关指标最优的作为分枝用的节点,这样,每次生成的树也就不同了 

(二)random_state & splitter:控制随机性

  1. random_state:用来设置分枝中的随机模式的参数。输入任意整数,会一直长出同一棵树,让模型稳定下来
  2. splitter:用来控制决策树中的随机选项,有两种输入值,best(默认)/ random

    - best:决策树在分枝时虽然随机,但还是会优先选择更重要的特征进行分枝(重要性可以通过属性 feature_importances_ 查看)

    - random:决策树在分枝时会更加随机,树会因为含有更多不必要的信息而更深更大,并因这些不必要的信息而降低对训练集的拟合(也是防止过拟合的一种方式)

树一旦建成,使用剪枝参数来防止过拟合

(三)剪枝参数(5个)

  • 在不加限制的情况下,一棵决策树会生长到衡量不纯度的指标最优,或者没有更多的特征可用为止,这样的决策树往往会过拟合(训练集上表现好,测试集上表现差)
  • 我们收集的样本数据不可能和整体的状况完全一致,因此,当一棵决策树对训练数据有了过于优秀的解释性,它找出的规则必然包含了训练样本中的噪声,并使它对未知数据的拟合程度不足
  • 为了让决策树有更好的泛化性,要对决策树进行剪枝

sklearn为我们提供了不同的剪枝策略:

  1. max_depth:超过设定深度的树枝全部剪掉。在高维度低样本量时有效,一般从=3开始尝试
  2. min_samples_leaf:限定一个节点在分枝后的每个子节点都必须包含至少min_samples_leaf个训练样本,否则分枝就不会发生,或朝着满足每个子节点都包含min_samples_leaf个样本的方向去发生。设置的太小会引起过拟合,设置的太大会阻止模型学习数据,一般从=5开始使用。如果叶节点中含有的样本量变化很大,输入浮点数作为样本量的百分比来使用
  3. min_samples_split:限定一个节点必须要包含至少min_samples_split个训练样本,这个节点才允许被分枝
  4. max_features:限制分枝时考虑的特征个数,超过限制个数的特征都会被舍弃。如果希望通过降维的方式防止过拟合,建议使用PCA、ICA或者特征选择模块中的降维算法
  5. min_impurity_decrease:限制信息增益的大小,信息增益小于设定数值的分枝不会发生

确定最优的剪枝参数:超参数学习曲线,是一条以超参数的取值为横坐标,模型的度量指标为纵坐标的曲线,它是用来衡量不同超参数取值下模型的表现的线

import matplotlib.pyplot as plt

test = []
for i in range(10):
    clf = tree.DecisionTreeClassifier(max_depth=i+1   # 1-10
                                    ,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()

(四)目标权重参数(完成样本标签平衡的参数,不常用) 

  1. class_weight:对样本标签进行一定的均衡,给少量的标签更多的权重,让模型更偏向少数类
  2. min_weight_fraction_leaf:有了权重之后,样本量就不再是单纯地记录数目,而是受输入的权重影响,此时剪枝需要基于权重的剪枝参数min_weight_fraction_leaf。它将比不知道样本权重的标准(如min_samples_leaf)更少偏向主导类

重要属性和接口

属性:在模型训练之后,能够调用查看的模型的各种性质。对决策树来说,属性feature_importances_能够查看各个特征对模型的重要性

接口:

  • fit 和 score:几乎每个算法都可以使用
  • apply:输入测试集,返回每个测试样本所在的叶子节点的索引
  • predict:输入测试集,返回每个测试样本的分类/回归结果

所有接口中要求输入 X_train 和 X_test 的部分,输入的特征矩阵必须至少是一个二维矩阵(sklearn不接受任何一维矩阵作为特征矩阵被输入)

  • 如果数据只有一个特征,必须用reshape(-1,1)来给矩阵增维
  • 如果数据只有一个特征和一个样本,使用reshape(1,-1)来给数据增维

总结 

分类树的八个参数、一个属性(feature_importances_)、四个接口(fit,score,apply,predict)

八个参数:

  • criterion
  • 两个随机性相关的参数:random_state,splitter
  • 五个剪枝参数:max_depth,min_samples_split,min_samples_leaf,max_feature,min_impurity_decrease 

回归树DecisionTreeRegressor与波士顿房价数据集

在回归树中,没有标签分布是否均衡的问题,故没有class_weight这样的参数

重要参数、属性及接口 

(一)criterion(回归树衡量分枝质量的指标)

  1. mse:均方误差(样本真实数据与回归结果的差异)
  2. friedman_mse:费尔德曼均方误差
  3. mae:绝对平均误差

在回归树中,MSE不只是分枝质量衡量指标,也是最常用的衡量回归树回归质量的指标

在使用交叉验证获取回归树的结果时,往往选择MSE作为评估(在分类树中是score代表的accuracy) 

(二)属性

feature_importances_

(三)接口

score返回的是R²(默认),不是MSE

u是残差平方和,v是总平方和
  • R²可以为正为负,取值范围是 ﹣∞ ~ 1(越接近1越好)
  • MSE永远为正 

(四)交叉验证 

将数据划分为n份,依次使用其中一份作为测试集,其他n-1份作为训练集,多次计算模型的精确性来评估模型的平均准确程度

训练集和测试集的划分会干扰模型的结果,因此用交叉验证n次的结果求出的平均值,是对模型效果的一个更好的度量

交叉验证的过程包含了fit 

from sklearn.datasets import load_boston
from sklearn.model_selection import cross_val_score
from sklearn.tree import DecisionTreeRegressor

boston = load_boston()   # 字典
# boston.data取数据,boston.target取标签(连续型变量)

regressor = DecisionTreeRegressor(random_state=0) #实例化
# 交叉验证传入的是完整数据,不需要划分训练集和测试集
# cv=10意味着十折,1份测试,9份训练。默认为5
cross_val_score(regressor, boston.data, boston.target, cv=10, scoring="neg_mean_squared_error").mean()

实例:一维回归的图像绘制 

用回归树来拟合正弦曲线,并添加一些噪声来观察回归树

.rand(x):随机生成x个0-1之间的随机数

.rand(x,y):x行y列的数组

np.random.rand(数组结构):生成随机数组
np.sort(axis=0):从小到大排序(按行)


.ravel():降维函数,n维降维n-1维,多次运行可以一直降到1维


np.newaxis:增维切片

  • l = np.array([1,2,3,4])    # (4,)
  • l[: , np.newaxis]    # (4,1)
  • l[np.newaxis, :]    # (1,4)
import numpy as np  # 生成数据点,即正弦曲线
from sklearn.tree import DecisionTreeRegressor
import matplotlib.pyplot as plt

# 创建一条含有噪声的正弦曲线

'''
基本思路:
先创建一组随机的、分布在0-5上的横坐标轴的取值(x),
然后将这一组值放到sin函数中去生成纵坐标的值(y),
接着再到y上去添加噪声
'''
rng = np.random.RandomState(1) #随机数种子(一种固定的随机)

'''
接口不允许导入一维数组,故X生成的是二维的
'''
X = np.sort(5 * rng.rand(80,1), axis=0) #生成0~5之间随机的x的取值

'''
输入的X是二维的,故np.sin(X)生成的结果也一定是二维的。
但是导入回归树的标签必须是一维的,否则会报错
故使用.ravel()降维
'''
y = np.sin(X).ravel() #生成正弦曲线

'''
y[::5]中的5为步长,故取出16个数
'''
y[::5] += 3 * (0.5 - rng.rand(16)) #在正弦曲线上加噪声

plt.figure()  # 画布
plt.scatter(X, y, s=20, edgecolor="black",c="darkorange", label="data")  # s为点的大小

# 实例化&训练模型
regr_1 = DecisionTreeRegressor(max_depth=2)
regr_2 = DecisionTreeRegressor(max_depth=5)
regr_1.fit(X, y)
regr_2.fit(X, y)

# 测试集导入模型,预测结果
X_test = np.arange(0.0, 5.0, 0.01)[:, np.newaxis]

y_1 = regr_1.predict(X_test)
y_2 = regr_2.predict(X_test)

# 绘制图像
plt.figure()
plt.scatter(X, y, s=20, edgecolor="black",c="darkorange", label="data")
plt.plot(X_test, y_1, color="cornflowerblue",label="max_depth=2", linewidth=2)
plt.plot(X_test, y_2, color="yellowgreen", label="max_depth=5", linewidth=2)   # 过拟合了
plt.xlabel("data")
plt.ylabel("target")
plt.title("Decision Tree Regression")
plt.legend()
plt.show()

如果树的最大深度(由max_depth控制)设置的太高,则决策树学习的太精细,它从训练数据中学了很多细节(包括噪声的呈现),从而使模型偏离真实的正弦曲线,过拟合


决策树的优缺点

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

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

相关文章

LOAM和SSL-SLAM

今天来水两个激光SLAM的相关框架的学习笔记。 一、LOAM 首先介绍scan-to-scan map-to-map scan-to-map之间的关系: 1.scan-to-scan匹配 即两帧激光雷达数据之间的匹配,目的是求得从起始帧A到目标帧B的相对平移量与旋转矩阵。目前来说scan-toscan中&a…

Elasticsearch搜索引擎

The Elastic Stack, 包括 Elasticsearch【搜索,分析】、 Kibana【可视化】、 Beats 和 Logstash【数据的搜集】(也称为 ELK Stack)。能够安全可靠地获取任何来源、任何格式的数据,然后实时地对数据进行搜索、分析和可视化。 Elati…

安装压缩包版mysql

一、mysql-8.0.21-winx64.zip解压 二、在解压后的目录下添加data目录 三、配置环境变量 win7: ​ 我的电脑–>属性–>高级系统设置–>高级–>环境变量 ​ 在下面系统变量中 ​ 新建 ​ 变量名:MYSQL_HOME ​ 变量值:E:\MySQL\my…

常用的接口安全性保障手段

http接口有哪些安全问题 数据被抓包窃取数据被恶意篡改数据被爬取泄漏Token授权机制 用户使用用户名密码登录后服务器给客户端返回一个Token(通常是UUID),并将Token-UserId以键值对的形式存放在缓存服务器中。服务端接收到请求后进行Token验…

UG NX二次开发(C#)-曲线-NXOpen.Curve初探

系列文章目录 `` 例如:第一章 初探NXOpen.Curve类 文章目录 系列文章目录1.前言2.NXOpen.Curve2. NXOpen.Curve包含的子类3.曲线类型的获取4.将曲线对象转换为子类类型1.前言 介绍下NXOpen.Curve类、Curve类型的获取、一些创建曲线的封装方法(包括直线、样条曲线、圆锥曲线…

OSM数据内容解析

OSM数据内容解析 数据简介 OpenStreetMap(简称OSM,中文是公开地图),这是一个网上地图协作计划,目标是创造一个内容自由且能让所有人编辑的世界地图。是一款由网络大众共同打造的免费开源、可编辑的地图服务。 OSM采…

成功实施APS生产排程系统,必须具备哪些条件?

在许多生产管理者眼中,生产作业计划是不重要的,如果我们只停留在小加工作坊的规模,大脑就能把一个月的订单、物料、资源记得清清楚楚,那么生产计划排程的必要性确实不太大,但事实上,随着生产规模的扩大&…

JDK1.8中HashMap的resize()方法详解

JDK1.8中HashMap的resize()方法详解 文章目录JDK1.8中HashMap的resize()方法详解[toc]一、概述二、源码解析三、元素迁移四、小结在学习本文之前,默认大家已经有了HashMap源码的前置知识。 「集合底层」深入浅出HashMap底层源码 一、概述 resize()方法的代码比较长…

OpenHarmony#深入浅出学习eTs#(四)登陆界面UI

本项目Gitee仓地址:深入浅出eTs学习: 带大家深入浅出学习eTs (gitee.com) 一、明确目标 经过前面两章的学习,大家对Super Visual应该有了一个较为简单的认识,这一章就把前面的知识点串一下,使用Ark UI(Super Visual)赖模仿一个Q…

浅谈权限系统在多利熊业务应用

作者 | 百度智能小程序团队 导读 本文首先引入多利熊业务介绍,引出多利熊业务建设权限系统的痛点,接着分别从权限系统模型、权限系统设计以及多利熊业务业务应用方面详细探讨了具体的方案和设计,最后对权限系统设计思考,对数据维度…

linux连接器脚本前奏-基于x86(一)

从今天开始进入正文,和讲解liteos一样,我们先从连接器脚本开讲。我们知道连接器脚本描述了编译输出程序的布局,那么linux内核编译输出的布局是怎么样的呢?听我慢慢道来,关于连接器脚本的大概使用用途,可以参见 liteos链接器脚本一 liteos链接器脚本二 这里先说明一下对于…

Python进行异步请求,实现多开任务

前言 本文是该专栏的第5篇,后面会持续分享python的各种干货知识,值得关注。 在工作中,你可能或多或少会接到这样一个任务需求。 给你一个任务队列,需要你进行多任务去实现处理,尤其在爬虫项目或者是使用selenium,pyppeteer等任务中比较常见,至于多线程和多进程那些,笔…

OpenCL 是什么

OpenCL 创建Program对象|极客笔记 文章目录 OpenCL标准什么是OpenCL OpenCL全称为Open Computing Language(开放计算语言),先由Apple设计,后来交由Khronos Group维护,是异构平台并行编程的开放的标准,也是…

antd 时间类组件的国际化 locale 设置不生效 解决方案汇总

antd 时间类组件的国际化 locale 设置不生效,踩坑之路和解决办法 问题 如图所示,antd 时间类组件中英文混合显示: 初始配置代码如下: import ./index.css; import ./global.less;import { ConfigProvider } from antd; import…

excel表格制作如何设置?新手必备教程!

Excel是一种专门用于制作表格、输入数据和统计分析的办公软件,日常办公中它带给我们极大的便利。下面我们一起来看看excel表格制作如何操作?为了方便理解,下面分为详细的六个步骤。你可以根据下面的操作顺序来操作(里面有些顺序是…

Windows版本Tomcat升级openssl版本

本次教程适用于windows版本安装Tomcat调整openssl版本。 下载Tomcat Native Tomcat native提供让Tomcat以APR模式运行,APR的全称是Apache Portable Runtime,它是一个高度可移植的库,它是Apache HTTP Server 2.x的核心。APR有许多用途&#…

element ui Form 自定义校验规则,验证手机号

网站快速成型工具 Element,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库 指南 了解设计指南,帮助产品设计人员搭建逻辑清晰、结构合理且高效易用的产品。 查看详情 组件 使用组件 Demo 快速体验交互细节;使用前端框架…

@开发者:个推小程序消息推送解决方案来了

随着小程序技术和应用场景的不断完善,越来越多的开发者搭建了小程序平台,为用户带来更“轻量”的服务。在小程序用户迅猛增长的同时,开发者对于小程序用户精细化触达的需求也愈加强烈。近日,个推消息推送上线了小程序推送功能&…

Python量化交易05——基于多因子选择和选股策略(随机森林,LGBM)

参考书目:深入浅出Python量化交易实战 在机器学习里面的X叫做特征变量,在统计学里面叫做协变量也叫自变量,在量化投资里面则叫做因子,所谓多因子就是有很多的特征变量。 本次带来的就是多因子模型,并且使用的是机器学习的强大的非…

Linux系统下的组管理和权限管理

Linux系统下的组管理和权限管理 组管理 在linux中的每个用户必须属于一个组,不能独立于组外。在linux中每个文件有所有者、所在组、其它组的概念。 对于一个文件而言,有以下几种说法:1)所有者;2)所在组;3)其它组&#…