Survival Analysis: IBM Telco Customer Churn

2026-04-27 · 生存分析 · PySpark + Lifelines + MySQL

本文对 IBM Telco Customer Churn 数据集进行完整的生存分析,涵盖 Kaplan-Meier 生存曲线估计Cox 比例风险模型加速失效时间(AFT)模型,并基于 MySQL 数据库演示 LLM 在 Text-to-SQL 任务中的常见失败模式。


1. 数据概述

数据集:IBM Telco Customer Churn(7,043 位客户,21 个特征)

筛选条件:

最终样本:3,351 位客户,其中已流失 1,556(46.4%),未流失(删失)1,795(53.6%)。筛选聚焦于流失风险最高的客户——持有月付合同且有活跃互联网服务的客户。


2. Kaplan-Meier 生存分析

总体生存曲线

MetricValue
Observations3,351
Events (churn)1,556
Censored1,795
Median survival time34.00 months
KM Population Curve

中位生存时间为 34 个月,意味着到第 34 个月时有 50% 的客户已流失。生存概率在最初几个月快速下降,表明早期阶段存在较高的流失风险。

Log-Rank 检验

CovariateTest Statisticp-value显著?
gender2.040.153No
seniorcitizen0.130.723No
partner135.762.25e-31Yes
internetservice25.175.24e-07Yes
onlinesecurity141.601.19e-32Yes
techsupport90.431.92e-21Yes
paperlessbilling8.340.0039Yes

主要发现:性别和老年公民状态对生存/流失模式没有显著影响。在线安全和伴侣状态显示出最显著的差异。Electronic check 的流失率显著高于 Bank transfer 和 Mailed check。


3. Cox 比例风险模型

模型结果

CovariateCoefexp(coef) (HR)p-value
dependents_Yes-0.330.72<0.005
internetservice_DSL-0.220.80<0.005
onlinebackup_Yes-0.780.46<0.005
techsupport_Yes-0.640.53<0.005
Cox Hazard Ratios

模型指标:一致性(Concordance)0.64,偏 AIC 22639.90,对数似然比检验 337.77(p < 0.005)。

风险比解读

比例风险假设违背

四个协变量中有三个未能通过比例风险假设检验(Schoenfeld 检验):internetservice_DSL(p < 0.005)、onlinebackup_Yes(p < 0.005)、techsupport_Yes(p < 0.005)。这表明这些协变量对流失风险的影响随时间变化——例如技术支持的保护效应在客户刚接触服务的头几个月可能最强。

建议补救措施:对违反假设的协变量进行分层建模、引入时变协变量、或改用 AFT 模型。


4. 加速失效时间(AFT)模型

AFT Coefficients

Log-Logistic AFT 结果

Covariate (alpha)Coefexp(coef)p-value
onlinesecurity_Yes0.862.37<0.005
partner_Yes0.681.97<0.005
techsupport_Yes0.691.99<0.005
onlinebackup_Yes0.812.25<0.005
multiplelines_Yes0.661.94<0.005
internetservice_DSL0.381.47<0.005
deviceprotection_Yes0.481.62<0.005
paymentmethod_Credit card (auto)0.802.22<0.005
paymentmethod_Bank transfer (auto)0.742.10<0.005

模型指标:一致性(Concordance)0.73,AIC 13698.72。在 AFT 模型中,exp(coef) > 1 表示该协变量加速失败(缩短生存时间)。

分布比较(AIC)

DistributionAIC
Log-Normal13625.86
Log-Logistic13698.72
Weibull13771.07

最佳拟合分布:Log-Normal(AIC 最小)。这表明生存时间的对数近似服从正态分布,这在流失数据中很常见。

生存预测

Predicted Survival Curves

结论与建议

  1. 早期流失是最大风险:生存概率到第 1 个月降至约 90%,到第 10 个月降至约 74%,表明最初几个月是最关键的保留期。
  2. 最具影响力的保留手段:在线备份(HR = 0.46)和技术支持(HR = 0.53)是最强的保护因素,捆绑增值服务可显著降低流失。
  3. 人口统计学特征不显著:性别和老年公民状态未能区分流失模式(Log-Rank p > 0.05)。保留策略应关注服务功能。
  4. Fiber optic 客户流失风险更高:可能与价格敏感度相关。
  5. AFT 模型更适合该数据集:三个协变量违反比例风险假设。

5. MySQL Database + LLM Text-to-SQL 分析

数据库环境

失败案例 1:条件聚合 + 子查询

问题:找出平均在网时长高于整体平均值,且流失率超过 30% 的支付方式。

LLM 生成的错误 SQL:

SELECT PaymentMethod, COUNT(*) AS total,
       ROUND(AVG(tenure), 2) AS avg_tenure,
       ROUND(SUM(CASE WHEN Churn='Yes' THEN 1 ELSE 0 END)/COUNT(*)*100, 2) AS churn_rate
FROM customers
WHERE AVG(tenure) > (SELECT AVG(tenure) FROM customers)
  AND SUM(CASE WHEN Churn='Yes' THEN 1 ELSE 0 END)/COUNT(*) > 0.30
