Python 全栈体系【四阶】(十)

2024-01-01 20:44
文章标签 python 体系 全栈 四阶

本文主要是介绍Python 全栈体系【四阶】(十),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

第四章 机器学习

十三、决策树分类

1. 决策树

1.1 什么是决策树

决策树是一种常见的机器学习方法,其核心思想是相同(或相似)的输入产生相同(或相似)的输出,通过树状结构来进行决策,其目的是通过对样本不同属性的判断决策,将具有相同属性的样本划分到一个叶子节点下,从而实现分类或回归。以下是几个生活中关于决策树的示例。

【示例 1】

在这里插入图片描述

男生看女生与女生看男生的决策树模型

【示例 2】

在这里插入图片描述

挑选西瓜的决策树模型

在上述示例模型中,通过对西瓜一系列特征(色泽、根蒂、敲声等)的判断,最终我们得出结论:这是否为一个好瓜。决策过程中提出的每个判定问题都是对某个属性的“测试”,例如“色泽=?”,“根蒂=?”。每个测试的结果可能得到最终结论,也可能需要进行下一步判断,其考虑问题的范围是在上次决策结果限定范围之内。例如若在“色泽=青绿”之后再判断“根蒂=?”。

1.2 决策树的结构

一般来说,一棵决策树包含一个根节点、若干个内部节点和若干个叶子节点。叶子节点对应最终的决策结果,其它每个节点则对应与一个属性的测试。最终划分到同一个叶子节点上的样本,具有相同的决策属性,可以对这些样本的值求平均值来实现回归,对这些样本进行投票(选取样本数量最多的类别)实现分类。

在这里插入图片描述

1.3 如何构建决策树
1.3.1 构建决策树算法

决策树的构建,就是不断选取好的特征作为决策节点,构建一颗泛化能力较强的树结构,其基本算法描述如下:

在这里插入图片描述

显然,决策树的构建是一个递归的过程,核心是以下两个问题:

  • 如何选取特征。决策树构建的每一步,应该挑选最优的特征,进行决策对数据集划分效果最好;
  • 决定何时停止分裂子节点。

PS:

  • classification and regresstion tree
  • 回归:划分最优分割特征的方式是均方误差
1.3.2 如何选择特征
1.3.2.1 信息熵

信息熵(information entropy)是度量样本集合纯度的常用指标,该值越大,表示该集合纯度越低(或越混乱),该值越小,表示该集合纯度越高(或越有序)。信息熵定义如下:

H = − ∑ i = 1 n P ( x i ) l o g 2 P ( x i ) H = -\sum_{i=1}^{n}{P(x_i)log_2P(x_i)} H=i=1nP(xi)log2P(xi)

其中, P ( x i ) P(x_i) P(xi)表示集合中第 i 类样本所占比例,当 P ( x i ) P(x_i) P(xi)为 1 时(只有一个类别,比例为 100%), l o g 2 P ( x i ) log_2P(x_i) log2P(xi)的值为 0,整个系统信息熵为 0;当类别越多,则 P ( x i ) P(x_i) P(xi)的值越接近于 0, l o g 2 P ( x i ) log_2P(x_i) log2P(xi)趋近去负无穷大,整个系统信息熵就越大。以下代码,展示了类别数量从 1…10 的集合信息熵变化:

# 信息熵计算演示
import math
import numpy as np
import matplotlib.pyplot as mpclass_num = 10  # 类别最大数量def entropy_calc(n):p = 1.0 / n  # 计算每个类别的概率entropy_value = 0.0  # 信息熵for i in range(n):p_i = p * math.log(p)entropy_value += p_ireturn -entropy_value  # 返回熵值entropies = []
for i in range(1, class_num + 1):entropy = entropy_calc(i)  # 计算类别为i的熵值entropies.append(entropy)print(entropies)# 可视化回归曲线
mp.figure('Entropy', facecolor='lightgray')
mp.title('Entropy', fontsize=20)
mp.xlabel('Class Num', fontsize=14)
mp.ylabel('Entropy', fontsize=14)
mp.tick_params(labelsize=10)
mp.grid(linestyle='-')
x = np.arange(0, 10, 1)
print(x)
mp.plot(x, entropies, c='orangered', label='entropy')mp.legend()
mp.show()

