从决策树到随机森林:Python机器学习里的“树形家族“深度实战与原理拆解

引言

在机器学习那个算法种类非常多的体系里面, 有一对像树一样的兄弟模型一直都在核心位置占据着非常重要的地位。这个决策树呢, 它就像一个逻辑思路特别清楚的老教授一样, 它会用那种可以看得见的树状结构, 去把那些很复杂的决策过程拆解成是或不是的这种简简单单的判断环节。

然后它的升级版随机森林, 它更像是一个精锐的部队集合体, 它会通过很多棵决策树一起来进行投票表决这种方式, 让结果在准确度和防止过拟合这样的能力方面,实现了一个非常重大的、本质上的提升和改进。

无论是用在医疗的诊断工作里面去对疾病进行预测, 还是在金融的风控业务里面去识别会不会违约, 这一对组合都用他们非常强大的适应能力证实了他们自己在算法领域里像常青树一样长存不枯的地位。今天就从基本的原理一直到实际的操作案例这个范围, 把这一对像树这种形状的搭档给完全拆解得清清楚楚。

一、决策树被大家当成是一棵"逻辑树", 它的作用就像是剥洋葱那样, 一层一层地把问题拆解清楚。在1.1原理部分中, 我们可以从如何分拣西瓜这样的具体例子出发, 去弄明白生长出这种决策树的内在逻辑是怎么回事。

咱们来想一想生活中的这么一个情景, 就是你得去判断一个西瓜到底是不是已经熟了, 你或许会先去看一看那个纹路清不清楚,如果发现纹路确实非常清晰, 那么接下来你再动手敲一敲听一听那个声音浑不浑厚, 要是如果纹路并不清晰的话, 那么你很有可能直接就判断为这个西瓜还没有成熟, 这种从特征到判断再到分支的这样一个过程呢, 其实就是决策树在模仿人类在做决定的时候的那个逻辑。

从数学的角度去进行观察, 决策树是一种基于特征划分的监督学习模型, 这一模型的核心要点在于通过选择最优特征来对数据集进行分割处理, 这个过程需要一直持续下去, 直到每一个子节点都变得足够纯, 所谓的足够纯就是指每个子节点都属于单一的同一类别, 对于整个分割的过程来说有一个比较形象的比喻, 它完全就像是人们在切蛋糕一样, 每次选择的那一刀都是最能将不同的口味给分开的最优的那一刀。

关键概念:如何选择"最优分割特征"?

这个决策树的长个儿过程, 它是必须要靠那两个非常核心的测量指标来支持的, 这两个指标的主要作用嘛, 就是用来看看分割出来之后的那些子集合里面是不是更加的纯粹。

拿个具体的例子来说, 假定有一组关于西瓜的数据信息, 这其中的特征包括瓜皮纹路是清晰还是模糊、以及敲击的时候声音是浑厚还是清脆, 而对应的标签则是这个瓜到底成熟还是没有成熟, 接下来如果我们选择使用"纹路清晰"这一项来进行数据分割操作的话, 那么可以观察到的情况是位于左边的那个子节点里面有百分九十的西瓜都是成熟的品种, 同时位于右边的另一个子节点里面却有百分之八十的西瓜都属于未成熟的种类, 基于这样的分布状态计算出来的信息增益数值, 显然是要比如果使用"敲击声"来进行分割操作时所获得的增益值要更高的, 所以相关的算法机制最终就会倾向于把"纹路清晰"选作第一个用来进行分割的特征依据。

1.第二个实操环节, 我们要利用这个内容, 亲手种下一棵属于咱们自己的决策树。

在中, - learn的er(分类树)和r(回归树)已经帮我们封装好了决策树的核心逻辑。我们以经典的鸢尾花分类任务为例, 一步步实现:

先做第一步, 这一步的任务是把数据准备好, 具体做法就是把鸢尾花的数据集加载进来。

