| data | ||
| src | ||
| .env.example | ||
| .gitignore | ||
| .python-version | ||
| 111.txt | ||
| Customer_Sentiment.csv | ||
| pyproject.toml | ||
| README.md | ||
| uv.lock | ||
客户情感预测与风险分析系统
机器学习 (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以确保实验可复现。
防泄漏措施:
- ID 剔除:移除
customer_id,防止模型记忆特定用户。 - 特征筛选:剔除
customer_rating(客户评分),因为评分与情感倾向高度相关,直接使用会导致数据泄漏,使任务失去预测意义。 - 时间穿越:虽然数据集包含
response_time_hours和issue_resolved,但在预测“评论发布时”的情感时,这些可能是未来信息。若业务场景为“收到评论即时预测”,应排除这些特征;若为“事后归因分析”,则可保留。本项目暂作为特征处理,但需注意其业务含义。 - 预处理隔离:所有统计特征(如文本向量化的词汇表、数值归一化的均值/方差)仅在 训练集 上计算,严禁利用验证集或测试集信息。
🚀 快速开始
# 克隆仓库
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
- 定义 Schema:
清洗操作(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
- positive:
- 性别分布:
- male:
8,385,female:8,356,other:8,259
- male:
- 渠道分布:
purchase_channel = online(25,000)
- 业务状态:
issue_resolved=True比例:66.372%complaint_registered=True比例:39.748%
- 响应时长(按情感均值,小时):
- neutral:
36.0869,negative:36.0222,positive:35.9924
- neutral:
- Top 平台(前 5):
- nykaa (
1,301), snapdeal (1,289), others (1,286), reliance digital (1,279), zepto (1,278)
- nykaa (
- Top 产品品类(前 5):
- groceries (
2,858), automobile (2,833), books (2,812), travel (2,811), fashion (2,782)
- groceries (
机器学习(必做)
- 至少 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 流水线输出负面情感概率(risk,0.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配置校验。 - 部署与监控:容器化部署、资源优化(并行/向量化);加上指标监控与告警、模型版本管理与回滚策略。