机器学习实战2-决策树算法

news2024/11/24 2:58:07

文章目录

    • 决策树算法核心是要解决两个的关键问题
    • sklearn中的决策树模型
    • sklearn建模步骤
    • 分类树
      • Criterion
      • random_state && splitter
      • 剪枝参数
      • max_depth
      • min_samples_leaf&&min_samples_split
      • max_features&&min_impurity_decrease
      • 确认最优剪枝参数
      • 目标权重参数
      • 重要属性和接口
    • 回归树
      • 参数、属性、接口
        • Criterion
      • 交叉验证
    • sin函数模拟实例(回归树)
    • 案例:泰坦尼克号幸存者的预测
      • 导库
      • 读入数据
      • 数据预处理
        • 筛选特征
        • 处理缺失值
        • 处理数据类型
        • 数据集的划分
        • 模型的建立
          • 实例化模型
          • 交叉验证
          • 调参
        • 网格搜索

开发环境是:jupyter lab需要的库可以自行百度安装

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

1、如何从数据表中照出最佳节点和最佳分支
2、如何让决策树停止生长防止过拟合

就是说假如我有一张数据表,数据表中有成千上万个特征,我要把他们都提问完吗?

sklearn中的决策树模型

6.png
本文主要是学习分类树和回归树

sklearn建模步骤

7.png

from sklearn import tree
clf = tree.DecisionTreeClassifier()
clf = clf.fit(x_train, y_train)
result = clf.score(x_test, y_test)

分类树

Criterion

为了将表格转化为一棵树,决策树需要找到最佳节点和最佳分支方法,对于分类数来说衡量最佳的方法是叫做不纯度,通常来说不纯度越低,决策树对训练集的拟合效果越好,所有的决策树算法都是将和不纯度相关的某个属性最优化,不管我们用那个算法,都是追求的与不纯度相关的指标最优化
不纯度基于节点来计算,树中的每个节点都会有一个不纯度,并且子节点的不纯度一定低于父节点的不纯度,在一棵决策树上叶子节点的不纯度一定是最低的

Criterion这个参数就是用来决定不纯度计算方法的,sklearn中提供了两种方法
一种是输入“entropy”,使用信息熵
一种是输入"gini",使用基尼系数

8.png
我们无法干扰信息熵和基尼系数的计算,所以这里我们知道怎么算的即可,sklearn中的方法我们是无法干扰的
相比于基尼系数来说,信息熵对于不纯度更加敏感,对不纯度的更强,但在实际使用中两者的效果差不多,信息熵的计算相比于基尼系数会慢一点,因为基尼系数没有对数运算,因为信息熵对于不纯度更加敏感,所以信息熵在计算决策树时候会更加仔细,所以对于高维数据或者噪音很多的数据来说很容易过拟合
关于参数如何选择
9.png
10.png
我们可以看到我们的决策树中并没有用到我们所给的所有属性
11.png

clf = tree.DecisionTreeClassifier(criterion = "entropy", random_state=30)
clf = clf.fit(Xtrain, Ytrain)
score = clf.score(Xtest, Ytest) # 返回预测的准确度accuracy
score

random_state && splitter

用来设置分支中的随机模式的参数,默认为None,在高维度时随机性会表现更明显,低维度数据几乎不会显现,我们任意给random_state一个数值可以让模型稳定下来
决策树是随机的
splitter也是用来控制决策树中随机选项的可以输入best,决策树虽然分支时会随机但会有限选择更重要的特征进行分支,输入random分支时会更加随机,树会更深,拟合将会降低,这也是防止过拟合的一种方法

clf = tree.DecisionTreeClassifier(criterion = "entropy", splitter="best")
clf = clf.fit(Xtrain, Ytrain)
score = clf.score(Xtest, Ytest) # 返回预测的准确度accurac
score

剪枝参数

在不加限制的情况下,一颗决策树会生长到衡量不纯度的指标最优,或没有更多的特征可用停止,这样的决策树往往会过拟合,也就是说他会在训练集上表现很好,在测试集上表现却很糟糕
12.png

score = clf.score(Xtrain, Ytrain)
score

13.png

我们要分清楚过拟合的概念,过拟合,也就是说他会在训练集上表现很好,在测试集上表现却很糟糕,但如果我们在训练集和测试集上的表现效果都很好的话不能称为过拟合

剪枝策略对于决策树的影响巨大,正确的剪枝策略是决策树优化的核心

max_depth