大家现在用机器学习, 通常都会拿那个鸢尾花数据集来当个入门的例子, 这个事就像是编程里的"Hello World"一样普通。这个数据里头有三大类鸢尾花, 分别叫作山鸢尾、杂色鸢尾, 还有维吉尼亚鸢尾。这些数据里面包括了四个数值型的特征, 分别是花萼的长度、花萼的宽度, 以及花瓣的长度、花瓣的宽度。

python 复制代码
# 导入必要库

from sklearn.datasets import load_iris # 加载内置数据集

from sklearn.model_selection import train_test_split # 划分训练集/测试集

from sklearn.tree import DecisionTreeClassifier, plot_tree # 决策树分类器及可视化工具

from sklearn.metrics import accuracy_score, classification_report # 模型评估指标

import matplotlib.pyplot as plt # 绘图库

# 加载数据

iris = load_iris()

X = iris.data # 特征矩阵(4个特征)

y = iris.target # 标签(0/1/2三类)

feature_names = iris.feature_names # 特征名称列表

class_names = iris.target_names # 类别名称列表

print(f"特征名称:{``

-- -->feature_names}")

print(f"类别名称:{``

-- -->class_names}")

进行第二个步骤, 也就是对训练集和测试集加以划分。

为了验证模型泛化能力, 我们按七比三的比例划分训练集和测试集, 并且设置随机种子来保证结果可复现。

python 复制代码
X_train, X_test, y_train, y_test = train_test_split(

X, y,

test_size = 0.3, # 30%作为测试集

random_state = 42 # 固定随机种子,保证结果可复现

)

进入第三步的时候, 我们要做的具体事情就是去训练那个决策树模型。

er具有许多重要的参数, 比如:

我们在这里先把那些默认的参数拿来用做训练, 后面的时候再去细说关于如何调整参数那档子事。

python 复制代码
# 初始化决策树分类器(使用默认参数)

dt_clf = DecisionTreeClassifier(random_state = 42) # 固定随机种子保证结果一致

# 训练模型(用训练集拟合)

dt_clf.fit(X_train, y_train)

我们执行步骤四, 也就是对决策树进行可视化处理, 这样一来, 我们就能够非常直观地看清这棵树究竟长成了一个什么样的形态。

使用函数进行查看, 我们能够直接观察到决策树的具体结构, 这项特点可以说是决策树最为吸引人们的地方之一, 并且它还具备非常强的可解释能力。

python 复制代码
# 设置画布大小

plt.figure(figsize=(15, 10))

# 绘制决策树

plot_tree(

dt_clf,

feature_names = feature_names, # 显示特征名称

class_names = class_names, # 显示类别名称

filled = True, # 用颜色深度表示节点纯度(颜色越深,纯度越高)

rounded = True # 节点边框圆角

)

plt.title("训练后的鸢尾花决策树结构", fontsize = 14)

plt.show()

把步骤5进行切分, 然后对模型预测与评估这件事进行描述。

我们会拿测试集去对模型的表现情况做一下验证这个工作, 并且把准确率以及召回率这些个相关的考核指标都给计算出来。

python 复制代码
# 预测测试集

y_pred = dt_clf.predict(X_test)

# 计算准确率

accuracy = accuracy_score(y_test, y_pred)

print(f"测试集准确率:{``

-- -->accuracy:.4f}") # 输出4位小数

# 生成分类报告(包含精确率、召回率、F1分数)

print("\n分类报告:")

print(classification_report(y_test, y_pred, target_names = class_names))

1.第三部分, 关于决策树优缺点清单与实际应用情况的优势包括, 劣势也有, 其典型的应用场合也在其中, 接下来是第二部分随机森林方法, 这种方法被形容为多个决策树进行投票的智能团队, 二点一分原理部分探讨了多种简单判断组合为何能达成高水平效果的说法的依据是什么。

决策树出现的主要麻烦情况, 就是太容易把训练数据里的细节和噪声都记住, 从而导致模型在面对新数据时表现下降, 这种行为模式, 其实类似于某个领域专家在判断事情的时候, 可能带着自己的固定偏见或者主观立场。