GROUP BY PaymentMethod;

错误分析:

  1. WHERE AVG(tenure) — 聚合函数不能出现在 WHERE 子句中(WHERE 在 GROUP BY 之前执行),必须用 HAVING
  2. / COUNT(*) > 0.30 — 阈值不匹配:前面乘了 100 但此处用 0.30,应为 > 30

正确 SQL:

SELECT PaymentMethod, COUNT(*) AS total_customers,
       ROUND(AVG(tenure), 2) AS avg_tenure,
       ROUND(SUM(CASE WHEN Churn='Yes' THEN 1 ELSE 0 END)/COUNT(*)*100, 2) AS churn_rate
FROM customers
GROUP BY PaymentMethod
HAVING avg_tenure > (SELECT AVG(tenure) FROM customers)
   AND churn_rate > 30
ORDER BY churn_rate DESC;

结果:返回 0 行。Electronic check 流失率最高 (45.29%) 但在网时长 (25.17) 低于总体均值 (32.37),其他支付方式在网时长高但流失率低 (<17%) — 揭示了在网时长与流失率的反比关系

失败案例 2:窗口函数 + 聚合

问题:对于每种互联网服务类型,按流失客户数量排名,找出前 3 名的支付方式。

LLM 生成的错误 SQL:

SELECT InternetService, PaymentMethod, churn_count,
       ROW_NUMBER() OVER (ORDER BY churn_count DESC) AS churn_rank
FROM (
    SELECT InternetService, PaymentMethod,
           SUM(CASE WHEN Churn='Yes' THEN 1 ELSE 0 END) AS churn_count
    FROM customers GROUP BY InternetService, PaymentMethod
) sub
WHERE churn_rank <= 3;

错误分析:

  1. 缺少 PARTITION BY InternetService — 排名针对所有行而非每组内独立排名。
  2. WHERE churn_rank <= 3 在 SELECT 定义的别名之前执行 — SQL 执行顺序限制。

正确 SQL:

SELECT InternetService, PaymentMethod, churn_count, churn_rank
FROM (
    SELECT InternetService, PaymentMethod,
           SUM(CASE WHEN Churn='Yes' THEN 1 ELSE 0 END) AS churn_count,
           ROW_NUMBER() OVER (
               PARTITION BY InternetService
               ORDER BY SUM(CASE WHEN Churn='Yes' THEN 1 ELSE 0 END) DESC
           ) AS churn_rank
    FROM customers GROUP BY InternetService, PaymentMethod
) ranked WHERE churn_rank <= 3
ORDER BY InternetService, churn_rank;

结果:Electronic check 在所有互联网服务类型(DSL、Fiber optic、No)中都是 #1 流失支付方式。

失败案例 3:自连接 + 聚合

问题:找出月费高于其合同类型平均月费,且已流失的客户,按合同类型和月费排序显示前 10 条。

LLM 生成的错误 SQL:

SELECT customerID, gender, tenure, MonthlyCharges, Contract, Churn
FROM customers
WHERE MonthlyCharges > AVG(MonthlyCharges) AND Churn = 'Yes'
GROUP BY Contract
ORDER BY Contract, MonthlyCharges DESC LIMIT 10;

错误分析:

  1. WHERE MonthlyCharges > AVG(MonthlyCharges) — 标量值与聚合值不能直接比较,且得到的是全局均值而非按合同类型分组。
  2. GROUP BY Contract 语义错误 — 不需要聚合,需要保留每个客户记录。

正确 SQL:

SELECT c.customerID, c.gender, c.tenure, c.MonthlyCharges, c.Contract, c.Churn,
       ROUND(a.avg_charges, 2) AS avg_for_contract
FROM customers c
JOIN (SELECT Contract, AVG(MonthlyCharges) AS avg_charges
      FROM customers GROUP BY Contract) a ON c.Contract = a.Contract
WHERE c.MonthlyCharges > a.avg_charges AND c.Churn = 'Yes'
ORDER BY c.Contract, c.MonthlyCharges DESC LIMIT 10;

结果:月费远高于合同类型均值的客户($117 vs $66)更可能流失,说明相对价格敏感度是流失关键因素。

何时 LLM 容易在 SQL 分析中失败

场景失败原因
WHERE vs HAVING 混淆SQL 执行顺序与自然语言映射不清
阈值格式错误百分比 vs 小数表示不一致
窗口函数缺少 PARTITION BY分组语义理解偏差
标量与聚合值混用子查询 vs JOIN 选择不当
不必要的 GROUP BY数据粒度理解错误
MySQL 特有语法混淆不同数据库的 SQL 方言

总结:LLM 在 SQL 执行顺序(WHERE/HAVING/SELECT)、窗口函数语义、子查询与 JOIN 的转换、以及数据库方言差异这几个方面最容易出错。建议始终通过实际运行验证 LLM 生成的 SQL,并检查聚合、分组和过滤逻辑的正确性。


附录:代码与数据

所有代码和数据可在 GitHub 仓库 zhihang344/sta323 中获取。分析使用 PySpark 进行数据预处理,Lifelines 进行生存分析建模,MySQL 进行数据库查询演示。