限制树的最大深度,超过设定深度的树枝全部剪掉
这是用的最广泛的剪枝参数,在高维度低样本量时非常有效,决策树多生长一层对样本的需求量就会增加一倍,所以限制决策树的深度能够特别有效的限制过拟合,在集成算法中也非常常用,在实际使用过程中,建议我们从3开始尝试,看看拟合的效果再决定是否增加深度

min_samples_leaf&&min_samples_split

这两个是用来限制叶子节点的参数,
min_samples_leaf建议从5开始使用
min_samples_split:一个节点至少包含min_samples_split个样本才被允许进行分支

max_features&&min_impurity_decrease

14.png

确认最优剪枝参数

使用确认超参数的曲线

import matplotlib.pyplot as plt
test = []
for i in range(10):
    clf = tree.DecisionTreeClassifier(criterion = "entropy"
                                      , random_state=30
                                      , splitter="random"
                                      , max_depth = i + 1
                                     )
    clf = clf.fit(Xtrain, Ytrain)
    score = clf.score(Xtest, Ytest) # 返回预测的准确度accuracy
    test.append(score)
plt.plot(range(1,11), test,color = "red", label="max_depth")
plt.legend()
plt.show()

15.png
16.png

目标权重参数

17.png

重要属性和接口

fit
score
apply
predict
18.png
19.png

回归树

参数、属性、接口

Criterion

回归树衡量分枝质量的指标,支持的有三种
1、mse使用均方误差
2、friedman_mse误差费尔德曼均方误差
3、mae绝对均方误差
这里面也有许多数学原理,但是我们在使用sklearn时不用关心,因为这些因素我们并无法干预
20.png
属性依然是feature_importance_
接口中依然是
fit
score
apply
predict
是最核心
21.png

交叉验证

交叉验证是用来验证模型稳定性的一种方法,我们将数据划分为n份,依次使用其中一份作为测试集,其他n-1份作为训练集,多次计算模型的精确性来评估模型的平均准确程度
22.png

23.png
导入所需要的库

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

导入数据集

diabetes = load_diabetes()

实例化并交叉验证

regressor = DecisionTreeRegressor(random_state = 0) #实例化
cross_val_score(regressor
				, diabetes.data
				, diabetes.target
				, cv = 10
				, scoring = "neg_mean_squared_error") #交叉验证

参数解读
1、第一个参数可以是回归也可以是分类,这里的模型不止可以是决策树,可以是其他的支持向量机、随机森林等等模型,可以是任何我们实例化后的算法模型
2、第二个参数是完整的不需要分测试集和训练集的特征矩阵,交叉验证会自己帮我们划分测试集和数据集
3、第三个参数是数据的标签(完整的数据标签)
4、cv = 10是将数据集分成10分,每次用其中的一份作为测试集,通常我们将这个数设为5
5、scoring用后面的neg_mean_squared_error衡量我们交叉测试的结果,当默认时会返回R2可能为负数,但是我们在做回归时最常用的是均方误差,neg_mean_squared_error是负均方误差,R2越接近1越好

sin函数模拟实例(回归树)

导入库

import numpy as np
from sklearn.tree import DecisionTreeRegressor
import matplotlib.pyplot as plt

随机种子

rng = np.random.RandomState(1)

生成数据

x = np.sort(5 * rng.rand(80, 1), axis=0)
y = np.sin(x).ravel() # 降维使我们的数据只有一维
# y = np.sin(x).ravel()我们现实中不可获得的数据的真实的状况,所以我们需要加入一些噪声
print(y.shape)
y[::5] += 3 * (0.5 - rng.rand(16)) # 这里涉及切片的用法,行、列、最后一个是步长,这里表示对所有的数进行步长为5的切片,这一步是添加噪声

作图

plt.figure()
plt.scatter(x, y, s= 20, edgecolor = "black", c = "darkorange", label = "data")

不包含噪声的图
26.png
包含噪声的图
25.png

降维函数ravel()的使用、

27.png
实例化模型

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]
# 用numpy生成的随机数
np.arange(开始点, 结束点, 步长)

增维切片np.newaxis

28.png

作图

plt.figure() # 告诉python我们要画图了,让他帮我们生成一张画布
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 gression")
# 显示图例
plt.legend()

plt.show()

30.png
4.png

案例:泰坦尼克号幸存者的预测

5.png

导库

import pandas as pd
from sklearn.tree import DecisionTreeClassifier
import matplotlib as plt
from sklearn.model_selection import GridSearchCV

读入数据

data = pd.read_csv(r"C:\Users\cxy\OneDrive\桌面\titanic\train.csv") #加r之后不用将里面面向左的下划线改成向右的

