☰
基于决策树的电信客户流失预测:从特征工程到业务落地全流程解析
2026/10/19 5:29:01 网站建设 项目流程

做过运营商存量项目的都知道,客户流失预警从来不是“要不要做”而是“怎么做”的问题。我前阵子刚完成一个完整的流失预测分析,从数据清洗、特征加工到决策树建模、参数调优,再到最后输出可执行的挽留名单,走了一遍全流程。这次复盘,把核心环节和踩过的坑一并整理出来,聊的是基于决策树的电信客户流失预测分析。

这个项目的业务价值很直接:把“哪些客户在未来一段时间可能离网”这个问题,转化成一个分类问题,用决策树从历史数据里学出流失规律,再拿模型去给存量客户打分排序。对数据分析和建模岗的同学来说,这是一份非常合适的中级练手项目——数据量不大、特征语义清晰、决策树算法容易上手,而且最后的结果能直接跟运营同事解释,成就感来得很快。

我自己的感觉是:这个项目最大的学习点不在于“调一个多复杂的模型”,而是整个过程你必须时刻把业务目标挂在嘴边——准确率不是唯一指标,什么样的漏报和误报是业务能接受的,比模型本身的精度更重要。下面按我的实际操作流程展开说。

1. 流失预测这件事,先想清楚业务逻辑再动手

1.1 流失预测在电信业务里到底解决什么难题

电信行业的客户生命周期和一般互联网产品不太一样。用户一旦选了一家运营商的套餐,通常会有较长的使用周期,但换号、转网成本也在逐年降低。一个客户流失了,损失的不仅是他这一个月的话费、流量费,还包括后续若干年的消费贡献,以及他在社交圈里可能带给其他潜在用户的负面影响。业内普遍认为,获取一个新客户的成本往往是留住一个老客户的五倍甚至更高,所以“存量经营”成了运营商运营团队的核心命题,客户流失预测就是存量经营里最前置的一环。

从实际业务看,流失预测的任务可以这么定义:给定一个客户在某个时间截面上的属性(在网时长、套餐类型、消费水平、服务使用情况等),预测他在下一个时间窗口内是否流失。流失的定义也要事先和业务对齐——有的是“号码销户离网”,有的是“连续N个月无语音/流量行为”,不同定义会影响样本标注,也直接影响模型学习的目标。我这次采用比较常见的定义:目标月份内客户主动销户或转入停机保号状态,视为流失。

这里有个容易忽略的点:预测不是最终目的,干预才是。如果没有对应的挽留手段,比如合约优惠、套餐下调、服务升级、专属客服跟进,那预测做得再准,也只是纸上谈兵。所以我在做项目前,先和运营侧的同事明确了一件事:输出结果是一份每周更新的“高风险流失客户名单”,名单上要标注风险等级和可能的流失驱动因素,运营再根据名单分层施策。这个业务闭环,决定了模型输出格式和评估口径。

1.2 为什么决策树在这个场景里比复杂模型更好用

很多同学一上来就想用XGBoost、LightGBM或者深度学习模型,觉得效果一定更好。我不否认集成模型在精度上通常优于单棵决策树,但在流失预测这个场景里,决策树有一个任何复杂模型都给不了的优势:可解释性。

运营同事不会关心你用的基尼系数还是信息增益,他们关心的是“为什么这个客户会被列为高风险”。决策树天然是一组if-then规则,比如“在网时长小于10个月 且 月消费高于70元 且 使用按月合约 → 高风险”,这个规则可以直接说给人听,也能直接转成运营动作。即便是要做更复杂的模型,决策树也适合第一个上场当基线——构建快、结果稳、特征重要性能快速给出业务洞察。

另外,决策树对数据的容忍度比较高。电信数据里有大量分类型变量(合约类型、支付方式、互联网服务类型),决策树可以直接处理,不需要像逻辑回归那样先做大量的哑变量编码。树模型还天然不要求特征标准化,量级差异、分布偏斜对它的影响都远小于距离类模型。这些特性让我在数据清洗阶段能省下不少事,把精力集中在真正影响结果的特征理解上。