执行结果:

在这里插入图片描述

PS:

  • 随着决策树的节点划分,纯度是在不断地提升,熵值不断地减小。

  • 优先选择特征属性强的特征。

1.3.2.2 信息增益

决策树根据属性进行判断,将具有相同属性的样本划分到相同节点下,此时,样本比划分之前更加有序(混乱程度降低),信息熵的值有所降低。用划分前的信息熵减去划分后的信息熵,就是决策树获得的信息增益。可以用以下表达式表示:

G a i n ( D , a ) = E n t ( D ) − ∑ v = 1 V ∣ D v ∣ ∣ D ∣ E n t ( D v ) Gain(D, a) = Ent(D) - \sum_{v=1}^{V} \frac{|D^v|}{|D|} Ent(D^v) Gain(D,a)=Ent(D)v=1VDDvEnt(Dv)

其中,D 表示样本集合,a 表示属性,v 表示属性可能的取值 v 1 , v 2 , . . . , v n {v^1, v^2,...,v^n} v1,v2,...,vn, ∣ D v ∣ ∣ D ∣ \frac{|D^v|}{|D|} DDv表示权重,样本越多的分支对分类结果影响更大,赋予更高的权重, G a i n ( D , a ) Gain(D, a) Gain(D,a)表示在样本集合 D 上使用属性 a 来划分子节点所获得的信息增益。以下是一个关于信息增益计算的示例。

在这里插入图片描述

说明:

  • 香蕉占 2/5,所以 P 1 = 0.4 P_1=0.4 P1=0.4;梨占 1/5,所以 P 2 = 0.2 P_2 = 0.2 P2=0.2;黄瓜占 1/5,所以 P 3 = 0.4 P_3 = 0.4 P3=0.4
  • 根节点信息熵: − ( 0.4 ∗ l o g 2 0.4 + 0.2 ∗ l o g 2 0.2 + 0.4 ∗ l o g 2 0.4 ) ≈ 1.522 -(0.4 * log_2 0.4 + 0.2 * log_2 0.2 + 0.4 * log_2 0.4) \approx 1.522 (0.4log20.4+0.2log20.2+0.4log20.4)1.522
  • 根据颜色划分后:黄色分支信息熵 − ( 2 3 ∗ l o g 2 2 3 + 1 3 ∗ l o g 2 1 3 ) ≈ 0.918 -(\frac{2}{3} * log_2 \frac{2}{3} + \frac{1}{3} * log_2 \frac{1}{3}) \approx 0.918 (32log232+31log231)0.918;绿色分支信息熵 − ( 1.0 ∗ l o g 2 1.0 ) = 0 -(1.0 * log_2 1.0) = 0 (1.0log21.0)=0;整个第二层信息熵为 0.6 ∗ 0.918 + 0.4 ∗ 0 ≈ 0.55 0.6 * 0.918 + 0.4 * 0 \approx 0.55 0.60.918+0.400.55
  • 根据颜色划分后的信息增益: 1.522 − 0.55 ≈ 0.97 1.522 - 0.55 \approx 0.97 1.5220.550.97

由以上示例可知,经过对样本按颜色进行类别划分,划分后的信息熵比原来下降了,下降的值就是信息增益。一般来说,信息增益越大,以该属性划分所获得的“纯度提升”越大。著名的 ID3 决策树学习算法就是以信息增益为准则来划分属性。

1.3.2.3 增益率

增益率不直接采用信息增益,而采用信息增益与熵值的比率来作为衡量特征优劣的标准. C4.5 算法就是使用增益率作为标准来划分属性. 增益率定义为:

G a i n _ r a t i o ( D , a ) = G a i n ( D , a ) I V ( a ) Gain\_ratio(D, a) = \frac{Gain(D, a)}{IV(a)} Gain_ratio(D,a)=IV(a)Gain(D,a)

其中

