news 2026/7/2 23:40:13

19.AI大模型开发:机器学习----决策树与CART算法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
19.AI大模型开发:机器学习----决策树与CART算法

一句话讲完决策树:“像做选择题一样,一层一层往下问,直到得出答案。”

写在前面

今天讲一个特别直观、特别好懂的算法——决策树(Decision Tree)

你平时生活里其实天天都在用决策树,只是你自己没意识到。比如:

  • 你去相亲,心里会过一遍:年龄合不合适?→ 长得帅不帅?→ 工作好不好?→ 见还是不见?

  • 你买西瓜,会敲一敲:声音闷不闷?→ 瓜蒂新不新鲜?→ 皮薄不薄?→ 买还是不买?

决策树就是把这种“一问一答”的决策过程,用计算机自动学出来。


第一部分:决策树是什么?

1.1 一个真实的小故事:银行柜员小张的烦恼

小张在银行工作,每天要审批信用卡申请。他的判断标准是:

申请人月收入是否大于8000? ├── 是 → 是否有稳定工作(在职满1年)? │ ├── 是 → 信用分是否大于650? │ │ ├── 是 → ✅ 批卡(额度较高) │ │ └── 否 → ✅ 批卡(额度较低) │ └── 否 → ❌ 拒绝 └── 否 → ❌ 拒绝

小张的经验,就是一棵决策树

1.2 决策树的三个核心概念

概念通俗解释对应上面的例子
内部节点每个“判断条件”“月收入>8000?”“在职满1年?”
分支判断的结果“是 / 否”
叶子节点最终结论(不再继续分了)“✅批卡”或“❌拒绝”

1.3 决策树能解决两类问题

和KNN一样,决策树也是分类回归通吃

任务类型预测内容举例
分类树预测“是哪一类”信用卡批不批?(批/拒)
回归树预测“是多少”批多少额度?(连续数值:5000~10万)

第二部分:决策树的构建流程(4步走)

一颗决策树的“生长”过程分为4步:

步骤做什么白话解释
1特征选择从所有特征里挑一个“最有用”的,放在树根
2分裂根据这个特征把数据分成两组(或多组)
3递归对分出来的每一组,重复步骤1-2
4停止直到所有叶子节点都“纯”了,或者达到设定的停止条件

最关键的是第1步——怎么判断哪个特征“最有用”?这就是CART算法的核心。


第三部分:CART决策树(最主流的实现)

3.1 什么是CART?

CART=Classification And Regression Tree(分类与回归树)。

它是目前最主流的决策树实现,也是随机森林、XGBoost、LightGBM这些高级算法的“地基”。

3.2 CART的三个核心规则

规则说明举例
规则1:强制二分每次分裂只能分成两组问“收入>8000?”→ 是/否,不能分成“高/中/低”三组
规则2:贪心选择每一步都选当前“最有用”的特征比较所有特征,选那个让数据分得最“干净”的
规则3:递归进行一层一层往下分,直到满足停止条件分完一组再分下一组,像剥洋葱

3.3 怎么判断特征“最有用”?(基尼系数)

CART分类树用的是基尼系数(Gini Index)来度量“纯度”。

公式

  • pk​ = 某组数据中第 k 类样本的比例

  • Gini越小 → 数据越“纯”(大家都是一个类)

  • Gini越大 → 数据越“混”(各类都有)

一个特征“有用”,就是用它划分后,两组的Gini系数之和最小(分得最干净)。

3.4 CART回归树(预测数值)

如果我们要预测“批多少额度”(连续数字),CART也能做。区别在于:

对比分类树回归树
目标预测类别预测数值
“纯度”衡量基尼系数(Gini)均方误差(MSE)
叶子节点输出投票选最多的类别该组所有样本的平均值

回归树分裂时,找的是让MSE下降最多的那个分裂点


第四部分:决策树超参数(防过拟合的武器)

4.1 决策树容易过拟合

决策树有个特点:如果不加限制,它可以一直往下分,直到每个叶子节点只剩一个样本。这样的模型在训练集上100%准确,但在新数据上表现极差——这就是过拟合

4.2 常用超参数(限制树的大小)

