G05-Customer_Sentiment/README.md

208 lines
11 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) 课程设计**
## 👥 团队成员
| 姓名 | 学号 | 贡献 |
|------|------|------|
| 于洋 | 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` 配置校验
- 部署与监控容器化部署资源优化并行/向量化加上指标监控与告警模型版本管理与回滚策略