I V ( a ) = − ∑ v = 1 V ∣ D v ∣ ∣ D ∣ l o g 2 ∣ D v ∣ ∣ D ∣ IV(a) = - \sum_{v=1}^{V} \frac{|D^v|}{|D|} log_2 \frac{|D^v|}{|D|} IV(a)=v=1VDDvlog2DDv

1.3.2.4 基尼系数

基尼系数定义为:

G i n i ( p ) = ∑ k = 1 k p k ( 1 − p k ) = 1 − ∑ k = 1 k p k 2 Gini(p) = \sum_{k=1}^{k} p_k (1-p_k) = 1 - \sum_{k=1}^{k} p_k^2 Gini(p)=k=1kpk(1pk)=1k=1kpk2

直观来说,基尼系数反映了从数据集 D 中随机抽取两个样本,类别标记不一致的概率。因此,基尼系数越小,数据集的纯度越高。CART 决策树(Classification And Regression Tree)使用基尼系数来选择划分属性,选择属性时,选择划分后基尼值最小的属性作为最优属性。采用和上式相同的符号表示,数据集 D 下属性 a 的基尼系数定义为:

G i n i _ i n d e x ( D , a ) = ∑ v = 1 V ∣ D v ∣ ∣ D ∣ G i n i ( D v ) Gini\_index(D, a) = \sum_{v=1}^{V} \frac{|D^v|}{|D|} Gini(D^v) Gini_index(D,a)=v=1VDDvGini(Dv)

1.3.2.5 总结

cart:

  • 回归:均方误差 mse
  • 分类:Gini 系数

ID3:

  • 信息增益

C4.5:

  • 增益率
1.3.3 如何停止分裂

以下几种情况会停止决策树子节点的构建:

  • 当前节点所有样本属于同一个类别,无需划分
  • 当前属性集为空,或者所有样本取值相同,无法划分
  • 当前节点包含的样本集合为空,不能划分
  • 当前节点样本数量少于指定数量
1.4 如何实现决策树

scikit-learn 中决策树相关 API:

# 模型
model = st.DecisionTreeRegressor(max_depth=4)   # 决策树回归器
model = st.DecisionTreeClassifier(max_depth=4)	# 决策树分类器
# 训练
model.fit(train_x, train_y)
# 预测
pre_test_y = model.predict(test_x)
【案例】波士顿房价预测
1. 数据集介绍

该数据集为一个开放房价数据集,包含 506 笔样本,每个样本包含 13 个特征和 1 个标签,具体如下所示:

在这里插入图片描述

2. 代码实现
# 决策树回归示例
# 使用决策树预测波士顿房价import sklearn.datasets as sd
import sklearn.utils as su
import sklearn.tree as st
import sklearn.ensemble as se
import sklearn.metrics as smboston = sd.load_boston()  # 加载boston地区房价数据
print(boston.feature_names)
print(boston.data.shape)
print(boston.target.shape)random_seed = 7  # 随机种子,计算随机值,相同的随机种子得到的随机值一样
x, y = su.shuffle(boston.data, boston.target, random_state = random_seed)
# 计算训练数据的数量
train_size = int(len(x) * 0.8) # 以boston.data中80%的数据作为训练数据
# 构建训练数据、测试数据
train_x = x[:train_size]  # 训练输入, x前面80%的数据
test_x = x[train_size:]   # 测试输入, x后面20%的数据
train_y = y[:train_size]  # 训练输出
test_y = y[train_size:]   # 测试输出######## 单棵树进行预测 ########
# 模型
model = st.DecisionTreeRegressor(max_depth=4)  # 决策回归器# 训练
model.fit(train_x, train_y)
# 预测
pre_test_y = model.predict(test_x)
# 打印预测输出和实际输出的R2值
print(sm.r2_score(test_y, pre_test_y))

执行结果

['CRIM' 'ZN' 'INDUS' 'CHAS' 'NOX' 'RM' 'AGE' 'DIS' 'RAD' 'TAX' 'PTRATIO''B' 'LSTAT']
(506, 13)
(506,)
0.8202560889408634
3. 特征重要性

