决策树的概念和案例

决策树简介

生活中的决策树

女孩相亲的决策树(源于网络,切勿当真)

        让我们康康这个表格里的“?”该如何填充:

        预测值1:根据女孩相亲决策树,年龄和长相都符合期望,于是收入甚至不用考虑,预测值1为:见。

        预测值2:根据女孩相亲决策树,年龄符合,但长相不符合期望,于是收入不用考虑,预测值2为:不见。

        预测值3:根据女孩相亲决策树,年龄不符合,于是长相和输入不用考虑,预测值3为:不见。

思考:(笔者会在文末给出答案,友友们也可以在评论区写写自己的理解❁´◡`❁)

        1.女孩相亲过程中,更加看重哪些因素呢?

        2.机器学习算法中,选择数据集的哪些特征进行分裂,效果会更好呢?

决策树概念

决策树是什么?

        决策树是一种树形结构,树中每个内部节点表示一个特征上的判断,每个分支代表一个判断结果的输出,每个叶子节点代表一种分类结果。

决策树的建立过程

1.特征选择:选取有较强分类能力的特征。

2.决策树生成:根据选择的特征生成决策树。

3.决策树也易过拟合,采用剪枝的方法缓解过拟合。

ID3决策树

信息熵

Entropy :信息论中代表随机变量不确定度的度量。熵越大,数据的不确定性度越高,信息就越多;熵越小,数据的不确定性越低。

举个例子:

        数据 αABCDEFGH

        数据 βAAAABBCD

        明显:数据α 包含了 8 种信息数据 β 包含了 4 种信息,则特征 α 的信息熵大于特征 β 的信息熵。

信息熵的计算较为复杂,下面给出它的计算方法:

信息增益

概念

特征a对训练数据集D的信息增益g(Da)定义为集合D的熵H(D)与特征a给定条件下D的熵H(D|a)之差。

数学公式

g(D, a) = H(D)-H(D|A)

信息增益 = 熵 - 条件熵

条件熵

计算方法

ID3决策树的构建流程

        1.计算每个特征的信息增益

        2.使用信息增益最大的特征将数据集  拆分为子集

        3.使用该特征(信息增益最大的特征)作为决策树的一个节点

        4.使用剩余特征对子集重复上述(1,2,3)过程

信息增益案例

结论活跃度的信息增益比性别的信息增益大,对用户流失的影响比性别大。

C4.5决策树

ID3决策树的不足

偏向于选择种类多的特征作为分裂依据

举个例子:

信息增益率

概念:

信息增益率 = 信息增益 /特征熵

计算方法:

信息增益率的本质:

        特征的信息增益 ➗ 特征的内在信息

        相当于对信息增益进行修正增加一个惩罚系数

        特征取值个数较多时,惩罚系数较小;特征取值个数较少时,惩罚系数较大。

        惩罚系数:数据集D以特征a作为随机变量的熵的倒数

小案例

CART决策树

CART决策树概念

CART决策树Classification and Regression Tree

Cart模型是一种决策树模型,它即可以用于分类,也可以用于回归。

Cart回归树使用平方误差最小化策略,

Cart分类生成树采用的基尼指数最小化策略。

基尼指数

基尼值GiniD):从数据集D中随机抽取两个样本,其类别标记不一致的概率。故,GiniD值越小,数据集D的纯度越高。

基尼指数Gini_indexD):选择使划分后基尼系数最小的属性作为最优化分属性。

注意:

1.信息增益(ID3)、信息增益率值越大(C4.5),则说明优先选择该特征。

2.基尼指数值越小(cart),则说明优先选择该特征。

小案例

三种决策树的区别

案例

泰坦尼克号乘客生存预测案例

数据下载: https://pan.baidu.com/s/1PasiSSK2xpSYDSmen6T4Ug?pwd=wrgu 提取码: wrgu 

案例背景

        泰坦尼克号沉没是历史上最著名的沉船事件。1912年4月15日,在她的处女航中,泰坦尼克号在与冰山相撞后沉没,在2224名乘客和船员中造成1502人死亡。这场耸人听闻的悲剧震惊了国际社会,并为船舶制定了更好的安全规定。 造成海难失事的原因之一是乘客和船员没有足够的救生艇。尽管幸存下来有一些运气因素,但有些人比其他人更容易生存,例如妇女,儿童和社会地位较高的人群。 在这个案例中,我们要求您完成对哪些人可能存活的分析。数据集中的特征包括票的类别,是否存活,乘坐班次,姓名,年龄,上船港口,房间,性别等。

决策树api介绍
class sklearn.tree.DecisionTreeClassifier(criterion=’gini’, max_depth=None,random_state=None)
  • criterion

    • 特征选择标准

    • "gini"或者"entropy",前者代表基尼系数,后者代表信息增益。一默认"gini",即CART算法。

  • min_samples_split

    • 内部节点再划分所需最小样本数

    • 这个值限制了子树继续划分的条件,如果某节点的样本数少于min_samples_split,则不会继续再尝试选择最优特征来进行划分。 默认是2.如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。我之前的一个项目例子,有大概10万样本,建立决策树时,我选择了min_samples_split=10。可以作为参考。

  • min_samples_leaf

    • 叶子节点最少样本数

    • 这个值限制了叶子节点最少的样本数,如果某叶子节点数目小于样本数,则会和兄弟节点一起被剪枝。 默认是1,可以输入最少的样本数的整数,或者最少样本数占样本总数的百分比。如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。之前的10万样本项目使用min_samples_leaf的值为5,仅供参考。

  • max_depth

    • 决策树最大深度

    • 决策树的最大深度,默认可以不输入,如果不输入的话,决策树在建立子树的时候不会限制子树的深度。一般来说,数据少或者特征少的时候可以不管这个值。如果模型样本量多,特征也多的情况下,推荐限制这个最大深度,具体的取值取决于数据的分布。常用的可以取值10-100之间

  • random_state

    • 随机数种子

案例实现

        相比其他学习模型,决策树在模型描述上有巨大的优势,决策树的逻辑推断非常直观,具有清晰的可解释性,也有很方便的模型的可视化。在决策树的使用中,无需考虑对数据量化和标准化,就能达到比较好的识别率。

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import classification_report, precision_score, recall_score, f1_score, roc_auc_score
import matplotlib.pyplot as plt
from sklearn.tree import plot_tree

"""
演示决策树分层
"""

# 1、读取数据
train_df = pd.read_csv("data/train.csv")
train_df.info()

# 2、数据预处理
# 2-1 获取特征列 和标签列   船舱等级 、 性别 、年龄
x = train_df[['Pclass', 'Sex', 'Age', 'Embarked', 'Ticket']]
y = train_df['Survived']

# 2-2 用age 处理  age列求平均值
x['Age'] = x['Age'].fillna(x['Age'].mean())

# 2-3 查看数据
# x.info()
print(x.head(5))

# 分析 age需要处理 采用热编码
x = pd.get_dummies(x)
print(x.head(5))
x.drop('Sex_male', axis=1, inplace=True)
print(x.head(5))

# 拆分训练集和测试集
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=24)
print(x_train.head(5))

# 是否需要特征工程
f = StandardScaler()
x_train = f.fit_transform(x_train)
x_test = f.transform(x_test)

# 4训练模型
model = DecisionTreeClassifier(criterion="gini")
model.fit(x_train, y_train)

y_pre = model.predict(x_test)
print(f"打印预测结果{y_pre}")  # 0已故   1 活着

# 模型评估
print(f"准确率:{model.score(x_test, y_test)}")
print(f"精确率:{precision_score(y_test, y_pre)}")
print(f"召回率:{recall_score(y_test, y_pre)}")
print(f"F1:{f1_score(y_test, y_pre)}")
print(f"ROC_AUC:{roc_auc_score(y_test, y_pre)}")
print(f"分类报告{classification_report(y_test, y_pre, target_names=['Died', 'Survivor'])}")

# TODO 绘CART决策树图
# TODO 1设置画布大小
plt.figure(figsize=(50, 30))

# TODO 2.绘制决策树
#   decision_tree:决策树模型   filled 填充颜色
# 注意: 可以提前设置层数 max_depth=15,达到预剪枝效果!!!
plot_tree(model, filled=True)

# TODO 3.保存图片
plt.savefig('data/cart.png')
# TODO 4.展示图片
plt.show()
代码运行结果

CART回归树

CART 回归树和 CART 分类树的不同之处

        1. CART 分类树预测输出的是一个离散值,CART 回归树预测输出的是一个连续值。

        2. CART 分类树使用基尼指数作为划分、构建树的依据,CART 回归树使用平方损失。

        3. 分类树使用叶子节点里出现更多次数的类别作为预测类别,回归树则采用叶子节点里均值作为预测输出

CART回归树的平方损失

举个例子

线性回归和回归决策树的对比案例

案例分析

从预测效果来看:

1、线性回归是一条直线

2、决策树是曲线

3、树的拟合能力是很强的,易过拟合

案例实现

# 导包.
import numpy as np
import pandas as pd
from sklearn.tree import DecisionTreeRegressor  # 回归决策树
from sklearn.linear_model import LinearRegression  # 线性回归
import matplotlib.pyplot as plt  # 绘图
# 解决中文乱码问题
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 1. 获取数据.
x = np.array(list(range(1, 11))).reshape(-1, 1)
y = np.array([5.56, 5.70, 5.91, 6.40, 6.80, 7.05, 8.90, 8.70, 9.00, 9.05])
# print(x)
# print(y)

# 2. 创建线性回归 和 决策树回归模型.
estimator1 = LinearRegression()  # 线性回归
estimator2 = DecisionTreeRegressor(max_depth=1)  # 回归决策树, 层数=1
estimator3 = DecisionTreeRegressor(max_depth=3)  # 回归决策树, 层数=3

# 3. 训练模型.
estimator1.fit(x, y)
estimator2.fit(x, y)
estimator3.fit(x, y)

# 4. 准备测试数据, 用于测试.
# 起始, 结束, 步长.
x_test = np.arange(0.0, 10.0, 0.1).reshape(-1, 1)
# print(x_test)

# 5. 模型预测.
y_predict1 = estimator1.predict(x_test)
y_predict2 = estimator2.predict(x_test)
y_predict3 = estimator3.predict(x_test)

# 6. 绘图
plt.figure(figsize=(10, 5))

# 散点图(原始的坐标)
plt.scatter(x, y, color='gray', label='data')
# 线性回归的预测结果
plt.plot(x_test, y_predict1, color='r', label='liner regression')
# 回归决策树, 层数=1
plt.plot(x_test, y_predict2, color='b', label='max depth=1')
# 回归决策树, 层数=3
plt.plot(x_test, y_predict3, color='g', label='max depth=3')
# 显示图例.
plt.legend()
# 设置x轴标签.
plt.xlabel('data')
# 设置y轴标签.
plt.ylabel('target')
# 设置标题
plt.title('回归决策树和线性回归可视化对比')
# 保存图片
plt.savefig('data/line_rtree.png')
# 显示图片
plt.show()
运行结果

决策树 剪枝

决策树正则化

        我们在之前的知识里已经知道,模型有时会出现过拟合的情况,这时我们需要采取措施来缓解,以让模型达到相对较好的拟合状态,在线性回归模型里,我重点介绍了两种缓解过拟合的方法,即L1正则化和L2正则化缓解过拟合,感兴趣的友友可以点击文末的链接,温习一下正则化的概念和案例。

        对于决策树模型,也会存在过拟合问题,这时我们会用到决策树正则化,即剪枝。

挑选西瓜案例

剪枝思想

剪枝原理

 预剪枝和后剪枝补充

预剪枝(Pre-pruning)​

  • 定义​:在决策树构建过程中,通过某些规则提前停止树的生长。
  • 剪枝时机​:在生成节点时即时判断是否继续分裂。
  • 常见停止条件​:
    • 当前节点的样本数低于阈值。
    • 分裂后的性能提升(如信息增益、基尼系数)小于阈值。
    • 树的深度达到预设最大值。
    • 节点中样本的类别纯度(如95%属于同一类)。
  • 优点​:
    • 训练速度快(避免生成复杂树后再剪枝)。
    • 降低过拟合风险,模型更简单。
  • 缺点​:
    • 可能欠拟合​(过早停止可能导致关键分裂被忽略)。
    • 依赖阈值设定,需调参(如最大深度、最小样本数)。

2. 后剪枝(Post-pruning)​

  • 定义​:先让决策树完全生长,再根据一定规则从底部向上剪去子树。
  • 剪枝时机​:树构建完成后,对非叶节点进行考察。
  • 常见方法​:
    • 代价复杂度剪枝(CCP)​​:如CART树的α参数,平衡子树复杂度与误差。
    • 错误率降低剪枝(REP)​​:用验证集测试剪枝前后错误率。
    • 悲观剪枝(PEP)​​:基于统计检验(如卡方检验)判断节点是否冗余。
  • 优点​:
    • 保留更多有用分裂,泛化能力通常优于预剪枝。
    • 对噪声数据更鲁棒。
  • 缺点​:
    • 计算成本高(需先生成完整树)。
    • 可能需要额外验证集(如REP)。

预剪枝-西瓜挑选案例

基于预剪枝策略从上表数据所生成的决策树如上图所示,其验证集精度为 71.4%.

后剪枝-西瓜挑选案例

先利用训练集完整的生成一颗树,有6个内部节点。分别考察这些节点作为叶子节点模型的准确率,若准确率上升,则剪掉,否则保留。

 决策树两种正则化方法对比:


尾声

        行文至此,虽然身体和心理上都很累,但是想到马上要发布此篇博文,就会觉得一切都值得<( ̄︶ ̄)↗[GO!]

        接下来,我来回答一下上文提到的两个问题:

        1、女孩相亲过程中,更看重哪些特征呢?

        年龄 > 长相 > 收入 > 是否公务员

        2、机器学习算法中,选择数据集中的哪些特征进行分裂,会更好呢?

        本文提到的ID3决策树、C4.5决策树、CART决策树的构建过程的开始就是选择特征进行分裂,显然信息增益、信息增益率、基尼指数都是用来评估特征的,得分高者优先被选择去用来分裂,如信息增益率高的特征会优先被选择。

        最后,将系列的前几篇文章的链接附在下面,供友友们参考:

1.K-近邻算法

2.线性回归的概念和案例

3.逻辑回归的概念和案例

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值