参数作用建议值
max_depth树的最大深度(层数)3~10,太深容易过拟合
min_samples_split内部节点再划分所需的最小样本数默认2,可设5~20
min_samples_leaf叶子节点最少样本数默认1,可设3~10
max_features每次分裂考虑的最大特征数默认全部,可设 sqrt(n)

4.3 剪枝(Pruning)——更高级的防过拟合

剪枝就是砍掉一些没用的树枝,让树变简单。

两种剪枝方式

方式时机做法优缺点
预剪枝树生长过程中每次分裂前评估:分了能提升效果吗?不能就停省时间,但可能“错过好分支”
后剪枝树完全长成后从下往上检查:这个分支有用吗?没用就砍掉效果好,但耗时更久

sklearn的DecisionTreeClassifier默认是预剪枝——通过max_depthmin_samples_split等参数限制。


第五部分:信用卡审批预测

5.1 生成数据

import numpy as np import pandas as pd from sklearn.model_selection import train_test_split from sklearn.tree import DecisionTreeClassifier from sklearn.metrics import accuracy_score, classification_report import matplotlib.pyplot as plt from sklearn.tree import plot_tree # 设置随机种子 np.random.seed(42) # 生成2000条信用卡申请数据 n = 2000 # 特征:月收入(万)(0.5~15)、在职月数(1~120)、信用分(300~850)、负债率(0~0.9) income = np.random.uniform(0.5, 15, n) work_months = np.random.randint(1, 121, n) credit_score = np.random.randint(300, 851, n) debt_ratio = np.random.uniform(0, 0.9, n) # 生成标签(批卡=1,拒卡=0) # 业务逻辑:收入高+信用分高+负债低 → 批卡 score = (income * 0.6 + credit_score * 0.01 - debt_ratio * 3 + work_months * 0.01) y = (score > 5).astype(int) # 综合得分>5批卡 # 拼成DataFrame data = pd.DataFrame({ '月收入(万)': income, '在职月数': work_months, '信用分': credit_score, '负债率': debt_ratio, '是否批卡': y }) print("数据前5行:") print(data.head()) print(f"\n总样本数:{len(data)},批卡比例:{y.sum()/n*100:.1f}%")

5.2 划分训练集和测试集(决策树不需要标准化)

# 特征和标签分开 X = data[['月收入(万)', '在职月数', '信用分', '负债率']] y = data['是否批卡'] # 训练集70%,测试集30% X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.3, random_state=42 ) print(f"训练集:{len(X_train)}条,测试集:{len(X_test)}条")

注意:和KNN不同,决策树不需要做标准化!因为决策树是“按阈值比较”,不是算距离,特征尺度不影响分裂结果。

5.3 训练决策树模型(分类)

# 创建决策树分类器(限制深度防止过拟合) model = DecisionTreeClassifier( max_depth=5, # 最大深度5层 min_samples_split=20, # 节点至少20个样本才继续分 min_samples_leaf=10, # 叶子节点至少10个样本 random_state=42 ) # 训练 model.fit(X_train, y_train) # 预测 y_pred = model.predict(X_test) # 准确率 acc = accuracy_score(y_test, y_pred) print(f"测试集准确率:{acc * 100:.2f}%") # 详细分类报告 print("\n分类报告:") print(classification_report(y_test, y_pred, target_names=['拒卡', '批卡']))

5.4 特征重要性分析(决策树的隐藏技能)

决策树能告诉我们:哪个特征对决策最重要?

# 获取特征重要性 importance = model.feature_importances_ feature_names = ['月收入(万)', '在职月数', '信用分', '负债率'] print("\n特征重要性(加起来=1):") for name, imp in zip(feature_names, importance): print(f" {name}:{imp:.3f}") # 可视化特征重要性 plt.figure(figsize=(8, 5)) plt.barh(feature_names, importance, color='steelblue') plt.xlabel('重要性') plt.title('信用卡审批决策树-特征重要性') plt.show()

输出示例

特征重要性(加起来=1): 月收入(万):0.452 在职月数:0.098 信用分:0.335 负债率:0.115

说明:月收入和信用分是最关键的两个因素。

