G18/README.md
2026-01-15 13:13:27 +08:00

6.3 KiB
Raw Blame History

电信客户流失预测系统

机器学习 (Python) 课程设计

👥 团队成员

姓名 学号 贡献
陈思坤 2311020204 数据处理、模型训练
(请填写) (请填写) Agent 开发、Streamlit
(请填写) (请填写) 测试、文档撰写

📝 项目简介

本项目基于 Telco Customer Churn 数据集,构建了一个完整的客户流失预测与挽留建议系统。系统包含三个核心能力:

  1. 传统机器学习:使用 LightGBM 模型预测客户流失概率
  2. LLM 集成:使用 DeepSeek 生成个性化挽留建议
  3. Agent 工具调用:通过 pydantic-ai 实现 ML 预测 + 风险分析的工具链

🚀 快速开始

# 克隆仓库
git clone http://hblu.top:3000/MachineLearning2025/GXX-TelcoChurn.git
cd GXX-TelcoChurn

# 安装依赖
uv sync

# 配置环境变量
cp .env.example .env
# 编辑 .env 填入 API Key

# 训练模型
uv run python src/train.py

# 运行 Demo
uv run streamlit run src/streamlit_app.py

1 问题定义与数据

1.1 任务描述

  • 任务类型:二分类
  • 业务目标:预测电信客户是否会流失,并给出针对性的挽留建议
  • 输入:客户基本信息、服务订阅情况、账户信息
  • 输出:流失概率、风险等级、挽留行动计划

1.2 数据来源

项目 说明
数据集名称 Telco Customer Churn
数据链接 Kaggle
样本量 7,043 条
特征数 20 个
流失率 ~26.5%

1.3 数据切分与防泄漏

  • 切分策略80% 训练集20% 测试集
  • 分层采样:使用 stratify=y 确保训练集和测试集的流失率一致
  • 随机种子:固定 random_state=42 确保可复现
  • 防泄漏措施
    • 不使用 customerID 作为特征
    • TotalCharges 与 tenure 存在相关性,但保留两者因为业务含义不同
    • 所有特征工程在训练集上拟合,在测试集上转换

2 机器学习流水线

2.1 数据预处理

使用 Polars 进行高性能数据处理:

# 使用 Polars Lazy API
df = pl.read_csv("data/WA_Fn-UseC_-Telco-Customer-Churn.csv")
df_clean = preprocess_data(df)  # 删除缺失值、转换类型

使用 Pandera 进行 Schema 校验:

class CleanTelcoSchema(pa.DataFrameModel):
    tenure: int = pa.Field(ge=0, nullable=False)
    MonthlyCharges: float = pa.Field(ge=0, nullable=False)
    Churn: int = pa.Field(isin=[0, 1], nullable=False)

2.2 基线模型

模型 F1 Score ROC-AUC
Logistic Regression ~0.58 ~0.84

2.3 进阶模型

模型 F1 Score ROC-AUC
LightGBM ~0.60 ~0.85

2.4 误差分析

模型在以下样本上表现不佳:

  1. 边界客户:流失概率在 0.4-0.6 之间的客户,模型难以准确判断
  2. 长期客户突然流失:任期较长但突然流失的客户,可能受到外部因素影响
  3. 低费用客户:月费较低的客户,特征区分度不够

改进方向

  • 引入更多行为特征(如投诉记录、服务使用频率)
  • 考虑时序特征(如近期费用变化趋势)

3 Agent 实现

3.1 工具定义

工具名 功能 输入 输出
predict_churn_probability 调用 ML 模型预测流失概率 CustomerFeatures float
get_model_explanation 获取模型特征重要性 - str
analyze_risk_factors 分析客户具体风险因素 CustomerFeatures list[str]

3.2 决策流程

用户输入客户信息
    ↓
Agent 调用 predict_churn_probability → 获取流失概率
    ↓
Agent 调用 get_model_explanation → 获取特征重要性
    ↓
Agent 调用 analyze_risk_factors → 获取具体风险因素
    ↓
Agent 生成结构化输出 (ChurnPrediction)
    ↓
返回:流失概率 + 风险等级 + 关键因素 + 行动计划 + 依据说明

3.3 案例展示

输入

客户信息:任期 2 个月,月费 $89.99,月付合同,光纤服务,电子支票支付

输出

{
  "churn_probability": 0.82,
  "risk_level": "高风险",
  "key_factors": [
    "新客户任期仅2个月流失风险较高",
    "月付合同,无长期绑定,容易流失",
    "使用电子支票支付,该支付方式用户流失率最高"
  ],
  "action_plan": [
    {"action": "提供首年合同升级优惠8折", "priority": "高"},
    {"action": "赠送 3 个月在线安全服务", "priority": "高"},
    {"action": "引导切换为自动银行转账支付", "priority": "中"}
  ],
  "rationale": "该客户为新客户且使用月付合同,根据模型分析,合同类型和客户任期是最重要的流失预测因素..."
}

4 开发心得

4.1 主要困难与解决方案

  1. 数据类型处理TotalCharges 字段在原始数据中是字符串,包含空值

    • 解决:使用 Polars 的条件表达式处理空字符串
  2. 类别不平衡:流失客户仅占 26.5%

    • 解决:使用 class_weight="balanced" 参数
  3. Agent 输出稳定性LLM 有时不按要求调用工具

    • 解决:在 instructions 中明确规定必须调用的工具顺序

4.2 对 AI 辅助编程的感受

  • 有帮助的场景代码框架搭建、API 文档查询、错误调试
  • 需要注意的地方AI 生成的代码需要仔细审查,特别是边界条件处理

4.3 局限与未来改进

  1. 可以引入更多特征(如客户投诉记录、服务使用频率)
  2. 可以实现阈值策略,针对不同风险等级采取不同挽留措施
  3. 可以添加相似案例检索功能,提供历史成功挽留案例参考

📋 Checklist提交前自检

  • 使用 uv sync 安装依赖,无需手动创建虚拟环境
  • .gitignore 包含 .env__pycache__、大文件
  • 在干净环境下可以复现(git clone && uv sync && uv run
  • 没有提交 API Key 或敏感信息
  • 使用 Polars 进行数据处理
  • 使用 Pydantic 定义特征和输出模型
  • Agent 至少有 2 个 tool含 1 个 ML 工具)
  • README.md 说明了数据切分策略
  • Demo 可以正常运行