作为决策树模型训练过程中的副产品,根据每个特征划分子表前后信息熵减少量就标志了该特征的重要程度,此即为该特征重要性的指标。训练后得到的模型对象提供了属性 featureimportances来存储每个特征的重要性。在工程应用上,可以对决策树做一些优化,不必让每一个特征都参与子表划分,而只选择其中较重要的(或者说影响因素较大的)的特征作为子表划分依据。特征重要性的评价指标,就是根据该特征划分子表后所带来的信息熵减少量,熵减越大的就越重要,也就越优先参与子表的划分。

在上述示例中加入如下代码:

import matplotlib.pyplot as mp
import numpy as np
fi = model.feature_importances_  # 获取特征重要性
print("fi:", fi)# 特征重要性可视化
mp.figure("Feature importances", facecolor="lightgray")
mp.plot()
mp.title("DT Feature", fontsize=16)
mp.ylabel("Feature importances", fontsize=14)
mp.grid(linestyle=":", axis=1)
x = np.arange(fi.size)
sorted_idx = fi.argsort()[::-1]  # 重要性排序(倒序)
fi = fi[sorted_idx]  # 根据排序索引重新排特征值
mp.xticks(x, boston.feature_names[sorted_idx])
mp.bar(x, fi, 0.4, color="dodgerblue", label="DT Feature importances")mp.legend()
mp.tight_layout()
mp.show()

执行结果:

在这里插入图片描述

1.5 决策树的剪枝

剪枝(pruning)是决策树学习算法对付“过拟合”的主要手段。在决策树学习中,为了尽可能正确分类训练样本,节点划分过程将不断重复,有时会造成决策树分支过多,这时就可能因训练样本学的“太好了”,以至于把训练集本身的一些特点当做数据所具有的一般性质而导致过拟合。因此,可通过主动去掉一些分支来降低过拟合风险。

(1)预剪枝。决策树生成过程中,对每个节点在划分前进行评估,若当前节点不能带来决策树泛化性能的提升,则停止划分并将当前节点标记为叶子节点。

(2)后剪枝。先训练为一颗完整的决策树,然后自低向上对非叶子节点进行考察,若将该节点对应的子树替换为叶节点能带来决策树泛化能力提升,则将该子树替换为叶节点。

2. 集成学习与随机森林

2.1 集成学习

集成学习(ensemble learning)通过构建并合并多个模型来完成学习任务,从而获得比单一学习模型更显著优越的泛化性能,简言之,集成学习就是利用模型的“集体智慧”,提升预测的准确率。根据单个模型方式,集成学习可以分为两大类:

  • 个体间存在强依赖关系,必须串行生成的序列化方法,其代表为 Boosting 算法;
  • 个体之间不存在强依赖关系,可同时生成的并行化方法,代表是 Bagging 和随机森林算法。
2.2 Boosting
2.2.1 什么是 Boosting

Boosting(直译为推进、提升)是一族可以将弱学习器提升为强学习器的算法,其工作原理是:

  • 先训练出一个初始模型;
  • 根据模型的表现进行调整,使得模型预测错误的数据获得更多的关注,再重新训练下一个模型;
  • 不断重复第二步,直到模型数量达到预先设定的数目 T,最终将这 T 个模型加权结合。

AdaBoosting 是 Boosting 算法族中最著名的算法,它根据每次训练集之中每个样本的分类是否正确,以及上次的总体分类的准确率,来确定每个样本的权值。将修改过权值的新数据集送给下层分类器进行训练,最后将每次训练得到的分类器最后融合起来,作为最后的决策分类器。

2.2.2 实现 Boosting

sklearn 中,AdaBoosting 相关 API:

