胡慧华
菜单
首页人工智能机器学习深度学习智能体项目实践关于我
← 返回机器学习课程

DECISION TREE · RANDOM FOREST · COURSE 04

先分析历史客户,再判断谁会流失

问题背景

下面是一组课程教学客户数据。每条记录包含使用月数、周均使用次数、投诉次数、优惠依赖情况,以及客户最终是否流失。

你可以先下载历史数据,寻找流失客户与留存客户之间可能存在的判断规律,再分析右侧的新客户。

客户流失教学数据集12 条带真实标签的历史客户记录churn:1 表示流失,0 表示留存下载数据集 · CSV ↓
下载并分析寻找判断规律预测新客户
待判断客户 · 标签已隐藏

结合历史数据,作出你的初步判断

尝试寻找与这个客户条件相近的历史记录,观察它们最终是流失还是留存。

使用月数8成为客户后持续使用产品的时间
周均使用次数1.4最近一段时间的产品活跃度
投诉次数2近期已记录的服务投诉数量
是否依赖优惠近期续费是否主要由优惠推动
01

建立树形直觉

决策树,就是连续提出几个问题

每个节点提出一个可以回答“是或否”的条件,沿着答案向下走,最终到达一个预测结果。
问题 1周均使用次数 ≤ 2?
问题 2投诉次数 ≥ 2?是 → 预测流失
结果预测留存活跃度相对较高
新客户路径:周均使用 1.4 ≤ 2 → 投诉 2 ≥ 2 → 预测流失
根节点第一个判断问题
内部节点继续细分数据的问题
分支条件回答后的路径
叶节点最终分类结果
02

寻找更好的问题

什么样的条件,适合放在树的上方?

好的分裂会让分开后的两组更“纯”:流失客户尽量聚在一起,留存客户也尽量聚在一起。
满足条件BDHJL
不满足条件ACEFGIK

蓝色方形表示留存,橙色圆形表示流失。颜色和形状同时区分类别。树会比较候选条件,选择能更有效降低混杂程度的分裂。

03 · 控制复杂度

树越深,不一定越好

深树可以继续切分更多细节,但也更容易记住训练数据中的偶然噪声。

交互任务
试着调节树的深度,查看测试集的效果

先从深度1逐步拖到6,重点观察深度超过3后:训练集继续提升时,测试集发生了什么变化?

拖动下方滑块 ↓
1
2

深度超过3后,示意中的训练表现继续上升,但测试表现开始下降,这就是过拟合的典型信号。数值用于教学演示,不代表真实业务精度。

04 · 集成学习

一棵树容易摇摆,多棵树一起判断更稳定

随机抽取历史客户

每棵树看到的数据样本略有不同。

随机选择部分特征

不同树尝试不同判断视角。

独立训练多棵树

树与树之间形成必要差异。

汇总投票

多数意见成为最终分类。

决策树清晰、容易解释

但对数据细微变化较敏感,深树容易过拟合。

随机森林更稳定、通常泛化更好

代价是模型更大,无法像单棵树那样完整展示全部规则。

05 · INTERACTIVE LAB

逐棵加入树,观察投票结果

1流失活跃度 + 投诉

周均使用 ≤ 2.0 → 流失

2流失使用月数 + 优惠

使用月数 ≤ 10 且依赖优惠 → 流失

3流失投诉 + 使用月数

投诉 ≥ 2 → 流失

当前投票流失 3 票 · 留存 0最终预测:流失
06 · 训练与评估

测试集才是检查新客户表现的考场

训练集

学习特征、阈值与树结构。

固定随机种子 42
测试集

训练时没有看过,用来比较准确率、召回率和错误类型。

不能只看准确率:如果漏掉一个真正会流失的高价值客户,业务成本可能远高于一次误报。

07 · PYTHON / SCIKIT-LEARN

用代码训练决策树和随机森林

tree_forest.py
01import pandas as pd
02from sklearn.model_selection import train_test_split
03from sklearn.tree import DecisionTreeClassifier
04from sklearn.ensemble import RandomForestClassifier
05from sklearn.metrics import accuracy_score
06data = pd.read_csv("customer_churn.csv")
07features = ["months", "weekly", "complaints", "discount"]
08X, y = data[features], data["churn"]
09X_train, X_test, y_train, y_test = train_test_split(
10 X, y, test_size=0.2, random_state=42, stratify=y
11)
12tree = DecisionTreeClassifier(max_depth=3, random_state=42)
13tree.fit(X_train, y_train)
14forest = RandomForestClassifier(n_estimators=100, max_depth=4, random_state=42)
15forest.fit(X_train, y_train)
16prediction = forest.predict(X_test)
17print(accuracy_score(y_test, prediction))
18new_customer = pd.DataFrame([[8, 1.4, 2, 1]], columns=features)
19print(forest.predict(new_customer)[0])
01

导入 pandas 读取客户表格。

02

导入训练集与测试集拆分工具。

03

导入决策树分类器。

04

导入随机森林分类器。

05

导入分类准确率指标。

06

读取带有历史流失标签的数据。

07

指定四个客户特征。

08

X 保存特征,y 保存是否流失标签。

09

开始拆分训练数据与测试数据。

10

固定种子并保持流失比例一致。

11

完成数据拆分。

12

建立限制深度为3的决策树,降低过拟合风险。

13

让决策树学习分裂特征与阈值。

14

建立由100棵树组成的随机森林。

15

让不同树基于不同样本和特征完成训练。

16

让森林对未见过的测试客户投票预测。

17

输出测试准确率,检查新数据表现。

18

输入课程开场的新客户特征。

19

输出随机森林最终投票类别。

08 · 使用边界

适合什么问题,又要警惕什么?

适合

分类与数值预测、非线性关系、特征交互、需要规则解释

警惕

过拟合、类别不平衡、数据偏差、森林解释成本、外推能力弱

常见场景

客户流失、风险判断、质量分类、故障预测、营销响应

特征重要性说明模型经常使用哪些信息,但不能直接证明现实因果,也需要检查偏差与公平性。

09 · KNOWLEDGE CHECK

检查你是否理解了“树”和“森林”

当前答对 0 / 5 题。

决策树如何完成一次预测?

树为什么不能无限长深?

随机森林中的树为什么要有所不同?

分类随机森林如何得到最终结果?

特征重要性可以直接说明因果吗?

COURSE 04 · SUMMARY

决策树学习规则,随机森林汇总不同规则的意见

  1. 节点提出判断条件,分支连接下一步。
  2. 分裂目标是让子节点中的类别更纯。
  3. 限制树深可以缓解过拟合。
  4. 随机森林通过样本与特征随机性制造不同的树。
  5. 分类森林用投票得到最终结果。
开场新客户:你的判断是 尚未提交,单棵树和7棵树森林都预测为流失。