2. 数据清洗与特征工程,决定模型上限的往往是这步

2.1 一份典型的电信客户数据长什么样

我这里用的是一份典型的电信客户历史订单数据集,大概七千多条样本,每条样本对应一个客户在当前时间截面的档案。字段可以分为三类:人口统计学特征、服务订阅特征、消费账单特征。

人口统计学特征包含性别、是否为老年人、是否有伴侣、是否有家属等;服务订阅特征包含电话服务类型、互联网服务类型、是否开通在线安全服务、设备保护、技术支持、流媒体电视、流媒体电影等;账单特征包含签约时长(月)、月消费金额、累计消费金额、合同类型、付款方式、纸质账单偏好等。目标列是“是否流失”,一个二分类标签。

我想强调的是,这份数据虽然是开源的模拟数据,但字段设计和真实运营商数据高度相似。真实环境中还会多出通话时长、流量使用分布、投诉工单次数、客服交互记录等行为维度字段,模型效果自然会更好,但处理思路是一样的。作为练手,先把这份数据的规律吃透,后面接真实数据就不会慌。

2.2 清洗和预处理的几个关键动作

拿到数据后我的第一个动作不是建模,而是把每个字段过一遍,看缺失值、看类型、看分布。这一步看着枯燥,但很多低级错误都是后来返工才发现的。

先说缺失值。这份数据里“累计消费金额”字段存在少量空值,数量占比大概不到2%。我查了一下,这些空值基本都出现在“签约时长=0”的新客户身上——客户刚入网,还没有产生过任何账单,累计金额自然为空。这种情况直接填充为0是合理的,因为0本身就是真实含义,不能用均值去填充。这也是一条经验:缺失值的填充方式,先想业务含义,再选统计方法。

再说类型转换。“累计消费金额”在原始数据里被读成了字符串类型,因为字段里可能混入了空白字符。我直接用正则清洗后转成float,这种问题在真实数据里非常常见。分类型字段里,二元字段(比如“是否开通在线安全服务”)我用标签编码,变成0/1;多分类字段(比如“互联网服务类型”有三种取值)转成哑变量。有一类字段特别容易被坑——付款方式有电子支票、邮寄支票、银行自动转账、信用卡自动转账四种,它是无序类别,只能做One-Hot编码,不能按1/2/3/4处理。

最后是拆分数据集和检查类平衡。我用分层抽样的方式按75%和25%划分训练集和测试集,并且设置了固定随机种子,保证结果可复现。检查目标列后发现流失样本约占26%,整体是偏不平衡的。这个问题我在后面第五节会详细展开,因为处理方式直接影响模型效果和评估口径。

2.3 特征筛选与关键衍生变量

清洗完不代表所有字段都要塞进模型。我习惯先做一轮单变量分析,看每个特征和流失标签之间有没有直观的相关性,再决定怎么加工。

在网时长和合约类型是两个信号最强的字段。这个结果其实很符合业务直觉:在网时间越长,说明客户越稳定,流失概率越低;按月签约的客户比按年签约的客户流失风险高得多。我做了个简单统计,按月合约客户的流失率几乎是两年合约客户的三倍,这个差异非常显著。另外月消费金额和流失率大致呈U型关系——低消费用户觉得服务可有可无容易走,高消费用户对价格敏感也容易走,中间段更稳。这种非线性关系,也正是决策树能比线性模型表现更好的原因。

在衍生变量上,我加了两个。一是“服务开通数量”,把在线安全、设备保护、技术支持等增值服务加总,代表客户在网内绑定的服务深度——绑定越多,退出成本越高,流失概率越低。二是“是否新客户”,在网时长小于6个月标记为1,因为新用户阶段是流失高发期。衍生变量的原理也一样:不是越多越好,要看它是否真的刻画了客户的退出成本和使用粘性。