import sklearn.tree as st
import sklearn.ensemble as se# model: 决策树模型(单个模型,基学习器)
model = st.DecisionTreeRegressor(max_depth=4)# n_estimators:构建400棵不同权重的决策树,训练模型
model = se.AdaBoostRegressor(model, # 单模型n_estimators=400, # 决策树数量random_state=7)# 随机种子# 训练模型
model.fit(train_x, train_y)# 测试模型
pred_test_y = model.predict(test_x)

代码:

# AdaBoosting示例
# 使用AdaBoosting预测波士顿房价
import sklearn.datasets as sd
import sklearn.utils as su
import sklearn.tree as st
import sklearn.ensemble as se
import sklearn.metrics as smboston = sd.load_boston()  # 加载boston地区房价数据
print(boston.feature_names)
print(boston.data.shape)
print(boston.target.shape)random_seed = 7  # 随机种子,计算随机值,相同的随机种子得到的随机值一样
x, y = su.shuffle(boston.data, boston.target, random_state = random_seed)
# 计算训练数据的数量
train_size = int(len(x) * 0.8) # 以boston.data中80%的数据作为训练数据
# 构建训练数据、测试数据
train_x = x[:train_size]  # 训练输入, x前面80%的数据
test_x = x[train_size:]   # 测试输入, x后面20%的数据
train_y = y[:train_size]  # 训练输出
test_y = y[train_size:]   # 测试输出model2 = se.AdaBoostRegressor(st.DecisionTreeRegressor(max_depth=4),n_estimators=400,   # 决策树数量random_state=random_seed) # 随机种子
# 训练
model2.fit(train_x, train_y)
# 预测
pre_test_y2 = model2.predict(test_x)
# 打印预测输出和实际输出的R2值
print(sm.r2_score(test_y, pre_test_y2))

执行结果:

['CRIM' 'ZN' 'INDUS' 'CHAS' 'NOX' 'RM' 'AGE' 'DIS' 'RAD' 'TAX' 'PTRATIO''B' 'LSTAT']
(506, 13)
(506,)
0.9068598725149652

可以看到,通过 AdaBoosting 算法,回归模型获得了更高的 R2 值。

2.3 随机森林
2.3.1 什么是随机森林

随机森林(Random Forest,简称 RF)是专门为决策树设计的一种集成方法,是 Bagging 法的一种拓展,它是指每次构建决策树模型时,不仅随机选择部分样本,而且还随机选择部分特征来构建多棵决策树。这样不仅规避了强势样本对预测结果的影响,而且也削弱了强势特征的影响,使模型具有更强的泛化能力。

随机森林简单、容易实现、计算开销小,在很多现实任务中展现出强大的性能,被誉为“代表集成学习技术水平的方法”。

2.3.2 如何实现随机森林

sklearn 中,随机森林相关 API:

import sklearn.ensemble as semodel = se.RandomForestRegressor(max_depth, # 决策树最大深度n_estimators, # 决策树数量min_samples_split)# 子表中最小样本数 若小于这个数字,则不再继续向下拆分

以下是利用随机森林实现波士顿房价预测的代码:

# 使用随机森林预测波士顿房价
import sklearn.datasets as sd
import sklearn.utils as su
import sklearn.tree as st
import sklearn.ensemble as se
import sklearn.metrics as smboston = sd.load_boston()  # 加载boston地区房价数据
print(boston.feature_names)
print(boston.data.shape)
print(boston.target.shape)random_seed = 7  # 随机种子,计算随机值,相同的随机种子得到的随机值一样
x, y = su.shuffle(boston.data, boston.target, random_state=random_seed)
# 计算训练数据的数量
train_size = int(len(x) * 0.8)  # 以boston.data中80%的数据作为训练数据
# 构建训练数据、测试数据
train_x = x[:train_size]  # 训练输入, x前面80%的数据
test_x = x[train_size:]  # 测试输入, x后面20%的数据
train_y = y[:train_size]  # 训练输出
test_y = y[train_size:]  # 测试输出# 创建随机森林回归器,并进行训练
model = se.RandomForestRegressor(max_depth=10,  # 最大深度n_estimators=1000,  # 树数量min_samples_split=2)  # 最小样本数量,小于该数就不再划分子节点
model.fit(train_x, train_y)  # 训练# 基于天统计数据的特征重要性
fi_dy = model.feature_importances_
# print(fi_dy)
pre_test_y = model.predict(test_x)
print(sm.r2_score(test_y, pre_test_y))  # 打印r2得分

打印输出:

['CRIM' 'ZN' 'INDUS' 'CHAS' 'NOX' 'RM' 'AGE' 'DIS' 'RAD' 'TAX' 'PTRATIO''B' 'LSTAT']
(506, 13)
(506,)
0.9271955403309159

3. 总结

1)什么是决策树:利用样本特征进行决策归类,将具有相同属性的样本划入一个子节点

2)决策树的用途:用作分类器、回归器

3)如何构建决策树:根据信息增益、增益率、基尼系数构建

