本文对 IBM Telco Customer Churn 数据集进行完整的生存分析,涵盖 Kaplan-Meier 生存曲线估计、Cox 比例风险模型和加速失效时间(AFT)模型,并基于 MySQL 数据库演示 LLM 在 Text-to-SQL 任务中的常见失败模式。
数据集:IBM Telco Customer Churn(7,043 位客户,21 个特征)
筛选条件:
最终样本:3,351 位客户,其中已流失 1,556(46.4%),未流失(删失)1,795(53.6%)。筛选聚焦于流失风险最高的客户——持有月付合同且有活跃互联网服务的客户。
| Metric | Value |
|---|---|
| Observations | 3,351 |
| Events (churn) | 1,556 |
| Censored | 1,795 |
| Median survival time | 34.00 months |
中位生存时间为 34 个月,意味着到第 34 个月时有 50% 的客户已流失。生存概率在最初几个月快速下降,表明早期阶段存在较高的流失风险。
| Covariate | Test Statistic | p-value | 显著? |
|---|---|---|---|
| gender | 2.04 | 0.153 | No |
| seniorcitizen | 0.13 | 0.723 | No |
| partner | 135.76 | 2.25e-31 | Yes |
| internetservice | 25.17 | 5.24e-07 | Yes |
| onlinesecurity | 141.60 | 1.19e-32 | Yes |
| techsupport | 90.43 | 1.92e-21 | Yes |
| paperlessbilling | 8.34 | 0.0039 | Yes |
主要发现:性别和老年公民状态对生存/流失模式没有显著影响。在线安全和伴侣状态显示出最显著的差异。Electronic check 的流失率显著高于 Bank transfer 和 Mailed check。
| Covariate | Coef | exp(coef) (HR) | p-value |
|---|---|---|---|
| dependents_Yes | -0.33 | 0.72 | <0.005 |
| internetservice_DSL | -0.22 | 0.80 | <0.005 |
| onlinebackup_Yes | -0.78 | 0.46 | <0.005 |
| techsupport_Yes | -0.64 | 0.53 | <0.005 |
模型指标:一致性(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 模型。
| Covariate (alpha) | Coef | exp(coef) | p-value |
|---|---|---|---|
| onlinesecurity_Yes | 0.86 | 2.37 | <0.005 |
| partner_Yes | 0.68 | 1.97 | <0.005 |
| techsupport_Yes | 0.69 | 1.99 | <0.005 |
| onlinebackup_Yes | 0.81 | 2.25 | <0.005 |
| multiplelines_Yes | 0.66 | 1.94 | <0.005 |
| internetservice_DSL | 0.38 | 1.47 | <0.005 |
| deviceprotection_Yes | 0.48 | 1.62 | <0.005 |
| paymentmethod_Credit card (auto) | 0.80 | 2.22 | <0.005 |
| paymentmethod_Bank transfer (auto) | 0.74 | 2.10 | <0.005 |
模型指标:一致性(Concordance)0.73,AIC 13698.72。在 AFT 模型中,exp(coef) > 1 表示该协变量加速失败(缩短生存时间)。
| Distribution | AIC |
|---|---|
| Log-Normal | 13625.86 |
| Log-Logistic | 13698.72 |
| Weibull | 13771.07 |
最佳拟合分布:Log-Normal(AIC 最小)。这表明生存时间的对数近似服从正态分布,这在流失数据中很常见。
telco_churn,表名 customers问题:找出平均在网时长高于整体平均值,且流失率超过 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;
错误分析:
WHERE AVG(tenure) — 聚合函数不能出现在 WHERE 子句中(WHERE 在 GROUP BY 之前执行),必须用 HAVING。/ 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%) — 揭示了在网时长与流失率的反比关系。
问题:对于每种互联网服务类型,按流失客户数量排名,找出前 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;
错误分析:
PARTITION BY InternetService — 排名针对所有行而非每组内独立排名。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 流失支付方式。
问题:找出月费高于其合同类型平均月费,且已流失的客户,按合同类型和月费排序显示前 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;
错误分析:
WHERE MonthlyCharges > AVG(MonthlyCharges) — 标量值与聚合值不能直接比较,且得到的是全局均值而非按合同类型分组。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)更可能流失,说明相对价格敏感度是流失关键因素。
| 场景 | 失败原因 |
|---|---|
| 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 进行数据库查询演示。