我在这轮做完之后,把字段从20个左右缩到16个入模特征。精简的目的不是单纯为了降维度,而是为了让决策树更容易学到稳定规律,也方便后面做特征重要性解读。

3. 决策树建模与调参的核心过程

3.1 决策树是怎么一步步“做决策”的

进入建模环节之前,先把决策树的工作原理说清楚。决策树做分类的过程,其实就是递归地把样本空间切分成越来越纯的子集。每个节点选一个特征,按特征取值把当前样本切到子节点,目标是让子节点里的样本类别尽可能一致。衡量这个“纯度提升”的指标有两种常用方案:一种是信息熵,对应信息增益;一种是基尼系数,对应基尼指数。

拿“合约类型”来举例。初始样本里流失样本占比约26%,整个数据集的信息熵大概是0.85左右。如果按照“是否按月签约”把样本切成两组,按月签约的那一组流失占比大幅升高,信息熵显著下降;按年签约的那一组流失占比下降,熵也下降。两次熵的加权平均比初始熵小,这个差值就是信息增益。决策树在每个节点上,遍历所有特征的所有可能切分方式,找出信息增益最大的那个切分,然后递归重复。这就是决策树“学习”的过程。

基尼系数比信息熵的计算更快,默认情况下我通常先选基尼系数。两者在大多数场景下结果差异不大,但如果你有充足的计算资源,可以两个都试一下,放进交叉验证里对比。

3.2 训练集与测试集的划分策略

划分数据这件事,很多新手会忽略“分层抽样”的细节。如果用普通的随机划分,测试集里的流失比例很可能偏离训练集,导致评估时高估或低估模型表现。我用train_test_split时传了stratify参数,按“是否流失”分层抽样,保证两边类别比例一致,这样后续评估指标才有参考意义。

树的训练还需要注意验证策略。单次划分训练集和测试集,调参时如果反复对着测试集试,其实会造成信息泄露,调出来的参数在真正未见过的数据上会打折扣。我在这里做了两层防护:先做一次75/25的训练测试划分,测试集全程只最后用一次;调参过程用5折交叉验证,每次训练再对训练集内部划分5份,轮流来训练和验证。这样模型参数是在验证集上选出来的,最终报告用的是没参与过任何训练和调参的测试集,评估结果干净可信。

3.3 参数调优与剪枝实战

决策树的超参数不多,但组合起来影响很大。我最看重的四个是:最大深度max_depth、内部节点再划分需最小样本数min_samples_split、叶子节点最小样本数min_samples_leaf、最大特征数max_features。理解这些参数要回到树生长的本质:树如果完全不限制生长,它会一直切分到每个叶子都很纯,结果必然是过拟合——训练集上准确率接近100%,测试集上大幅下降。

我用网格搜索来调参。搜索范围大致如下:max_depth从3到9,min_samples_split从2到20,min_samples_leaf从1到10,max_features在auto和sqrt之间选择,criterion在基尼和熵之间二选一。5折交叉验证后,效果最好的组合通常落在深度5到6左右,min_samples_leaf设置在5附近。这个结果在意料之中:限制深度和叶子大小,本质上是给树做了预剪枝。

除了预剪枝,决策树还支持后剪枝。在Scikit-learn里可以通过设置代价复杂度剪枝参数ccp_alpha实现。原理是:先生成完整树,再按“剪掉某个节点后整体误差变化”给每个节点算一个值,ccp_alpha越大,剪掉的节点越多,树越精简。我试过一次,在交叉验证里把ccp_alpha从0慢慢往上调,找到模型效果开始明显下滑的临界点。实际操作中,预剪枝和代价复杂度剪枝可以配合使用,但一般先用预剪枝把深度和叶子大小限制住,再看有没有必要走后剪枝。

调参后模型的测试集表现,拿一份参考实验数据说:准确率大概在79%到81%之间,AUC大约在0.83到0.85之间,召回率在55%到60%区间。单独看准确率不算惊艳,因为流失样本占比低,模型即使把所有人都判为不流失,准确率也能有74%——这正是后面我们要评估指标的原因。