数据如下图
2.png
数据来源于坦坦尼克号数据集
观察我们的数据集,我们的标签一般我们习惯上放在最后一列,但是在这个数据集中并不是在最后一列所以这里我们用切片的方式将标签提取出来
我们先来探索数据

data.info()

3.png
我们的数据集一共有891行0到890是我们的索引,
我们还可以观察到我们的这些标签中有很多不是数字类型的,有很多类类型,而我们的分类器是不能处理这些数据类型的
我们还可以观察到表中还有很多缺失值,例如年龄这些都是需要我们去处理的

#显示前几行数据,可以有一个参数n,如果不填默认是5,可以有效地帮我查看表的样式
data.head()

4.png

数据预处理

筛选特征

data.drop(['Cabin', "Name", "Ticket"], inplace = True, axis = 1)

删除名为’Cabin’, “Name”, "Ticket"的列, inplace = True这个参数的作用是用新生成的表覆盖原表,axis=1表示对列进行操作
5.png
6.png

处理缺失值

我们可以看到当我筛选完特征之后数据中依然含有一些特征是有很多的缺失值的,所以这时我们要对这些缺失值进行处理

data['Age'] = data['Age'].fillna(data['Age'].mean())

这里我们对于这种缺失值的处理使用年龄的平均值去进行处理的,这里也给我们的数据添加了一些噪声,对于有些缺失值我们也可以直接用0去填补
7.png
可以看到我们填充之后年龄这一属性就没有缺失值了
这里我们再次观察我们的数据集,我们会发现Embarked这一属性还是有缺失值,但是缺失值只有几个比较少,我们就直接把那几个缺失值的行给删去即可

data = data.dropna(axis = 0)

8.png

处理数据类型

我们知道决策树是处理不了文字类型的所以遇到文字类型,我们需要处理这些文字类型的数据
unique()方法是对数据进行去重,我们就可以得到这个数据有多少种取值

data['Embarked'].unique()

9.png

data['Embarked'].unique().tolist()

10.png
这里tolist()方法可以将array转化为list

data['Embarked'].apply(lambda x : labels.index(x))

11.png

labels.index("S")

12.png

只要我们unique()后的数据不超过10个我们都可以用这种方式来处理数据,前提是我们的数据之前没有联系就比如我们的S、Q、C中的数据没有任何关系

对于性别的处理我们仍然可以按照上述方式不过这里性别是二分类,我们可以另一种方式去处理

data.loc[:,"Sex"] = (data["Sex"] == "male").astype("int")

数据处理完之后我们就可接着回到sklearn了,sklearn中特征和标签是分开的,所以这里我们也需要将特征和标签分开

x = data.iloc[:, data.columns != "Survived"]

13.png

y = data.iloc[:, data.columns == "Survived"]

14.png

数据集的划分

Xtrain, Xtest, Ytrain, Ytest = train_test_split(x, y, test_size = 0.3)

15.png
我们可以看到由于我们的数据集是随机划分的,所以划分完之后的索引也变乱了,如果我们不是刻意需要保持索引的乱序,我们一般来说需要将索引调整为升序

Xtrain.index = range(Xtrain.shape[0])

16.png

for i in [Xtrain, Xtest, Ytrain, Ytest]:
    i.index = range(i.shape[0])

因为有四组数据我们可以直接用循环来处理

索引的处理是很重要的,我们只要在进行了某些随机操作,为了避免后续出错一般来说都需要将索引恢复到正常

至此我们将数据处理的所有工作完成,下面我们就可以开始跑模型了

模型的建立

实例化模型
clf = DecisionTreeClassifier(random_state=30)
clf = clf.fit(Xtrain, Ytrain)
score = clf.score(Xtest, Ytest)

score

17.png

交叉验证
from sklearn.model_selection import cross_val_score
clf = DecisionTreeClassifier(random_state=25)
# mean()是求均值的方法
score = cross_val_score(clf, x, y, cv = 10).mean()
score

18.png
我们可以看到这里平均得分相比于我们上面随机划分的数据集得分低,这说明我们随机划分的数据集比较好,接下来我们就需要通过调参来将模型的得分调高

调参

画超参数的曲线

import matplotlib.pyplot as plt 
te = []
tr = []
for i in range(10):
    clf = DecisionTreeClassifier(random_state = 25
                                ,max_depth = i + 1)
    clf = clf.fit(Xtrain, Ytrain)
    score_tr = clf.score(Xtrain, Ytrain)
    score_te = cross_val_score(clf, x, y, cv = 10).mean()
    tr.append(score_tr)
    te.append(score_te)