5.5 可视化决策树(画出来看看!)

plt.figure(figsize=(25, 15)) plot_tree( model, feature_names=feature_names, class_names=['拒卡', '批卡'], filled=True, # 用颜色表示类别 rounded=True, # 圆角框 fontsize=12, max_depth=4 # 只画前4层,不然太密 ) plt.title('信用卡审批决策树') plt.show()

5.6 决策树回归(预测授信额度)

如果把标签改成连续值(批多少额度),就是用回归树。

from sklearn.tree import DecisionTreeRegressor from sklearn.metrics import mean_squared_error, mean_absolute_error # 生成新的标签:授信额度(万),范围2~50 limit = 2 + income * 2.5 + credit_score * 0.02 - debt_ratio * 10 + np.random.normal(0, 2, n) limit = np.clip(limit, 2, 50) # 重新切分 X_train, X_test, y_train_reg, y_test_reg = train_test_split( X, limit, test_size=0.3, random_state=42 ) # 创建回归树 reg_model = DecisionTreeRegressor( max_depth=6, min_samples_split=20, min_samples_leaf=10, random_state=42 ) # 训练 reg_model.fit(X_train, y_train_reg) # 预测 y_pred_reg = reg_model.predict(X_test) # 评估 mse = mean_squared_error(y_test_reg, y_pred_reg) mae = mean_absolute_error(y_test_reg, y_pred_reg) print(f"回归树 - 均方误差(MSE):{mse:.2f}") print(f"回归树 - 平均绝对误差(MAE):{mae:.2f}") print(f"真实额度前5个:{y_test_reg[:5]}") print(f"预测额度前5个:{y_pred_reg[:5]}")

第六部分:决策树 vs KNN(什么时候用谁?)

对比维度决策树KNN
是否需要标准化❌ 不需要✅ 必须做
可解释性✅ 超强(可以画出来看)❌ 黑盒
训练速度✅ 快❌ 慢(要存所有数据)
预测速度✅ 极快(就几层判断)❌ 慢(要算距离)
对缺失值处理可以处理无法处理
过拟合风险高(需要剪枝)低(调K值就好)
非线性数据✅ 能处理❌ 效果差

经验建议

  • 需要解释给老板/客户听→ 选决策树(可以画图展示)

  • 数据特征少、干净→ 选KNN

  • 数据有缺失值→ 选决策树

  • 追求预测速度(在线服务)→ 选决策树

  • 追求极致准确率→ 两个都试试,选好的


第七部分:CART的优缺点

7.1 优点(5个)

优点说明
简单易懂画出来一看就懂,非技术人员也能理解
功能强大分类回归通吃
规则简洁强制二分,逻辑清晰
鲁棒性好自带剪枝,抗过拟合
应用广泛是随机森林、XGBoost的基石

7.2 缺点(3个)

缺点说明
容易过拟合不加限制的话,可以完美拟合训练集
结果不稳定数据稍微变一点,整棵树可能完全不一样
非全局最优每一步只选当前最优(贪心),不保证整体最优

第八部分:剪枝详解(两种方式对比)

8.1 预剪枝(Pre-pruning)

在树生长过程中就决定“要不要继续分”。

# 这就是预剪枝——通过参数限制树的生长 model = DecisionTreeClassifier( max_depth=5, # 到5层就不分了 min_samples_split=20, # 样本少于20就不分了 min_samples_leaf=10 # 叶子少于10就不分了 )
优点缺点
省时间(不用长完整棵树)可能“短视”——现在没用但后面有用的分支被误砍
防止过拟合容易欠拟合

8.2 后剪枝(Post-pruning)

先让树完全长成,再从下往上检查:这个分支有用吗?没用就砍掉。

sklearn的DecisionTreeClassifierccp_alpha参数可以实现成本复杂度剪枝(一种后剪枝)。

# 用ccp_alpha做后剪枝(值越大剪得越狠) model_pruned = DecisionTreeClassifier( ccp_alpha=0.005, # 剪枝系数,需要调参 random_state=42 ) model_pruned.fit(X_train, y_train)
优点缺点
比预剪枝效果好(保留了更多有用分支)耗时(先要长完整棵树)

实战建议:先用预剪枝(限制max_depth等),简单高效;如果效果还不够好,再尝试后剪枝。


第九部分:完整知识点脑图

决策树(CART) │ ├── 核心思想 │ └── 像做选择题一样,一层层往下问,直到出答案 │ ├── 三大规则 │ ├── 强制二分(每次只分两组) │ ├── 贪心选择(每一步选最"纯"的特征) │ └── 递归进行(一层一层往下分) │ ├── 两种任务 │ ├── 分类树(基尼系数衡量纯度) │ └── 回归树(MSE衡量纯度,叶子输出平均值) │ ├── 防止过拟合 │ ├── 预剪枝(限深度、限样本数)← sklearn默认 │ └── 后剪枝(先长完整棵树再砍)← ccp_alpha │ ├── 优势 │ ├── 可解释性强(可以画图) │ ├── 不需要标准化 │ └── 能处理缺失值 │ └── 劣势 ├── 容易过拟合 ├── 结果不稳定(数据一变树就变) └── 贪心策略不保证全局最优

第十部分:总结

模块核心内容
决策树思想一层一层做选择题,直到得出结论
CART算法强制二分 + 基尼系数 + 递归分裂
分类 vs 回归分类看基尼,回归看MSE
超参数max_depth、min_samples_split等(防过拟合)
剪枝预剪枝(生长时限制)和后剪枝(长完再砍)
对比KNN决策树可解释性强、不需标准化、速度快
代码实战信用卡审批预测(分类)+ 额度预测(回归)

给新手的3个建议

  1. 先理解“树是怎么长的”:每次找一个特征分裂→让数据变纯→递归→停止。把这句话背下来,决策树的骨架你就有了。

  2. 重视max_depth这个参数:它是防止过拟合最简单粗暴的手段。从max_depth=3开始试,慢慢加深。

  3. 画图看树plot_tree是你理解模型最好的工具。画出来一看,比看100行代码都管用。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/3 13:54:35

5分钟接入 WhatsApp Cloud API Webhook,实现自动回复

5分钟接入 WhatsApp Cloud API Webhook,实现自动回复目录WhatsApp Cloud API 简介环境准备Webhook 配置步骤Python 代码实现常见踩坑与解决方案进阶:接入 WADesk 实现多账号管理一、WhatsApp Cloud API 简介WhatsApp Cloud API 是 Meta 在 2022 年推出的…

作者头像 李华
网站建设 2026/7/1 2:31:02

RIS赋能的ISAC系统隐私保护技术解析

1. RIS赋能的隐私保护集成感知与通信系统解析在无线通信与感知技术深度融合的今天,集成感知与通信(ISAC)系统正面临前所未有的隐私安全挑战。传统无线信号中的信道状态信息(CSI)就像一把双刃剑——它既能实现毫米级的人体动作识别,也可能成为黑客窃取隐私…

作者头像 李华
网站建设 2026/7/1 2:26:31

从IO500双榜第一,看国产存储的系统级突破

作者:王聪彬中国存储厂商再次站上全球榜单最高点。6月24日,ISC 2026高性能计算大会公布最新IO500榜单,中科曙光ParaStor F9000全闪存储系统包揽生产型全节点榜单和10节点榜单双榜第一,也是首个达成此成就的中国厂商,实…

作者头像 李华
网站建设 2026/7/2 7:19:13

OBS直播教程:OBS美颜常见的七个问题

做了两年多直播技术支持,关于OBS美颜插件的问题基本就那几个反复出现。obs美颜插件安装了不显示、摄像头被占用、黑边去不掉、美颜效果不生效——这些问题看着简单,但新手卡住就很崩溃。 今天把7个最高频的obs美颜教程问题整理出来,每个都给排…

作者头像 李华
网站建设 2026/7/1 2:23:20

6.30遇到的问题

1.个人资料修改头像,只能使用默认头像,上传的图片不能当头像2.我的钱包:绑定支付宝沙箱和银行卡,下完单之后,钱包余额不能自动扣除3.优惠券领取不能点击,打车界面看不到使用最优优惠券后的价格4.天气不能实…

作者头像 李华