4. 模型评估、可解释性与业务落地

4.1 混淆矩阵和业务指标取舍

做分类评估,混淆矩阵是第一个要看的工具。横纵坐标分别是预测类别和真实类别,四个格子分别是:真正例(预测流失且实际流失)、假正例(预测流失但实际没流失)、真负例(预测未流失且实际未流失)、假负例(预测未流失但实际流失)。

从这四个格子出发,可以推导出精确率、召回率、F1值和AUC一系列指标。但在流失预测这个业务场景里,盲目追求准确率没有任何意义。假设模型把所有客户都判为“不流失”,准确率也有74%,但那些真正流失的客户一个都没被捞出来,运营团队拿不到名单,模型等于废了。所以业务上更关心的是召回率,也就是真实流失客户里有多大比例被模型识别出来了。召回率越高,漏网之鱼越少。

但召回率也不能无限追高。把预测阈值往下调,模型会把更多客户标为高风险,漏报减少但误报增多。误报意味着运营团队要浪费资源去维护那些本来就不会流失的客户,实际上增加了打扰,可能适得其反。整个决策过程就是在这两个方向之间找平衡:捞回越多流失客户,误伤也越多,而整个运营团队每天的触达量是有限的。我这里最终采用了阈值平衡法:以预测概率大于0.5作为默认高风险线,同时单独给运营一个“概率超过0.3的中风险名单”,低风险名单用于日常观察,不主动打扰。

4.2 特征重要性透露的流失密码

决策树的特征重要性是一个特别适合向业务汇报的中间产物。它的计算逻辑大致是:每个特征在所有节点切分时带来的纯度提升量做累计,再按比例归一化。数值越大,说明模型在区分流失与否时对这个特征的依赖程度越高。

我跑出来的特征重要性排前三的一般是:在网时长、合约类型、月消费金额,后面跟着服务开通数量、是否新客户、累计消费金额。这个排序和业务直觉完全能对上,也让运营同事更容易接受模型。比如在网时长的特征重要性通常稳居首位,因为一个新用户和一个五年老用户的流失概率差距是数量级的。

结合特征重要性,我能提炼出几个对业务有指导意义的规则:按月签约客户是流失重灾区,特别是其中在网时长小于10个月的新客群体;高消费但没开通技术支持服务的客户,往往对故障处理体验不满,容易转投别家;累计消费金额越高但近期没有新增值服务的客户,可能存在服务与需求不匹配的问题。这些规则不涉及太复杂的逻辑,运营直接拿去就能制定话术和策略。

4.3 从预测名单到实际的运营动作

模型打分只是项目的一半,怎么把名单用起来才是真正创造价值的部分。我这里做一个简化的落地流程:每周跑一次模型,输出本周存量客户的风险分,按风险等级分桶,每个桶对应不同运营策略。

高风险桶,预测概率大于0.5,运营优先触达。策略上优先做“体检式关怀”——排查余额不足、流量饱和、套餐不匹配等问题,针对高消费客户推合约升级,针对低消费沉默客户推送优惠券。中风险桶,预测概率0.3到0.5,不主动扣费营销,但会对即将到期的合约客户发送续约提醒。低风险桶基本不做动作,避免打扰优质客户。

这里还不能漏掉同样重要的模型监控环节。模型上线后,每周要比较预测名单和实际流失名单,每周回收真实命中率;每月要重新训练一次或至少做一次数据漂移检查。如果模型用的特征分布变了,特征重要性排序也变了,那训练数据的假设可能已经失效,必须及时更新。算下来,这其实是一个需要持续投入的运营机制,而不是一次性输出一份报告。

5. 常见问题与排查技巧实录

5.1 流失样本占比低,模型学不到规律怎么办