随机森林这种方法的真正用意在于, 运用集成学习当中一种叫做模型组合的通用策略, 具体的执行方式是先用随机抽样的方法弄出很多个不同的用来训练的小规模数据集, 然后针对每一个这样的小数据集去单独训练一棵完全独立的决策树, 等到所有的树都训练完成之后, 再将它们各自给出的预测结果汇聚起来, 在需要进行分类选择的情况下靠多数投票来决定最终是谁, 而在需要进行数值回归计算的时候通过求平均值来得出最后的结论。

随机森林这个概念里头, 有一个特别重要的点, 那就是它的"双重随机"。

这种所谓的"双重随机"操作, 使得每一棵单独的树都展现出非常有特点的个性表现, 但是在一定程度上又不会让它们偏离正常的范围太远, 最终依靠集体的智慧力量, 达到降低整体方差的效果, 也就是能够有效抵抗过拟合问题的出现, 同时在保持准确度比较高这一条件下, 让偏差维持在比较低的水平。

2.进行第二个环节, 也就是实战部分的训练过程, 使用的是名为.learn的标记来指导随机森林模型完成训练操作。

  • 这个词里面的"er", 它指的是分类任务, 还有那个"r", 它指的是回归任务, 这两个情况下面, 它们都对随机森林里面那些最核心的运行逻辑做了打包处理。

咱们接下来还是采用那个众所周知的鸢尾花数据集来进行操作, 然后我们把决策树这种方法跟随机森林这种方法的实际效果放在一起进行对比看看。

第一步嘛, 就是把那个随机森林分类器给它初始化一下。

随机森林所涉及的重要参数, 数量是比决策树要更多一点的, 具体的例子可以举出来像是。

python 复制代码
from sklearn.ensemble import RandomForestClassifier

# 初始化随机森林分类器(设置关键参数)

rf_clf = RandomForestClassifier(

n_estimators = 100, # 100棵决策树

max_features ='sqrt', # 每个节点考虑√M个特征(M = 4时为2)

oob_score = True, # 启用袋外数据评估

random_state = 42, # 固定随机种子

n_jobs = -1 # 使用所有CPU核心并行训练

)

# 训练模型

rf_clf.fit(X_train, y_train)

我们进行第2步, 这一步的作用是对随机森林的运行表现情况做一下评估。

除了去评估那个测试集的情况之外, 还有一种办法, 是可以利用一个叫袋外分数的东西, 来初步地判断得出这个模型的效果到底怎么样, 在这种情况之下, 是不需要再去划分出一个验证集的。

python 复制代码
# 预测测试集

y_pred_rf = rf_clf.predict(X_test)

# 计算测试集准确率

accuracy_rf = accuracy_score(y_test, y_pred_rf)

print(f"随机森林测试集准确率:{``

-- -->accuracy_rf:.4f}")

# 输出袋外分数(OOB Score)

print(f"袋外数据准确率:{``

-- -->rf_clf.oob_score_:.4f}")

# 生成分类报告

print("\n随机森林分类报告:")

print(classification_report(y_test, y_pred_rf, target_names = class_names))

进行步骤三的时候, 我们要去挖掘随机森林里面那些隐藏着的消息, 这个工作叫做看特征的重要程度。

随机森林还有一个好处, 就是它可以把那些特征的重要程度给算出来, 也就是所谓的输出特征重要性, 然后这样干的话, 大家就比较容易明白到底是有哪些变量, 才对最后预测出来的那个结果影响最大。

python 复制代码
# 获取特征重要性分数

importances = rf_clf.feature_importances_

# 生成特征 - 重要性对的列表

feature_importance = list(zip(feature_names, importances))

# 按重要性降序排序

feature_importance.sort(key = lambda x: x[1], reverse = True)

# 打印结果

print("特征重要性排序:")

for feature, importance in feature_importance:

print(f"{``

-- -->feature}: {``

-- -->importance:.4f}")

# 可视化特征重要性

plt.figure(figsize=(10, 6))

plt.barh(

[f[0] for f in feature_importance], # 特征名称

[f[1] for f in feature_importance], # 重要性分数

color ='skyblue'

)

plt.xlabel("重要性分数", fontsize = 12)