print(max(te))
plt.plot(range(1, 11), tr, color = "red", label = 'train')
plt.plot(range(1, 11), te, color = 'blue', label = 'test')
plt.xticks(range(1, 11))
plt.legend()
plt.show()

19.png
我们可以看到随着树的层数的加深,过拟合的程度越来越严重,我可以看到极值点在3这说明在max_depth = 3的时候过拟合程度是最小的,所以我们就需要将max_depth固定在3然后i去调节其他参数
我们可以看到当我们将criterion设置为entropy后score会有怎样的变化

import matplotlib.pyplot as plt 
te = []
tr = []
for i in range(10):
    clf = DecisionTreeClassifier(random_state = 25
                                ,max_depth = i + 1
                                ,criterion = 'entropy'
                                )
    clf = clf.fit(Xtrain, Ytrain)
    score_tr = clf.score(Xtrain, Ytrain)
    score_te = cross_val_score(clf, x, y, cv = 10).mean()
    tr.append(score_tr)
    te.append(score_te)
print(max(te))
plt.plot(range(1, 11), tr, color = "red", label = 'train')
plt.plot(range(1, 11), te, color = 'blue', label = 'test')
plt.xticks(range(1, 11))
plt.legend()
plt.show()

20.png
可以看到我们模型的结果变好了
我们仍需要剪枝调参,我们不可能一个一个的画学习曲线,找出最优的组合,这里我们就要引入一个新的知识点叫网格搜索

网格搜索

网格搜索能够帮助我们一次调节多个参数的技术,枚举的思路
缺点:计算量很大,这时由于枚举本身就很耗时

linspace和arange的区别
linspace是随机的,arange是指定步长

import numpy as np
# 在给定的数据范围内取出指定个有顺序的随机数
jini_threholds = np.linspace(0, 0.5, 50)
# enproty_threholds = np.linspace(0, 1, 50)

# 一些参数和这些参数对应的,我们希望网格搜索来搜索的参数的取值范围
parameters = {"criterion" : ("gini", "rntropy")
              ,"splitter" : ("best", "random")
              ,"max_depth"  : [*range(1, 10)]
              ,"min_samples_leaf":[*range(1, 50, 5)]
              ,"min_impurity_decrease" : [*np.linspace(0, 0.5, 50)]
              
}

clf = DecisionTreeClassifier(random_state = 25)
GS = GridSearchCV(clf, parameters, cv = 10) # 同时满足了fit, score, 交叉验证三种功能
GS = GS.fit(Xtrain, Ytrain)

网格搜索模型中的参数(两个比较重要的参数)

GS.best_params_ #从我们输入的参数和参数取值的列表中,返回最佳组合
GS.best_score_ #网格搜索后的模型的评判标准

21.png

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

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

相关文章

谈谈Spring与字节码生成技术

Java程序员几乎都了解Spring。 它的IoC(依赖反转)和AOP(面向切面编程)功能非常强大、易用。而它背后的字节码生成技术(在运行时,根据需要修改和生成Java字节码的技术)就是一项重要的支撑技术。 …

spring之AOP简单介绍

1.AOP的概念 AOP,Aspect Oriented Programming,面向切面编程,是对面向对象编程OOP的升华。OOP是纵向对一个 事物的抽象,一个对象包括静态的属性信息,包括动态的方法信息等。而AOP是横向的对不同事物的抽象,…

云原生之深入解析Redis的原理分析与环境部署

一、Redis 简介 ① 什么是 Redis ? REmote DIctionary Server(Redis)是一个由 Salvatore Sanfilippo 写的 key-value 存储系统,是跨平台的非关系型数据库。Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可…

Linux —— 基础I/O(一)

目录 一,背景介绍 二,系统接口函数 open 打开或创建文件 close 关闭文件 read 读取文件 write 写入文件 三,文件描述符 结构体指针files 结构体指针files指向的表files_struct 文件结构体 一,背景介绍 狭义的文件存放在…

爆肝整理,接口测试-Fiddler对Jmeter请求抓包(详细实战)

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 使用Fiddler结合J…

编写html页面让谷歌浏览器不弹出“翻译此页”的问题

文章目录 1.问题2.解决总结 1.问题 2.解决 如下图,将html的lang由en改为zh-CN(注意大小写) 总结 将html的lang由en改为zh-CN

基于PyTorch的图像识别