电信流失数据天然不平衡,流失样本往往是少数类。决策树在默认情况下会偏向多数类,训练出来的模型在预测时几乎把所有样本都判为不流失,召回率极低。先确认你遇到的真是这个问题:打印模型预测结果的类别分布,如果流失类几乎没预测出来,基本可以断定是类别不平衡。

我有几种手段可以处理。第一是直接调class_weight='balanced',让损失函数给少数类的错误预测更高的权重,这个改动成本最低,很多情况下效果立竿见影。第二是过采样,用SMOTE或随机过采样让训练集里流失样本的数量接近多数类,但要注意SMOTE在类别重叠区域容易生成噪声样本,反而让树学到错误规律。第三是换评估指标,从一开始就不看准确率,而是关注召回率、F1和AUC,这些指标对少数类的表现更敏感。

这里有个经验之谈:不要先动手处理不平衡,而是在模型训练后先观察结果分布。如果模型已经能学出一定规律,只是召回率不够高,那用class_weight调整一下往往就够了;如果模型基本是“死水一潭”,再考虑SMOTE或者其他采样方法。简单的方法永远排在前面。

5.2 决策树过拟合和不稳定怎么同时解决

决策树过拟合是它的天性。树生长的本质是不断划分到纯,如果不对生长做限制,训练集上每个叶子都能分得很干净,模型把训练数据里的噪声也一并记下来了,测试集上自然表现差。解决思路就是第五节3.3里提到的预剪枝和后剪枝组合使用。

更麻烦的一个问题是决策树的稳定性。同一个数据集,稍微改动一点训练样本,树的结构就可能完全变样,解释规则也跟着变。这是因为决策树在每个节点上是贪心选择最优切分,某个特征的微小优势就可能导致完全不同的分支结构。要缓解这个不稳定性,一个做法是加上随机性——比如max_features='sqrt'让每个节点只随机挑选一部分特征参与竞争,虽然单棵树的稳定性下降,但从统计上反而更稳健。

在实际项目中,我通常的策略是:用单棵决策树快速摸清特征和业务规律,如果团队需要更高的线上AUC,再往随机森林或梯度提升树走。随机森林本质是决策树的集成,结构上可以从单棵决策树平滑过渡,解释性虽然弱一些,但稳定性明显提升。这块如何取舍,其实也取决于你和业务方的关系——他们更接受黑盒还是更接受规则。

5.3 特征工程里的数据泄露,坑得无声无息

最后必须专门提一个我栽过的跟头:数据泄露。泄露的意思是,某些特征里包含了未来信息,模型在“预测未来”时其实已经偷看到了结果。

比较典型的泄露情形是“累计消费金额”和“在网时长”:累计消费金额如果在时间段内包含了流失之后发生的费用,实质上等于造假。所以做特征工程的时候,一定要明确每个特征的时间属性。数据集的每个样本代表客户在某个截面前的状态,这个时间截点必须早于流失标签的定义时刻,模型才具有预测意义。

再细化一点,很多衍生特征也会引入泄露。例如“距离合约到期月数”这个特征,如果客户已流失,你算不出“到期月数”因为根本没有未来信息。即使在训练阶段你没发现异常,上线后模型的实际表现也会非常拉胯,因为线上环境没有线下训练时能拿到的未来信息。处理思路是统一约束:所有特征只允许使用T时刻之前的历史信息,标签严格取T时刻之后的结果。这个约束在代码实现上要时刻检查,通常我会专门写一个数据对比工具去验证训练和预测阶段的字段时间范围是否一致。

回想这个项目,让我收获最大的不是模型精度有多高,而是学会把模型放到业务闭环里看问题。决策树在这类场景里真正发挥价值的地方,是它用透明的规则帮我们把业务理解转成了可执行的运营动作。如果你正打算做类似项目,建议也按“业务定义—特征工程—基线模型—调参评估—运营落点”的顺序走一遍,千万别跳步。最后一个小建议:把训练得到决策树可视化导出来,挑几条分支给运营同事看,他们对模型的理解程度会立刻上一个台阶,项目推进起来顺很多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询