plt.title("随机森林特征重要性", fontsize = 14)

plt.gca().invert_yaxis() # 让最重要的特征在顶部

plt.show()

2.第三部分是关于随机森林的优缺点清单以及典型应用场景, 其中包含了优点、缺点和典型应用场景的具体内容。紧接着是第三部分从理论走向实战环节, 重点讲解决策树与随机森林之间的深度对比内容以及调优技巧。在3.1小节中展示了核心差异对比表, 该表格主要涉及两个维度分别对应决策树和随机森林的情况。

模型结构

单棵树

多棵树的集成

过拟合风险

该树的高度偏高, 需要进行剪枝处理。

低, 这是通过把方差降低来达到的。

计算速度

速度很快, 这是因为进行了单树训练。

这个速度会比较慢(这是因为存在多个树同时做并行训练的情况)。

可解释性

在树结构可视化当中, 高度这一概念被提及了。

整体决策逻辑比较复杂, 所以低。

特征重要性

需要额外来算一算, 比如说基于信息增益这种方法。

它是通过计算特征对不纯度的贡献, 然后直接输出的。

对噪声敏感

这种情况的评分是很高的, 因为单棵树容易受到那些不太正常的样本的影响。

低(多树结果中和噪声)

3.关于决策树调优这个事儿, 说白了其实就是在玩一种剪枝方面的艺术。

决策树所面临的过拟合这一问题, 是完全可以通过实施剪枝这个操作来获得解决的, 而在相关的领域里, 大家普遍认可的解决方案主要有两种类型:

3.3 随机森林的调优:平衡树的数量与质量

大家在进行随机森林算法的调优工作时, 其主要的工作内容其实是聚焦于两个参数的调整和优化。

总结

决策树和随机森林这两样东西, 都是机器学习里头很经典的算法, 不过, 它们各自都有好的一面, 也有不好的一面。再说那个决策树, 它的一个长处就是特别好解释, 而且训练起来速度也快, 所以说, 如果遇到那些对模型的解释要求比较高的时候, 或者说是数据量还比较小的时候, 用这个决策树就比较合适了。

再说说那个随机森林, 它的优点在于对抗那些过拟合的情况能力很强, 而且在特征选择这个方面也有它的优势所在, 因此, 在面对那些比较复杂的数据, 还有那种数据规模很大的数据集的时候, 随机森林的表现往往是相当不错的。

在具体的实际工作里面, 人们需要根据每一个实际碰到的问题的情况, 还有手头的数据所展现出来的那些特有的样子, 去做出比较灵活的选择, 并且对这两种算法进行必要的调整和优化, 这样做的最终目的是为了让属于"树形家族"的这些算法模型, 能够在各种各样不一样的业务运作场景当中, 最大限度地发挥出它们自身应该具有的那一份价值。

相关推荐
硅谷秋水2 小时前
PhysicalWords:一种用于构建机器人操作中潜推理过程的词汇体系
人工智能·机器学习·计算机视觉·语言模型·机器人
2601_967979124 小时前
这7个小众Python库,才是机器学习工程化的降效神器
机器学习·推荐系统·工程化·时间序列·python库
在所不辞兄5 小时前
为什么在标签噪声场景下,识别双重下降拐点有助于防止模型记忆异常数据?
人工智能·深度学习·神经网络·机器学习
云上工程笔记7 小时前
SRT字幕一键转手绘动画:srt-whiteboard-animation的复刻实录
大数据·开发语言·javascript·人工智能·机器学习
2601_9679801117 小时前
Hugging Face:成为机器学习界的“Github”
机器学习·hugging face·开源平台·开放科学·transformer模型
小白菜0017 小时前
AI的理解
人工智能·机器学习
DFT计算杂谈18 小时前
可DIY布里渊区图像绘制编辑器
人工智能·机器学习·语言模型·矩阵·编辑器
aifannihao1 天前
AI 学习第 8 课:1200 列纯噪声 CV 出 0.47,泄漏在筛特征那步
人工智能·机器学习·scikit-learn·学习路线·数据泄漏