前言 图像识别是计算机视觉领域的一个重要方向,具有广泛的应用场景,如医学影像诊断、智能驾驶、安防监控等。在本项目中,我们将使用PyTorch来开发一个基于卷积神经网络的图像识别模型,用来识别图像中的物体。下面是要识别的四种物…

Java作业2

1.递归求解汉诺塔问题 拿三个为例子 先从A设法拿走两个盘子到B上,再拿一个盘子到C上,再从B上挪走一个到A,再挪下面的到C上 如果有N个盘子,我们也一样的步骤,先设法拿N-1个盘子到B,再拿最底部的盘子到C&a…

【算法】逆波兰表达式

文章目录 定义求法代码思想: 定义 逆波兰表达式也称为“后缀表达式”,是将运算符写在操作数之后的运算式。 求法 *如:(ab)c-(ab)/e的转换过程: 先加上所有的括号。 (((ab)*c)-((ab)/e))将所有的运算符移到括号外面 (((ab) c)* …

Unity游戏源码分享-全民飞机大战源码unity2019

Unity游戏源码分享-全民飞机大战源码unity2019 项目地址:https://download.csdn.net/download/Highning0007/88204008

67 # 对象的处理

上一节学习了 form 数据的处理,这一节学习 Ajax 的方式提交数据 服务端的代码如下 const http require("http"); const url require("url"); const querystring require("querystring");let server http.createServer();server…

定时器

定时器 定时器是什么 定时器也是软件开发中的一个重要组件. 类似于一个 “闹钟”. 达到一个设定的时间之后, 就执行某个指定好的代码. 定时器是一种实际开发中非常常用的组件. 比如网络通信中, 如果对方 500ms 内没有返回数据, 则断开连接尝试重连. 比如一个 Map, 希望里面的…

elasticsearch简单入门语法

基本操作 创建不同的分词器 ik_smart: 极简分词 ; ik_max_word: 最细力再度分词 基本的rest命令 methodurl地址描述PUTlocalhost:9200/索引名称/类型名称/文档id创建文档(指定文档id)POSTlocalhost:9200/索引名称/类型名称创建文…

Qt应用开发(基础篇)——堆栈窗口 QStackedWidget

一、前言 QStackedWidget继承于QFrame,QFrame继承于QWidget,是Qt常用的堆栈窗口部件。 框架类QFrame介绍 QStackedWidget堆栈窗口,根据下标切换,一次显示一个小部件,常用于应用界面切换、图片轮询播放等场景。 二、QSt…

Linu网络服务NFS

linux网络服务NFS 一.NFS简介二.NFS原理三.NFS优势四.配置文件五.NFS共享存储服务的操作步骤 一.NFS简介 NFS(网络文件服务) NFS是一种基于tcp/ip传输的网络文件系统协议,最初由sun公司开放通过使用NFS协议,客户机可以像访问本地…

Java课题笔记~ ServletContext

单个Servlet的配置对象 web.xml <servlet><servlet-name>FirstServlet</servlet-name><servlet-class>com.ambow.test.FirstServlet</servlet-class><init-param><param-name>charset</param-name><param-value>utf-8&…

SpringMVC注解配置

1xml配置方式&#xff08;配置文件注解的方式&#xff09; 前提导入相关依赖&#xff1a;pom文件 说明&#xff1a;下方依赖是ssm项目中较为常用的一部分&#xff0c;可能部分依赖对于springmvc配置并未有关系&#xff0c;根据自己需求添加和删除。 <dependencies> &l…

新手如何快速学习单片机?

初步确定学习目标&#xff1a;是学习简单便宜的51呢&#xff0c;还是学习简单但是性价比已经不算太高的&#xff0c;但是功能强大稳定可靠的avr&#xff0c;还是物美价廉的stm32&#xff0c;或者ARM9&#xff08;可以跑系统了&#xff09;&#xff0c;再往上x86什么的如果是学8…

成员变量和局部变量的区别

局部变量成员变量 1、定义的位置不一样 在方法的内部&#xff0c;方法申明上&#xff08;形参&#xff09;。 声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量 在方法的外部&#xff0c;直接写在类当中 &#xff08;类中方法外的变量&#xff09; 2、作用范…

opencv 实现手势跟踪并返回位置信息(封装调用)

OpenCV 是一个基于 Apache2.0 许可&#xff08;开源&#xff09;发行的跨平台计算机视觉和机器学习软件库&#xff0c;可以运行在Linux、Windows、Android和Mac OS操作系统上。 需要提前准备opencv 和 mediapipe库 pip --default-timeout5000 install -i https://pypi.tuna.t…