G05-Customer_Sentiment/README.md

208 lines
11 KiB
Markdown
Raw Normal View History

# 客户情感预测与风险分析系统
> **机器学习 (Python) 课程设计**
## 👥 团队成员
| 姓名 | 学号 | 贡献 |
|------|------|------|
| 于洋 | 2311020129 | 数据处理、模型训练 |
| 张洁 | 2311020131 | Agent 开发、提交 |
| 杨艺瑶 | 2311020127 | streamlit汇报 |
## 📝 项目简介
本项目旨在构建一个端到端的客户情感分析与风险预警系统。通过对包含2.5万条记录的客户评论数据集Customer Sentiment Dataset进行挖掘结合交易属性如响应时间、解决状态、购买渠道等与评论文本利用机器学习算法自动识别客户的情感倾向Positive/Negative/Neutral
系统不仅实现了高精度的情感分类模型Logistic Regression 与 LightGBM还进一步集成了“预测 → 分析 → 建议”的智能 Agent 流程。最终通过 Streamlit 搭建了交互式仪表盘,支持实时输入客户特征,输出情感风险评分、关键影响因子解释以及针对性的运营建议,帮助企业及时挽留高风险客户,提升服务质量。
## 1⃣ 问题定义与数据
### 1.1 任务描述
**任务类型**:多分类任务 (Multi-class Classification)
**业务目标**:基于客户的评论文本 (`review_text`) 及相关交易属性(如评分、产品类别、平台等),预测客户的情感倾向 (`sentiment`)。该模型旨在帮助企业自动化监控客户反馈,及时识别负面评价并采取行动,从而提升客户满意度和留存率。
### 1.2 数据来源
| 项目 | 说明 |
|------|------|
| 数据集名称 | Customer Sentiment Dataset |
| 数据链接 | 本地文件 (data/Customer_Sentiment.csv) |
| 样本量 | 25,000 条 |
| 特征数 | 11 个 (不含 ID 和标签) |
### 1.3 数据切分与防泄漏
**数据切分**
- 采用 **随机切分** (Random Split) 策略。
- **训练集 : 验证集 : 测试集 = 8 : 1 : 1** (或 70% : 15% : 15%)。
- 设定固定的 `random_state` 以确保实验可复现。
**防泄漏措施**
1. **ID 剔除**:移除 `customer_id`,防止模型记忆特定用户。
2. **特征筛选**:剔除 `customer_rating`(客户评分),因为评分与情感倾向高度相关,直接使用会导致数据泄漏,使任务失去预测意义。
3. **时间穿越**:虽然数据集包含 `response_time_hours``issue_resolved`,但在预测“评论发布时”的情感时,这些可能是未来信息。若业务场景为“收到评论即时预测”,应排除这些特征;若为“事后归因分析”,则可保留。本项目暂作为特征处理,但需注意其业务含义。
4. **预处理隔离**:所有统计特征(如文本向量化的词汇表、数值归一化的均值/方差)仅在 **训练集** 上计算,严禁利用验证集或测试集信息。
## 🚀 快速开始
```bash
# 克隆仓库
git clone http://hblu.top:3000/MachineLearning2025/GXX-Customer_Sentiment_Analysis.git
cd GXX-Customer_Sentiment_Analysis
# 安装依赖
uv sync
# 配置环境变量
cp .env.example .env
# 编辑 .env 填入 API Key
# 运行 Demo
uv run streamlit run src/streamlit_app.py
```
## 2⃣ 机器学习流水线
### 2.1 基线模型
| 模型 | 指标 | 结果 |
|------|------|------|
| Logistic Regression | ROC-AUC | 1.0000 |
### 2.2 进阶模型
| 模型 | 指标 | 结果 |
|------|------|------|
| LightGBM | ROC-AUC | 1.0000 |
### 2.3 误差分析
(模型在哪些样本上表现不佳?为什么?)
**结果分析**
- 模型在测试集上取得了完美的分类效果 (ROC-AUC = 1.0, Accuracy = 100%)。
- **原因推测**数据集可能是合成数据且不同情感类别Positive, Neutral, Negative对应的评论文本模式非常固定且区分度极高例如 "very disappointed" 总是对应 Negative"excellent product" 总是对应 Positive。此外剔除了强相关特征 `customer_rating` 后,文本特征依然提供了足够的信息进行完美分类。
- **潜在问题**:虽然模型在当前数据集上表现完美,但在真实世界的复杂评论数据上可能无法泛化。建议引入更多样化、含噪声的真实评论数据进行进一步测试。
- **错误样本**0/5000 错误)。
### 2.4 阈值策略与代价敏感分析(加分项)
- 业务代价设定:假阴性(负面未拦截)成本 `C_FN = 10`,假阳性(误拦截)成本 `C_FP = 1`
- 风险阈值:为降低期望代价,采用分级策略:
- 高风险:`risk ≥ 0.7` → 立即升级处理、客服介入、补偿策略评估
- 中风险:`0.4 ≤ risk < 0.7` 标记与复核优先排队
- 低风险:`risk < 0.4` 常规监控
- 证据:结合 `explain_features` 的线性贡献因子,定位行动点(如高频负面词、长响应时间、未解决状态)。
## 数据处理(必做)
- 使用 **Polars** 完成可复现的数据清洗流水线,脚本位置:`src/data_processing.py`
- 定义 Schema`define_schema``pandera.polars`)在 `src/data_processing.py:5`
- 清洗流程:`clean_data` 在 `src/data_processing.py:23`(字段标准化、布尔化、类别转换)。
- 探索与保存:`load_and_inspect` 在 `src/data_processing.py:52`(校验→清洗→概览→保存至 `data/Cleaned_Customer_Sentiment.csv`)。
- 运行命令:`py src/data_processing.py`
### 清洗操作Polars + Pandera
- Schema 校验:
- `customer_id > 0``gender ∈ {male,female,other}``age_group ∈ {18-25,26-35,36-45,46-60,60+}`
- `region ∈ {north,south,east,west,central}``purchase_channel ∈ {online,offline}`
- `customer_rating ∈ [1,5]``sentiment ∈ {positive,negative,neutral}``response_time_hours ≥ 0`
- `issue_resolved, complaint_registered ∈ {yes,no}`
- 值标准化与类型转换:
-`issue_resolved`, `complaint_registered``yes/no` 转为 `bool`
-`product_category`, `platform`, `review_text` 统一为小写。
- 将类别列(`gender, age_group, region, product_category, purchase_channel, platform, sentiment`)转换为分类类型。
- 去除泄漏相关特征:在训练阶段剔除 `customer_rating`
- 数据探索输出:
- 类别列的频次统计(略过长文本列)。
- 清洗后数据示例与 Schema 打印。
- 落盘:
- 结果保存到 `data/Cleaned_Customer_Sentiment.csv`,供训练与 Demo 使用。
### 清洗结果(核心指标)
- 总行数:`25,000`
- 空值计数:所有列空值为 `0`
- 情感分布:
- positive: `9,978`
- negative: `9,937`
- neutral: `5,085`
- 性别分布:
- male: `8,385`female: `8,356`other: `8,259`
- 渠道分布:
- `purchase_channel = online``25,000`
- 业务状态:
- `issue_resolved=True` 比例:`66.372%`
- `complaint_registered=True` 比例:`39.748%`
- 响应时长(按情感均值,小时):
- neutral: `36.0869`negative: `36.0222`positive: `35.9924`
- Top 平台(前 5
- nykaa (`1,301`), snapdeal (`1,289`), others (`1,286`), reliance digital (`1,279`), zepto (`1,278`)
- Top 产品品类(前 5
- groceries (`2,858`), automobile (`2,833`), books (`2,812`), travel (`2,811`), fashion (`2,782`)
## 机器学习(必做)
- 至少 2 个模型对比:已实现 **Logistic Regression****LightGBM**(见 `src/train_models.py`)。
- 指标达标:`ROC-AUC = 1.0000 ≥ 0.75`(分类报告亦为满分,满足 `F1 ≥ 0.70` 要求)。
- 工件持久化:流水线与标签编码器保存到 `artifacts/`,便于 Agent 复用(`src/train_models.py:137-146` 与持久化 `src/train_models.py:145-149`)。
## 3⃣ Agent 实现
### 3.1 工具定义
| 工具名 | 功能 | 输入 | 输出 |
|--------|------|------|------|
| `predict_risk` | 调用 ML 模型预测 | CustomerFeatures | float |
| `explain_features` | 解释特征影响 | CustomerFeatures | list[str] |
CustomerFeatures 字段:
`gender`, `age_group`, `region`, `product_category`, `purchase_channel`, `platform`, `response_time_hours`, `issue_resolved`, `complaint_registered`, `review_text`
(不包含 `customer_rating``customer_id`
实现位置:`src/agent.py`
模型与预处理加载自:`artifacts/`(含 `lgb_pipeline.joblib`, `lr_pipeline.joblib`, `label_encoder.joblib`
### 3.2 决策流程
- 预测:`predict_risk(features)` 使用 LightGBM 流水线输出负面情感概率risk0.0~1.0)。
- 解释:`explain_features(features)` 通过 Logistic 回归的线性贡献,返回若干条影响说明(包含方向与权重)。
- 建议:基于 `risk` 与解释结果,产品可进一步生成运营建议(如:优先处理高风险投诉、优化长响应时间、针对高频负面词优化客服话术)。
### Agent必做符合项
- 使用 **Pydantic** 定义输入与输出模型:
- `CustomerFeatures` 输入模型(`src/agent.py:11-21`,包含枚举与边界约束)
- `RiskOutput``ExplanationOutput` 输出模型(`src/agent.py:23-27`
- 至少 2 个工具:
- `predict_risk`ML 预测工具,`src/agent.py:47-52`
- `explain_features`(特征影响解释,`src/agent.py:57-73`
## 4⃣ 开发心得
### 4.1 主要困难与解决方案
- 依赖安装与网络:`polars`, `pandera`, `scikit-learn`, `lightgbm`, `pyarrow` 等包在国内网络下安装不稳定。
解决:配置清华镜像(如 `pip -i https://pypi.tuna.tsinghua.edu.cn/simple`、设置 `UV_INDEX_URL`),分步安装缺失依赖(如 `pyarrow` 用于 `polars.to_pandas()`)。
- 项目初始化命名问题:中文目录名导致 `uv init` 的包名无效。
解决:使用 `uv init --name customer-sentiment-analysis` 指定合法英文包名。
- 模型参数兼容性:`LogisticRegression` 版本差异导致 `multi_class` 参数报错。
解决:移除不兼容参数,使用默认自动模式。
- 数据泄漏与指标异常:出现近乎完美的指标,初步判断评分与文本标签高度相关。
解决:剔除 `customer_rating` 特征,保留文本与业务属性;同时在文档明确风险与解释原因。
- 工件持久化与推理:训练后需在推理端复用预处理与模型。
解决:将流水线与标签编码器持久化至 `artifacts/`,在 `src/agent.py` 统一加载与推理。
### 4.2 对 AI 辅助编程的感受
- 明显提升效率:快速生成数据流水线、模型训练与解释模块、结构化文档,排查错误栈更高效。
- 需要严格验证:对自动生成的代码进行运行验证与指标审查,关注版本兼容与数据泄漏。
- 最佳实践:固定 `random_state`、将预处理封装进 `Pipeline`、仅在训练集拟合、保存可复用工件、在 README 清晰记录假设与风险。
### 4.3 局限与未来改进
- 数据与评估:引入更真实、含噪声的评论数据;采用交叉验证与时间切分;增加宏平均 F1、精细化错误聚类。
- 解释与可用性:引入 SHAP/LIME 等更稳健的解释方法;将解释结果转为面向运营的建议话术。
- 系统与工程:将 `agent.py` 封装为服务/API集成 Streamlit 交互完善单元测试、CI、类型检查与 lint健全 `.env` 配置校验。
- 部署与监控:容器化部署、资源优化(并行/向量化);加上指标监控与告警、模型版本管理与回滚策略。