4)什么情况下使用决策树:实用性较广,可用于一般回归、分类问题

5)决策树优化:集成学习、随机森林

这篇关于Python 全栈体系【四阶】(十)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/560466

相关文章

Django开发时如何避免频繁发送短信验证码(python图文代码)

《Django开发时如何避免频繁发送短信验证码(python图文代码)》Django开发时,为防止频繁发送验证码,后端需用Redis限制请求频率,结合管道技术提升效率,通过生产者消费者模式解耦业务逻辑... 目录避免频繁发送 验证码1. www.chinasem.cn避免频繁发送 验证码逻辑分析2. 避免频繁

精选20个好玩又实用的的Python实战项目(有图文代码)

《精选20个好玩又实用的的Python实战项目(有图文代码)》文章介绍了20个实用Python项目,涵盖游戏开发、工具应用、图像处理、机器学习等,使用Tkinter、PIL、OpenCV、Kivy等库... 目录① 猜字游戏② 闹钟③ 骰子模拟器④ 二维码⑤ 语言检测⑥ 加密和解密⑦ URL缩短⑧ 音乐播放

python panda库从基础到高级操作分析

《pythonpanda库从基础到高级操作分析》本文介绍了Pandas库的核心功能,包括处理结构化数据的Series和DataFrame数据结构,数据读取、清洗、分组聚合、合并、时间序列分析及大数据... 目录1. Pandas 概述2. 基本操作:数据读取与查看3. 索引操作:精准定位数据4. Group

Python pandas库自学超详细教程

《Pythonpandas库自学超详细教程》文章介绍了Pandas库的基本功能、安装方法及核心操作,涵盖数据导入(CSV/Excel等)、数据结构(Series、DataFrame)、数据清洗、转换... 目录一、什么是Pandas库(1)、Pandas 应用(2)、Pandas 功能(3)、数据结构二、安

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

Python安装Pandas库的两种方法

《Python安装Pandas库的两种方法》本文介绍了三种安装PythonPandas库的方法,通过cmd命令行安装并解决版本冲突,手动下载whl文件安装,更换国内镜像源加速下载,最后建议用pipli... 目录方法一:cmd命令行执行pip install pandas方法二:找到pandas下载库,然后

Python实现网格交易策略的过程

《Python实现网格交易策略的过程》本文讲解Python网格交易策略,利用ccxt获取加密货币数据及backtrader回测,通过设定网格节点,低买高卖获利,适合震荡行情,下面跟我一起看看我们的第一... 网格交易是一种经典的量化交易策略,其核心思想是在价格上下预设多个“网格”,当价格触发特定网格时执行买

Python标准库之数据压缩和存档的应用详解

《Python标准库之数据压缩和存档的应用详解》在数据处理与存储领域,压缩和存档是提升效率的关键技术,Python标准库提供了一套完整的工具链,下面小编就来和大家简单介绍一下吧... 目录一、核心模块架构与设计哲学二、关键模块深度解析1.tarfile:专业级归档工具2.zipfile:跨平台归档首选3.

使用Python构建智能BAT文件生成器的完美解决方案

《使用Python构建智能BAT文件生成器的完美解决方案》这篇文章主要为大家详细介绍了如何使用wxPython构建一个智能的BAT文件生成器,它不仅能够为Python脚本生成启动脚本,还提供了完整的文... 目录引言运行效果图项目背景与需求分析核心需求技术选型核心功能实现1. 数据库设计2. 界面布局设计3

Python进行JSON和Excel文件转换处理指南

《Python进行JSON和Excel文件转换处理指南》在数据交换与系统集成中,JSON与Excel是两种极为常见的数据格式,本文将介绍如何使用Python实现将JSON转换为格式化的Excel文件,... 目录将 jsON 导入为格式化 Excel将 Excel 导出为结构化 JSON处理嵌套 JSON: