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

213 lines
6.3 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 电信客户流失预测系统
> **机器学习 (Python) 课程设计**
## 👥 团队成员
| 姓名 | 学号 | 贡献 |
|------|------|------|
| 陈思坤 | 2311020204 | 数据处理、模型训练 |
| (请填写) | (请填写) | Agent 开发、Streamlit |
| (请填写) | (请填写) | 测试、文档撰写 |
## 📝 项目简介
本项目基于 Telco Customer Churn 数据集,构建了一个完整的客户流失预测与挽留建议系统。系统包含三个核心能力:
1. **传统机器学习**:使用 LightGBM 模型预测客户流失概率
2. **LLM 集成**:使用 DeepSeek 生成个性化挽留建议
3. **Agent 工具调用**:通过 pydantic-ai 实现 ML 预测 + 风险分析的工具链
## 🚀 快速开始
```bash
# 克隆仓库
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](https://www.kaggle.com/datasets/blastchar/telco-customer-churn) |
| 样本量 | 7,043 条 |
| 特征数 | 20 个 |
| 流失率 | ~26.5% |
### 1.3 数据切分与防泄漏
- **切分策略**80% 训练集20% 测试集
- **分层采样**:使用 `stratify=y` 确保训练集和测试集的流失率一致
- **随机种子**:固定 `random_state=42` 确保可复现
- **防泄漏措施**
- 不使用 customerID 作为特征
- TotalCharges 与 tenure 存在相关性,但保留两者因为业务含义不同
- 所有特征工程在训练集上拟合,在测试集上转换
---
## 2⃣ 机器学习流水线
### 2.1 数据预处理
使用 Polars 进行高性能数据处理:
```python
# 使用 Polars Lazy API
df = pl.read_csv("data/WA_Fn-UseC_-Telco-Customer-Churn.csv")
df_clean = preprocess_data(df) # 删除缺失值、转换类型
```
使用 Pandera 进行 Schema 校验:
```python
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,月付合同,光纤服务,电子支票支付
```
**输出**
```json
{
"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提交前自检
- [x] 使用 `uv sync` 安装依赖,无需手动创建虚拟环境
- [x] `.gitignore` 包含 `.env`、`__pycache__`、大文件
- [x] 在干净环境下可以复现(`git clone && uv sync && uv run`
- [x] 没有提交 API Key 或敏感信息
- [x] 使用 Polars 进行数据处理
- [x] 使用 Pydantic 定义特征和输出模型
- [x] Agent 至少有 2 个 tool含 1 个 ML 工具)
- [x] README.md 说明了数据切分策略
- [x] Demo 可以正常运行