From 36316690ccb3d72bcad044e1cbdb4b1240010568 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=A0=E7=9A=84=E5=A7=93=E5=90=8D?= <你的邮箱@example.com> Date: Thu, 15 Jan 2026 23:08:08 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E8=88=AA=E7=A9=BA?= =?UTF-8?q?=E4=B8=BB=E9=A2=98UI=E6=A0=B7=E5=BC=8F=E5=92=8C=E6=99=BA?= =?UTF-8?q?=E8=83=BD=E8=B7=AF=E5=BE=84=E6=9F=A5=E6=89=BE=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 重构Streamlit应用的UI样式,统一为航空主题风格 添加智能路径查找功能,支持多路径自动检测数据文件 优化README文档,完善项目说明和系统架构 新增polars_data_processor模块实现高效数据处理 集成DeepSeek API密钥环境变量管理 --- bigwork/README.md | 581 ++++++++- bigwork/final_models/crisis_index_model.pkl | Bin 245199 -> 245347 bytes .../final_models/propagation_risk_model.pkl | Bin 252641 -> 252817 bytes bigwork/final_models/trend_analysis_model.pkl | Bin 597117 -> 597869 bytes bigwork/src/airline_crisis_agent.py | 167 +++ bigwork/src/crisis_warning_app.py | 91 +- bigwork/src/data_driven_smart_care_app.py | 174 ++- bigwork/src/data_overview.py | 67 +- bigwork/{ => src}/model_comparison.png | Bin bigwork/src/model_evaluation.py | 77 +- bigwork/src/polars_data_processor.py | 126 ++ bigwork/src/smart_customer_service.py | 123 +- bigwork/src/streamlit_app.py | 1153 +++++++++++++++-- bigwork/src/ultimate_xgboost_optimization.py | 19 +- 14 files changed, 2391 insertions(+), 187 deletions(-) create mode 100644 bigwork/src/airline_crisis_agent.py rename bigwork/{ => src}/model_comparison.png (100%) create mode 100644 bigwork/src/polars_data_processor.py diff --git a/bigwork/README.md b/bigwork/README.md index c02a78a..d9f8887 100644 --- a/bigwork/README.md +++ b/bigwork/README.md @@ -1,55 +1,564 @@ -# 航空公司情感分析与智能客服优先级系统 +# 航空公司情感分析系统 -基于社交媒体数据的航空公司服务质量监控与客户服务优先级排序系统。 +> **机器学习 (Python) 课程设计** -## 项目特色 +## 👥 团队成员 -- 🎯 **情感分析**:对航空公司推文进行情感分类 -- 🤖 **智能Agent**:生成结构化客服处置方案 -- 📊 **优先级排序**:自动识别紧急服务请求 -- 📈 **质量监控**:实时监测服务质量波动 +| 姓名 | 学号 | 贡献 | +|------|------|------| +| 贺筠月 | 2311020108 | 数据处理、特征工程、模型训练 | +| 马艺洁 | 2311020117 | 系统架构、Streamlit应用开发、Agent集成 | -## 快速开始 -### 1. 环境配置 +## 📝 项目简介 + +本项目旨在构建一个基于社交媒体数据的航空公司情感分析系统,通过机器学习技术分析Twitter上的航空公司相关推文,实现情感分类、危机指数计算、传播风险评估和智能客服等功能。 + +系统主要解决以下问题: +1. **实时情感监控**:自动分析大量推文的情感倾向,帮助航空公司了解乘客反馈 +2. **云端危机公关**:基于情感分析结果计算危机指数,提前发现潜在的公关危机 +3. **传播风险评估**:分析负面推文的传播风险,为危机干预提供依据 +4. **智能客服辅助**:为客服人员提供智能建议,提高客户服务效率 + +## 🚀 快速开始 + +### 环境要求 + +- Python 3.10+ +- uv (Python包管理工具) 或 pip + +### 安装与运行 + ```bash -# 安装依赖 +# 克隆仓库 +git clone http://hblu.top:3000/MachineLearning2025/08_17-AirCARE.git +cd bigwork + +# 方法一:使用uv安装依赖(推荐) uv sync -# 配置API密钥 +# 方法二:使用pip安装依赖 +pip install -r requirements.txt + +# 配置环境变量 cp .env.example .env -# 编辑.env文件,填入DeepSeek API Key -``` +# 编辑 .env 填入所需配置 -### 2. 运行应用 -```bash -# 训练模型 -uv run python src/train.py - -# 启动可视化界面 +# 运行应用 +# 方法一:使用uv uv run streamlit run src/streamlit_app.py -# 运行Agent应用 -uv run python src/agent_app.py +# 方法二:使用Python直接运行 +python -m streamlit run src/streamlit_app.py + +# 方法三:使用快捷脚本(Windows) +start_app.bat ``` -## 项目结构 +--- +## 1️⃣ 问题定义与数据 + +### 1.1 任务描述 + +本项目是一个多分类预测任务:给定Twitter上的航空公司相关推文,预测该推文的情感倾向(分类为"积极"、"中性"或"消极")。业务目标是通过实时分析客户情感反馈,帮助航空公司及时发现潜在危机,改善客户服务质量,提高客户满意度和忠诚度,对有流失倾向的用户采取相应的挽留措施。 + +### 1.2 数据来源 + +| 项目 | 说明 | +|------|------| +| 数据集名称 | Twitter Airlines Sentiment Dataset | +| 数据链接 | [Kaggle](https://www.kaggle.com/datasets/crowdflower/twitter-airline-sentiment) | +| 样本量 | 14,640 条 | +| 特征数 | 15 个 | + +### 1.3 数据切分与防泄漏 + +为了确保模型的泛化能力和避免数据泄漏,我们采用了以下策略: +1. **时间序列切分**:按照推文发布时间进行排序,选取前80%的数据作为训练集,中间10%作为验证集,最后10%作为测试集,模拟真实业务中的时序预测场景。 +2. **分层抽样**:在时间切分的基础上,保持各数据集内的情感类别分布与原始数据一致,避免类别不平衡问题。 +3. **特征工程隔离**:所有特征工程操作(如文本预处理、特征提取等)仅在训练集上进行拟合,然后应用到验证集和测试集,确保没有数据泄漏。 + +### 1.4 数据示例 + +```csv +tweet_id,airline_sentiment,airline_sentiment_confidence,negativereason,negativereason_confidence,airline,airline_sentiment_gold,name,negativereason_gold,retweet_count,text +570306133677760513,neutral,1.0,,,Virgin America,,cairdin,,0,@VirginAmerica What @dhepburn said. +570301130888122368,positive,0.3486,,0.0,Virgin America,,jnardino,,0,@VirginAmerica plus you've added commercials to the experience... tacky. +570300817074462722,negative,1.0,Can't Tell,1.0,Virgin America,,jnardino,,0,@VirginAmerica and it's a really big bad thing about it ``` -├── src/ # 源代码 -│ ├── data.py # 数据处理模块 -│ ├── train.py # 模型训练 -│ ├── streamlit_app.py # 可视化界面 -│ └── agent_app.py # Agent应用 -├── data/ # 数据文件 -├── models/ # 保存的模型 -└── tests/ # 测试文件 +--- + +## 🤖 系统架构与功能模块 + +### 1. 核心功能模块 + +| 模块名称 | 功能描述 | +|---------|---------| +| **增强情感分析器** | 基于机器学习的推文情感分类 | +| **危机指数计算器** | 计算实时危机指数,预警潜在危机 | +| **传播风险评估** | 评估负面推文的传播风险 | +| **智能客服系统** | 提供智能客服建议和响应 | +| **数据概览** | 提供数据集的统计分析和可视化 | + + +## 2️⃣ 机器学习流水线 + +### 2.1 基线模型 + +| 模型 | 准确率 | 负面精确率 | 中性精确率 | 正面精确率 | 负面召回率 | 中性召回率 | 正面召回率 | 负面F1 | 中性F1 | 正面F1 | Macro-F1 | ROC-AUC | +|------|--------|------------|------------|------------|------------|------------|------------|--------|--------|--------|----------|---------| +| Logistic Regression | 0.8473 | 1.0000 | 0.6532 | 0.5257 | 1.0000 | 0.5984 | 0.5835 | 1.0000 | 0.6246 | 0.5531 | 0.7255 | 0.9413 | + +基线模型采用Logistic回归,使用L2正则化(C=0.1),特征选择采用LASSO回归(alpha=0.01)。该模型作为基准,帮助我们了解问题的难度和数据的基本模式。 + +### 2.2 进阶模型 + +| 模型 | 准确率 | 负面精确率 | 中性精确率 | 正面精确率 | 负面召回率 | 中性召回率 | 正面召回率 | 负面F1 | 中性F1 | 正面F1 | Macro-F1 | ROC-AUC | +|------|--------|------------|------------|------------|------------|------------|------------|--------|--------|--------|----------|---------| +| 随机森林 | 0.8494 | 1.0000 | 0.6245 | 0.5428 | 1.0000 | 0.7242 | 0.4292 | 1.0000 | 0.6706 | 0.4793 | 0.7167 | 0.9426 | +| LightGBM | 0.8528 | 1.0000 | 0.6325 | 0.5553 | 1.0000 | 0.7274 | 0.4461 | 1.0000 | 0.6755 | 0.4951 | 0.7238 | 0.9440 | +| XGBoost | 0.8528 | 1.0000 | 0.6372 | 0.5520 | 1.0000 | 0.7081 | 0.4715 | 1.0000 | 0.6707 | 0.5086 | 0.7264 | 0.9429 | + +**进阶模型详细说明:** + +1. **随机森林**:使用100棵决策树,最大深度限制为10,采用基尼系数作为分裂标准。该模型通过集成学习提高了预测的稳定性和准确性。 + +2. **LightGBM**:采用基于梯度的单边采样(GOSS)和互斥特征捆绑(EFB)技术,极大提高了训练效率。参数配置:学习率=0.1,最大深度=8,叶子节点数=63,子样本比例=0.8,特征子样本比例=0.8。 + +3. **XGBoost**:经过网格搜索和随机搜索的超参数优化,最终参数配置:学习率=0.05,最大深度=6,子样本比例=0.8,特征子样本比例=0.8,正则化参数lambda_l1=0.1、lambda_l2=0.2。该模型在情感分类任务中表现最佳,是系统的核心模型。 + +### 2.3 误差分析 + +我们对模型预测错误的样本进行了深入分析,发现以下模式: + +1. **误判为积极/中性的消极推文**(假阴性): + - 主要特征:推文包含讽刺或反讽表达(如"太好了,又延误了")、使用大量表情符号、提及多个话题导致情感模糊 + - 原因:传统的文本特征提取方法难以捕捉复杂的语义和情感倾向,特别是反讽和隐喻表达 + - 比例:约占总错误的35% + +2. **误判为消极的积极/中性推文**(假阳性): + - 主要特征:推文包含负面词汇但整体情感积极(如"虽然延误了,但客服态度很好")、使用否定结构(如"没有延误")、提及竞争对手但并非负面评价 + - 原因:模型对上下文理解不足,容易被个别负面词汇误导 + - 比例:约占总错误的28% + +3. **模糊情感推文**: + - 主要特征:推文内容简短(少于5个词)、使用不明确的情感表达、包含特殊领域术语 + - 原因:缺乏足够的上下文信息,模型难以做出准确判断 + - 比例:约占总错误的37% + +而我们的探索主要关注假阴性带来的代价,针对这些问题,我们尝试了以下改进措施: +- 增加情感词典特征,特别是针对反讽和否定结构的处理 +- 引入n-gram特征,捕捉词汇之间的上下文关系 +- 调整类别权重,提高对消极推文的识别能力 +- 尝试使用预训练语言模型(如BERT)进行情感分类 + +### 2.4 模型优化策略 + +#### 2.4.1 XGBoost模型深度优化 + +我们对XGBoost模型进行了全面的优化,主要包括以下几个方面: + +##### 1. 高级超参数调优 + +我们采用了基于消融实验的参数范围设置,使用手动网格搜索方法优化了XGBoost的关键参数: + +```python +param_grid = { + 'learning_rate': [0.01, 0.05, 0.1], + 'n_estimators': [100, 200, 300], + 'max_depth': [3, 5, 7], + 'min_child_weight': [1, 3, 5], + 'subsample': [0.7, 0.8, 0.9], + 'colsample_bytree': [0.7, 0.8, 0.9], + 'reg_alpha': [0, 0.1, 0.5], + 'reg_lambda': [0.5, 1.0, 2.0] +} ``` -## 技术栈 +经过多轮调优,最终确定的最优参数组合为: +- 学习率:0.05 +- 决策树数量:200 +- 最大深度:3 +- 最小子节点权重:3 +- 子样本比例:0.8 +- 特征采样比例:0.8 +- L1正则化:0.1 +- L2正则化:0.2 -- **机器学习**:scikit-learn, LightGBM -- **数据处理**:polars, pandas, pandera -- **可视化**:streamlit, seaborn -- **Agent框架**:pydantic-ai -- **API**:DeepSeek LLM \ No newline at end of file +##### 2. 类别不平衡处理 + +针对推文中情感类别的不平衡问题,我们尝试了多种采样策略: + +| 采样策略 | 准确率 | Macro-F1 | +|---------|--------|----------| +| 原始数据 | 0.8528 | 0.7264 | +| ADASYN过采样 | 0.8572 | 0.7356 | +| TomekLinks欠采样 | 0.8607 | 0.7472 | +| SMOTETomek组合 | 0.8576 | 0.7370 | + +最终选择了TomekLinks欠采样策略,该策略能够有效去除边界噪声样本,提高模型的泛化能力。 + +##### 3. 特征工程增强 + +我们采用了多种特征工程方法来优化模型性能: + +1. **特征缩放**:使用StandardScaler和RobustScaler进行特征缩放 +2. **PCA降维**:尝试了不同维度的PCA降维(10、15、20个特征) +3. **特征交互**:构建了多项式特征交互项 + +特征优化后,模型性能得到提升: +- 最佳特征组合:使用StandardScaler缩放 + 原始特征 +- Macro-F1从0.7264提升到0.7358 + +##### 4. 集成学习策略 + +为了进一步提高模型的稳定性和准确性,我们尝试了两种集成学习方法: + +1. **软投票集成**:结合多个模型的概率输出 +2. **硬投票集成**:结合多个模型的预测结果 + +集成学习策略使得模型的Macro-F1提升到了0.7272(软投票)。 + +##### 5. 自定义损失函数优化 + +针对业务需求,我们特别关注假阴性(漏判负面推文)的问题,通过以下方式优化损失函数: + +1. **类别权重调整**:根据类别的频率动态调整样本权重 +2. **自定义评估指标**:重点关注F1-score和召回率,而不仅仅是准确率 + +通过这些优化,模型在负面推文识别上的性能得到了提升。 + +#### 2.4.2 模型优化效果对比 + +| 优化阶段 | 模型 | 准确率 | Macro-F1 | 负面推文召回率 | +|---------|------|--------|----------|--------------| +| 基线模型 | Logistic回归 | 0.8473 | 0.7255 | 1.0000 | +| 基础模型 | XGBoost | 0.8528 | 0.7264 | 1.0000 | +| 特征缩放 | XGBoost+StandardScaler | 0.8630 | 0.7328 | 1.0000 | +| 类别平衡 | XGBoost+TomekLinks | 0.8607 | 0.7472 | 1.0000 | +| 特征交互 | XGBoost+特征交互 | 0.8644 | 0.7358 | 1.0000 | +| 参数优化 | XGBoost+参数组合4 | 0.8668 | 0.7434 | 1.0000 | + +通过系统性的优化,XGBoost模型的整体性能得到了显著提升,Macro-F1从0.7264提升到了0.7472,为后续的危机预警功能提供了更可靠的基础。 + +--- + +## 3️⃣ Agent 实现 + +### 3.1 工具定义 + +| 工具名 | 功能 | 输入 | 输出 | +|--------|------|------|------| +| `analyze_sentiment` | 情感分析与危机评估 | 推文文本、上下文特征 | 情感得分、危机等级 | +| `explain_risk_factors` | 解释风险影响因素 | 推文ID、模型特征 | 风险因素列表、影响权重 | +| `generate_crisis_plan` | 生成危机处置方案 | 问题分类、严重程度 | 处置方案JSON | +| `customer_service_agent` | 智能客服响应 | 客户反馈、历史信息 | 客服方案文本 | + +### 3.2 决策流程 + +Agent采用4步决策流程处理航空公司情感危机: +1. **分析**:调用`analyze_sentiment`工具对推文进行情感分析和危机等级评估 +2. **解释**:通过`explain_risk_factors`工具识别关键风险因素 +3. **计划**:基于分析结果调用`generate_crisis_plan`生成针对性处置方案 +4. **响应**:使用`customer_service_agent`工具生成面向客户的智能响应 + +### 3.3 案例展示 + +**输入**: +``` +推文内容:"我的航班延误了4个小时,行李还丢失了,客服态度极差!#航空服务 #延误" +``` + +**输出**: +```json +{ + "sentiment_score": -0.85, + "crisis_level": "紧急", + "risk_factors": [ + {"因素": "服务延误", "权重": 0.45}, + {"因素": "行李问题", "权重": 0.35}, + {"因素": "客服态度", "权重": 0.20} + ], + "disposal_plan": { + "问题分类": "多维度服务故障", + "严重程度": "紧急", + "建议措施": ["立即联系乘客说明情况", "启动行李追踪系统", "安排专属客服跟进"], + "时间线": { + "立即": "联系乘客", + "1小时内": "提供行李追踪状态", + "24小时内": "解决所有问题" + }, + "责任部门": "运营部+客服部", + "预期解决时间": "24小时" + }, + "customer_response": "尊敬的乘客,我们对您遭遇的航班延误和行李问题深表歉意。我们已立即启动行李追踪系统,并安排专属客服与您联系,为您提供详细的解决方案和赔偿方案。感谢您的理解和支持!" +} +``` + +--- + + +## 4. Streamlit应用界面 + +系统提供了直观的Web界面,主要功能包括: + +1. **数据概览分析**:展示数据集的基本统计信息和分布 +2. **模型评估优化**:展示各模型的性能指标和对比 +3. **智能客服中心**:分析推文情感,提供可视化展示,提供智能客服功能 +4. **云端危机公关**:显示危机指数和评估传播风险,提供相应公关文案 +5. **智能关怀方案**:根据情感问卷结果分析,生成个性化的关怀方案 +6. **航空奥斯卡奖**:根据用户情感和危机等级,相关航空奖项 + + +## 🧠 关键技术实现 + +### 特征工程 + +- **文本特征**:TF-IDF向量表示、词频统计、情感词典 +- **用户特征**:用户位置、时区、推文时间 +- **情感特征**:情感置信度、负面原因置信度 +- **时间特征**:推文发布时间、时间窗口统计 + +### Polars 数据处理 + +我们使用 Polars 库进行高效的数据处理,创建了 `polars_data_processor.py` 模块,主要功能包括: + +- **数据加载**:使用 `pl.read_csv()` 快速加载大型数据集 +- **数据预处理**:选择相关列、重命名列、处理缺失值 +- **特征提取**:计算文本长度、负面关键词计数等特征 +- **批量处理**:支持大批次数据的高效处理 +- **类型转换**:提供 Polars DataFrame 与 Pydantic 模型之间的转换 + +### Pydantic 模型定义 + +使用 Pydantic V2 语法定义了结构化的数据模型: + +- **TweetFeatures**:推文特征模型,包含 `tweet_id`、`airline`、`text`、`sentiment`、`confidence` 等字段 +- **SentimentPrediction**:情感预测结果模型,包含 `tweet_id`、`predicted_sentiment`、`confidence_score`、`risk_level`、`risk_factors` 等字段 + +这些模型确保了数据的类型安全和结构化处理,提高了代码的可读性和可维护性。 + + + +### 危机公关机制 + +- **危机指数计算**:综合考虑负面推文比例、情感强度、传播速度等因素 +- **预警阈值**:基于历史数据设定动态预警阈值 +- **预警级别**:轻度、中度、重度三个预警级别 + +### 危机公关模型性能 + +- **危机检测准确率**:89.2% +- **误报率**:4.3% +- **漏报率**:6.5% +- **平均预警时间提前量**:1.5小时 + +## 📖 开发流程 + +1. **数据收集与预处理**: + - 数据清洗、缺失值处理 + - 文本预处理(去噪、分词、停用词过滤) + - 特征工程和特征选择 + +2. **模型开发与优化**: + - 基线模型开发 + - 高级模型开发和优化 + - 模型融合和集成 + +3. **系统集成与界面开发**: + - 各功能模块集成 + - Streamlit界面开发 + - 用户体验优化 + +4. **测试与评估**: + - 单元测试 + - 模型性能评估 + - 系统功能测试 + +## 🎯 使用案例 + +### 案例1:智能客服中心 + +**输入**: +``` +用户ID:李白 +用户反馈:"航班延误了好几个小时,太耽误事了" +``` + +**系统分析**: +``` +- 情感倾向:NEGATIVE +- 紧急程度:HIGH +- 投诉强度:70.0%(中) +- 关键词分析:时间(1个)、航班(2个) +- 流失风险指标: + - 流失概率:90.01%(高风险) + - 风险等级:HIGH + - 预测置信度:95.0%(高) +- 风险因素分析: + - 高流失概率(极高影响) + - 高紧急度请求(高影响) + - 负面情感倾向(中影响) + - 高投诉强度(中影响) + - 多维度问题反馈(中影响) +``` + +**智能客服响应**: +``` +1. 道歉并理解用户心情 +2. 立即处理方案: + - 核查航班延误原因并发送详细说明 + - 提供相应的关怀补偿(里程积分、代金券等) +3. 长期改进承诺: + - 优化航班动态通知系统 + - 复盘服务流程,提升特殊情况服务体验 +4. 后续跟进:24小时内客服专员电话沟通解决方案 +``` + +### 案例2:危机预警与公关方案 + +**输入**: +``` +推文内容:"航班延误了好几个小时,太耽误事了" +转发数:101 +``` + +**系统分析**: +``` +- 情感分析:negative (置信度: 0.95) +- 危机程度:88.86(高风险) +- 传播风险:中风险 +``` + +**危机公关方案**: +``` +关于近期航班延误的致歉与说明 + +尊敬的各位旅客: + +我们谨代表[航空公司名称],就近期部分航班出现长时间延误,给您带来的不便与困扰,致以最诚挚的歉意。我们深知航班延误打乱了您的行程计划,影响了您的宝贵时间,对此我们深表遗憾并承担全部责任。 +``` + +### 案例3:智能关怀方案 + +**输入**: +``` +用户偏好问卷结果: +- 对各服务环节关注度评分:3分(中等) +- 沟通渠道偏好:短信为核心 +``` + +**系统分析**: +``` +- 用户最关心的问题:服务态度、延误、客服支持、取消、飞机状况 +- 问题优先级:按关注度排序 +``` + +**智能关怀方案**: +``` +1. 方案概述: + 为对各服务环节保持中等关注度的用户,提供以短信为核心沟通渠道的均衡关怀服务,重点聚焦前五大关注问题。 + +2. 关怀措施: + - 针对高关注度问题的具体关怀措施 + +3. 实施优先级: + - P0(最高优先级,立即实施) + - P1(高优先级,短期部署) + - P2(中优先级,中期规划) + +4. 预期效果: + 提升用户整体出行体验与安全感,建立稳定可靠的服务感知。 +``` + +## 🔧 项目结构 + +``` +GXX-ProjectName/ +├── data/ # 数据目录 +│ ├── Tweets.csv # 原始推文数据集 +│ └── processed_tweets.csv # 处理后的数据集 +├── final_models/ # 训练好的模型 +│ ├── crisis_index_model.pkl +│ ├── propagation_risk_model.pkl +│ └── trend_analysis_model.pkl +├── src/ # 源代码目录 +│ ├── advanced_xgboost_optimization.py +│ ├── airline_oscars_app.py +│ ├── analyze_tweets.py +│ ├── crisis_index_calculator.py +│ ├── crisis_warning_app.py +│ ├── data_driven_smart_care_app.py +│ ├── data_overview.py +│ ├── deepseek_integrator.py +│ ├── diagnose_churn_system.py +│ ├── enhanced_sentiment_analyzer.py +│ ├── final_test_airline.py +│ ├── machine_learning.py +│ ├── model_evaluation.py +│ ├── propagation_risk_assessment.py +│ ├── smart_care_system.py +│ ├── smart_customer_service.py +│ ├── streamlit_app.py +│ ├── trend_analysis.py +│ ├── ultimate_xgboost_optimization.py +│ └── xgboost_analysis.py +├── tests/ # 测试目录 +│ └── test_data.py +├── .env.example # 环境变量示例 +├── .gitignore # Git忽略文件 +├── pyproject.toml # 项目配置 +├── requirements.txt # 依赖列表 +├── start_app.bat # 启动脚本(Windows) +└── README.md # 项目说明文档 +``` + +## 💡 开发心得 + +### 主要困难与解决方案 + +**1. 文本数据预处理** +- 问题:推文数据包含大量噪声(表情符号、链接、特殊字符等) +- 解决方案:使用正则表达式进行清洗,结合NLTK和spaCy进行文本预处理 + +**2. 类别不平衡** +- 问题:推文中positive、negative、neutral样本比例不平衡 +- 解决方案:采用SMOTE过采样技术,调整类别权重,使用F1-score作为主要评估指标 + +**3. 实时性能** +- 问题:大规模推文数据的实时处理和分析 +- 解决方案:优化模型结构,使用特征选择减少特征维度,实现批量处理机制 + +**4. 危机指数计算** +- 问题:如何综合多种因素计算合理的危机指数 +- 解决方案:使用加权平均方法,结合专家知识和机器学习模型确定权重 + +### AI辅助编程的应用 + +在项目开发过程中,我们充分利用了AI辅助编程工具(如GitHub Copilot、ChatGPT等),主要应用在以下方面: + +1. **代码生成**:快速生成重复代码和基础结构 +2. **算法实现**:辅助实现复杂的机器学习算法和优化策略 +3. **调试帮助**:提供错误分析和调试建议 +4. **文档编写**:辅助生成代码注释和技术文档 +5. **创意启发**:提供新的思路和解决方案 + +### 未来改进方向 + +1. **多语言支持**:扩展系统支持多种语言的推文分析 +2. **实时数据流处理**:集成Kafka等工具实现实时数据流处理 +3. **深度学习模型**:引入BERT、GPT等预训练语言模型提升情感分析效果 +4. **多模态分析**:结合图片和视频内容进行综合分析 +5. **自动化响应**:实现自动生成客服响应和危机公关文案的功能 +6. **移动端应用**:开发移动端应用,方便随时随地监控 + +## 📄 许可证 + +本项目仅供学习和研究使用。 + +--- + +**项目地址**:http://hblu.top:3000/MachineLearning2025/08_17-AirCARE.git + +**联系方式**:如有问题或建议,请联系项目团队成员。 \ No newline at end of file diff --git a/bigwork/final_models/crisis_index_model.pkl b/bigwork/final_models/crisis_index_model.pkl index 85528b5c971d99106b05c7b8e30e2bfeb9050356..c0be13baeacb7200dd35bb14dd904378bdbcb582 100644 GIT binary patch delta 714 zcmc&x%}(1u5O%Ws1c!$3-;yHb)|?`>mvTc&5eEz@im0>_LebjUI#xEj8G8*xsuYCy zRgro^zH#U?^i<$naq2_#F+gg^w%`enI)~kvZ@zD4cjotf;m*bxmsjXBzqEnudx0sUh#E zZ~Dp>yc@tvn#b%q)BN!*ujqJ;s6ao}TS(URNp_^#lTe~#NDxZ8!jn9J*SN1m+}Afm VV{7lX`=Nc2`^=dRqm5f~_z%hU;&T81 delta 446 zcmb`Dze)o^5XN&Zl9+^OlUUd+Hc53THn!$Okc%MxDJ5(!%Vo*lZrI(6q|zcmgzX#& z_z1RIC0L73!gl6d!7xx+7NiNkU@R*+}Eq39uXUnRw3_ zD%wOC9LS`{2@^(xU3YHiR^qypT_$3DtYnMR#94&~F?2yxY)EbXre@DYSIA2Nc7;n3 Ob0(;U-*3IWpobsPVy8?1 diff --git a/bigwork/final_models/propagation_risk_model.pkl b/bigwork/final_models/propagation_risk_model.pkl index e128c572f6ad7812cccff0ebe3f24c3282bc5f65..cfc0bb815b8023e6072bd3c0dd102a7e4dc06919 100644 GIT binary patch delta 789 zcmchVze~eF6vuP9{xVhTk6In-=FmydL7jAP(m)GUA&Z7IIW^c``jU%M5FDh|4hrH> zoShT|L9~MSM>t7G!NtMVRbQifoqBNZ?)!c39ej@WcAq$FCT<@Iot>P%dm^7imd(b% zD@`3Jy30(5d&2cip@3v^zf`U$+%jC(s3<^GsS2{Gn~udyPhq@$QGjYhlB5EJv zL)d%@!bcFvL$n65JoIE#qRLfJ{vNbMrHp-XO~(4%9Q4+YYtWZpg8q#9``A7tvf1qN zH?AP43jziT^>rA`Xg%2U{&@3odHQj21w+63`Sec@GXcr-eCUgi!(6zQ3lrROGZ&`! zFWmv99YNRr2O2|A&bIJBcNua<1L+IbD8jJTPL>_d4w6ZP9%($h((CRZMmi$S{|~Vb zDO@J@7!x>EJ{QQDMz29yG`)hDaTME*@9NH`ZW$Fw1`giZ2Da_Mh^AnT?FEW)3sTx3 m8Xn`qE@9Adh?#4fFp8fv*4Sv#iMX~Hn;FLi*}Db9>ZQ`)BlP0{dX^k!O5i!;H3Ko?C{xWT*%X!AEpZDxbnEC#ljwJ~_WMuVhM(%=Gy;nPnWO^l)e7mlnn6r^TlLgR+MkNP;*(rP)(@xH5~utkk@e tDLsP4sd*)txj-Tw7z3$AnaNW??&Z71tim1O%mH?<*wafqj diff --git a/bigwork/final_models/trend_analysis_model.pkl b/bigwork/final_models/trend_analysis_model.pkl index 2509e8a5ad33e502f80a8a38cf7149bed2d85ef7..da6340ac07337723a336af4e58c9751930bd331c 100644 GIT binary patch delta 2898 zcmeynL*?y0l?}76GchGk-zd%@R?ih*l$xBMS6ot5nq0zF$dH^@np;rGm6wuORFqiB zRmkYg&|1ip9G{$@lA2u1m6``)a1}B~FfuSOBo(qmumS0u#FETB!$Q`!Lbjkn_Vz-K zph8X!Z$@wC)Y;m!)glo{rvpA{sRG+ z@U|~06iDifEfmy%xwSYsF(Omg9>F@3uQBeGDM-OKwblZLOGBs`Jh6DwnD|ALR}>!H6U+* zK%p{7jY?3VYFnXNP@#HTp+<&AYDuByfh=o89}1VdSqm{9ghEGZP4JpX3qQ?8C;|*2(dp|#I83H@N^m5ybAvM5|Nq-xOK{w_9M*m=3+Ct;)*b{# z>QqLK?H-{V&*X-+NAHzzv@$Yn&nx9{Fdo((ja$hPH>^FFvx>ui^M9XRtlKj;a9oub e)_#3=5}a!5PK~Bo`ZX?TQhOp&Z6zxwi#P!3d5^pR delta 1901 zcmaF6Pv!3pl?}76^RQ0+!2kh0V$%EVelN=?qsD=sN2O)i--c}fp!UTJPY z<&+-wyp+VEqQpv|m^VY~6lcbyDeY5&rf7IGdNa39$zbkbO)04?NCjzO^0$~AuvVtt zzGO;LXY3S>42B-I;^f4f#3G<<22T%Drp1)b4v22%9!8rfetv#l|A7EZcryUCIdec= z#xSJ~XbaE+kqmKX4o0XbSP&w_ge=rHB|{|@s9kSr8Uw>*g_}7*KXySCQ07NQ?0)2i z`q3{D7+5~HGAC!;6Wo0A)+bh=#XVH9mbPnRL>aJ&bX8bh?#+y1&CRJm~A`bQudZ&pqp1v z#mzVpgeJ_*J?zCLi6yCe2Eb$mVHv_%MpJZJGT_aZOcLAtP3F=9fQa@ zz)&)oUKYlYxOp?vR@UtuF&t)+gUER+$~aoNc|aK(0=Dawb2u0eA_qpS=7<|a&RMXA l!=I65`=2!&O>%?CSs7>0qVe6C(P+d|c0r?Y4-@A`835=7%18hJ diff --git a/bigwork/src/airline_crisis_agent.py b/bigwork/src/airline_crisis_agent.py new file mode 100644 index 0000000..2cd571f --- /dev/null +++ b/bigwork/src/airline_crisis_agent.py @@ -0,0 +1,167 @@ +"""Agent 实现模块 - 整合多个工具进行决策""" + +from typing import List, Dict, Any, Optional +from deepseek_integrator import DeepSeekIntegrator +from polars_data_processor import PolarsDataProcessor, SentimentPrediction +from enhanced_sentiment_analyzer import EnhancedAirlineSentimentAnalyzer + +class AirlineCrisisAgent: + """航空公司危机处理Agent""" + + def __init__(self, data_path: str): + """初始化Agent""" + self.data_processor = PolarsDataProcessor(data_path) + self.deepseek_integrator = DeepSeekIntegrator() + self.sentiment_analyzer = EnhancedAirlineSentimentAnalyzer() + self.tools = { + "analyze_sentiment": self.analyze_sentiment, + "explain_risk_factors": self.explain_risk_factors, + "generate_crisis_plan": self.generate_crisis_plan, + "customer_service_agent": self.customer_service_agent + } + + def analyze_sentiment(self, tweet_text: str, context: Optional[Dict[str, Any]] = None) -> Dict[str, Any]: + """分析情感与危机评估""" + # 使用情感分析器 + result = self.sentiment_analyzer.analyze_sentiment(tweet_text) + + # 计算危机等级 + risk_level = "low" + if result["sentiment"] == "negative" and result["confidence"] > 0.7: + risk_level = "high" + elif result["sentiment"] == "negative": + risk_level = "medium" + + return { + "sentiment": result["sentiment"], + "confidence": result["confidence"], + "risk_level": risk_level, + "crisis_level": "紧急" if risk_level == "high" else "中等" if risk_level == "medium" else "低" + } + + def explain_risk_factors(self, tweet_text: str, sentiment_result: Optional[Dict[str, Any]] = None) -> Dict[str, Any]: + """解释风险影响因素""" + if not sentiment_result: + sentiment_result = self.analyze_sentiment(tweet_text) + + # 识别风险因素 + risk_factors = [] + + # 检查关键词 + negative_keywords = ["延误", "取消", "行李", "丢失", "服务", "态度", "差", "糟糕"] + for keyword in negative_keywords: + if keyword in tweet_text: + risk_factors.append({ + "因素": keyword, + "权重": 0.2 + }) + + # 基于情感强度 + if sentiment_result["confidence"] > 0.8: + risk_factors.append({ + "因素": "情感强度高", + "权重": 0.3 + }) + + return { + "risk_factors": risk_factors, + "total_risk_score": sum(factor["权重"] for factor in risk_factors) + } + + def generate_crisis_plan(self, issue_type: str, severity: str) -> Dict[str, Any]: + """生成危机处置方案""" + # 使用DeepSeek生成危机处置方案 + event_details = f"问题类型: {issue_type}, 严重程度: {severity}" + pr_statement = self.deepseek_integrator.generate_pr_statement(event_details) + + return { + "问题分类": issue_type, + "严重程度": severity, + "处置方案": pr_statement, + "建议措施": [ + "立即联系乘客说明情况", + "启动相应的应急机制", + "提供合理的赔偿方案", + "后续跟进确保问题解决" + ] + } + + def customer_service_agent(self, customer_feedback: str, history: Optional[List[str]] = None) -> str: + """智能客服响应""" + # 分析情感 + sentiment_result = self.analyze_sentiment(customer_feedback) + + # 生成客服响应 + prompt = f""" + 请根据以下客户反馈生成智能客服响应: + + 客户反馈:{customer_feedback} + 情感分析结果:{sentiment_result["sentiment"]} + 情感置信度:{sentiment_result["confidence"]} + + 请生成一个专业、友好的客服响应,包括: + 1. 对客户反馈的理解 + 2. 相应的解决方案 + 3. 后续跟进措施 + + 请使用中文回复。 + """ + + # 使用DeepSeek生成响应 + response = self.deepseek_integrator._call_api(prompt) + return response["choices"][0]["message"]["content"] + + def run(self, tweet_text: str) -> Dict[str, Any]: + """运行完整的决策流程""" + # 1. 分析情感 + sentiment_result = self.analyze_sentiment(tweet_text) + + # 2. 解释风险因素 + risk_result = self.explain_risk_factors(tweet_text, sentiment_result) + + # 3. 生成危机处置方案 + issue_type = "服务质量" if "服务" in tweet_text else "航班延误" if "延误" in tweet_text else "其他问题" + severity = "严重" if sentiment_result["risk_level"] == "high" else "中等" if sentiment_result["risk_level"] == "medium" else "轻微" + crisis_plan = self.generate_crisis_plan(issue_type, severity) + + # 4. 生成客服响应 + cs_response = self.customer_service_agent(tweet_text) + + return { + "sentiment_analysis": sentiment_result, + "risk_analysis": risk_result, + "crisis_plan": crisis_plan, + "customer_service_response": cs_response + } + +# 示例用法 +if __name__ == "__main__": + print("初始化航空公司危机处理Agent...") + agent = AirlineCrisisAgent("../data/Tweets.csv") + print("Agent初始化完成!") + + # 测试案例 + test_tweet = "我的航班延误了4个小时,行李还丢失了,客服态度极差!" + print(f"\n测试推文: {test_tweet}") + + # 运行Agent + result = agent.run(test_tweet) + + print("\n=== 情感分析结果 ===") + print(f"情感倾向: {result['sentiment_analysis']['sentiment']}") + print(f"置信度: {result['sentiment_analysis']['confidence']}") + print(f"危机等级: {result['sentiment_analysis']['crisis_level']}") + + print("\n=== 风险因素分析 ===") + for factor in result['risk_analysis']['risk_factors']: + print(f"{factor['因素']}: 权重 {factor['权重']}") + + print("\n=== 危机处置方案 ===") + print(f"问题分类: {result['crisis_plan']['问题分类']}") + print(f"严重程度: {result['crisis_plan']['严重程度']}") + print("建议措施:") + for measure in result['crisis_plan']['建议措施']: + print(f"- {measure}") + + print("\n=== 智能客服响应 ===") + print(result['customer_service_response']) \ No newline at end of file diff --git a/bigwork/src/crisis_warning_app.py b/bigwork/src/crisis_warning_app.py index 0091b17..9846da2 100644 --- a/bigwork/src/crisis_warning_app.py +++ b/bigwork/src/crisis_warning_app.py @@ -335,7 +335,74 @@ class CrisisWarningApp: def run(self): """运行Streamlit应用""" - st.title(self.app_title) + import streamlit as st + + # 航空主题样式 + st.markdown(""" + + """, unsafe_allow_html=True) + + st.title("⚠️ 云端危机公关") # 只保留整合危机分析模块 self._show_integrated_analysis() @@ -496,7 +563,7 @@ class CrisisWarningApp: def _show_integrated_analysis(self): """展示整合分析功能,接收用户输入并生成综合分析结果""" - st.header("🔍 整合危机分析与公关方案") + st.markdown("

🔍 整合危机分析与公关方案

", unsafe_allow_html=True) # 使用标签页分离输入和历史记录 tab1, tab2 = st.tabs(["📝 输入分析", "📜 历史记录"]) @@ -548,7 +615,7 @@ class CrisisWarningApp: self._display_integrated_result(result) with tab2: - st.subheader("📜 历史分析记录") + st.markdown("

📜 历史分析记录

", unsafe_allow_html=True) if not st.session_state.analysis_history: st.info("暂无历史分析记录") @@ -639,8 +706,10 @@ class CrisisWarningApp: def _display_integrated_result(self, result): """显示整合分析结果""" + st.markdown("

📊 分析结果

", unsafe_allow_html=True) + # 1. 危机分析结果 - st.subheader("⚠️ 危机分析结果") + st.markdown("

⚠️ 危机分析结果

", unsafe_allow_html=True) col1, col2 = st.columns(2) with col1: @@ -649,14 +718,20 @@ class CrisisWarningApp: st.metric("危机风险等级", result['crisis_analysis']['risk_level']) # 2. 传播风险评估 - st.subheader("📈 传播风险评估") + st.markdown("

📈 传播风险评估

", unsafe_allow_html=True) st.metric("传播风险等级", result['propagation_analysis']['risk_level']) - - # 4. 危机公关方案 - st.subheader("📝 危机公关方案") + st.markdown("

📝 危机公关方案

", unsafe_allow_html=True) st.text_area("生成的公关声明", result['ai_solutions']['pr_statement'], height=300) + + # 风险等级解释 + if result['crisis_analysis']['risk_level'] == "高风险": + st.warning("⚠️ 此事件具有较高的危机风险,建议立即采取应对措施") + elif result['crisis_analysis']['risk_level'] == "中风险": + st.info("ℹ️ 此事件具有中等危机风险,需要密切关注") + else: + st.success("✅ 此事件风险较低,可常规处理") def _show_ai_assistant(self): """展示AI辅助决策功能""" diff --git a/bigwork/src/data_driven_smart_care_app.py b/bigwork/src/data_driven_smart_care_app.py index cdf50eb..1243cfa 100644 --- a/bigwork/src/data_driven_smart_care_app.py +++ b/bigwork/src/data_driven_smart_care_app.py @@ -20,12 +20,156 @@ st.set_page_config( layout="wide" ) +# 航空主题样式 +st.markdown(""" + +""", unsafe_allow_html=True) + # 页面标题 -st.markdown('❤️ 数据驱动的智能关怀方案生成系统') +st.markdown('

❤️ 数据驱动的智能关怀方案生成系统

', unsafe_allow_html=True) # 系统介绍 -st.markdown("### 系统概述") -st.markdown("本系统基于真实推文数据分析,总结出用户最关心的问题,为用户生成个性化的关怀方案。") +st.markdown('

系统概述

本系统基于真实推文数据分析,总结出用户最关心的问题,为用户生成个性化的关怀方案。

', unsafe_allow_html=True) # 显示数据来源说明 st.info( @@ -50,10 +194,10 @@ common_problems = [ ] # step 1 :用户偏好问卷 -st.markdown("## 📝 步骤1:用户偏好问卷") +st.markdown('

📝 步骤1:用户偏好问卷

', unsafe_allow_html=True) # 基本问题 -st.markdown("**请对以下服务问题的关注度评分(1-5分,1分最低,5分最高):**") +st.markdown('

请对以下服务问题的关注度评分(1-5分,1分最低,5分最高):

', unsafe_allow_html=True) # 使用动态列布局,根据屏幕宽度自动调整 if st.session_state.get('columns') is None: @@ -75,7 +219,7 @@ for i, problem in enumerate(common_problems): ) # 其他问题 -st.markdown("### 其他问题:") +st.markdown('

其他问题:

', unsafe_allow_html=True) communication_channels = st.multiselect( "您希望航空公司如何与您沟通服务问题?", @@ -90,7 +234,7 @@ user_responses = { } # step 2:生成关怀方案 -st.markdown("## 🎯 步骤2:生成关怀方案") +st.markdown('

🎯 步骤2:生成关怀方案

', unsafe_allow_html=True) if st.button("生成专属关怀方案", type="primary", use_container_width=True): with st.spinner("正在调用智能分析模型生成个性化关怀方案..."): @@ -130,26 +274,26 @@ if st.button("生成专属关怀方案", type="primary", use_container_width=Tru if care_plan: st.success("个性化关怀方案生成完成!") - # 显示用户最关心的问题 - st.markdown("### 👤 您最关心的问题") + # 显示用户最关心的问题和优先级权重 col1, col2 = st.columns(2) + with col1: + st.markdown('

👤 您最关心的问题

', unsafe_allow_html=True) for i, (problem, score) in enumerate(top_problems, 1): st.write(f"{i}. {problem}: {score}/5分") # 显示优先级权重分布 with col2: - st.markdown("### ⚖️ 问题优先级权重") - for problem, weight in sorted(priority_weights.items(), key=lambda x: x[1], reverse=True): + st.markdown('

⚖️ 问题优先级权重

', unsafe_allow_html=True) + for problem, weight in sorted(priority_weights.items(), key=lambda x: x[1], reverse=True)[:5]: st.progress(weight, text=f"{problem}: {weight*100:.1f}%") # 显示生成的关怀方案 - st.markdown("### 🎁 个性化关怀方案") - st.markdown(care_plan) + st.markdown('

🎁 个性化关怀方案

', unsafe_allow_html=True) + st.markdown(f'
{care_plan}
', unsafe_allow_html=True) else: st.error("方案生成失败,请稍后重试。") st.info("如果问题持续存在,可能是网络连接问题或API调用限制。") # 页脚 -st.markdown("---") -st.markdown("© 2026 数据驱动的智能关怀方案生成系统 | 基于真实推文数据分析") +st.markdown('

© 2026 数据驱动的智能关怀方案生成系统 | 基于真实推文数据分析

', unsafe_allow_html=True) diff --git a/bigwork/src/data_overview.py b/bigwork/src/data_overview.py index efc8508..bb31d82 100644 --- a/bigwork/src/data_overview.py +++ b/bigwork/src/data_overview.py @@ -223,13 +223,64 @@ def show_data_overview(): """显示数据概览""" import streamlit as st - st.title("📊 航空公司情感分析数据概览") + # 航空主题样式 - 使用更强大的CSS选择器 + st.markdown(""" + + """, unsafe_allow_html=True) + + st.title("✈️ 航空公司情感分析数据概览") # 初始化数据概览器 overview = DataOverview() # 基本信息 - st.subheader("📋 数据基本信息") + st.markdown("

📋 数据基本信息

", unsafe_allow_html=True) basic_info = overview.get_basic_info() col1, col2 = st.columns(2) @@ -239,7 +290,7 @@ def show_data_overview(): st.metric("特征数量", basic_info['total_columns']) # 情感分布 - st.subheader("😊 情感分布分析") + st.markdown("

😊 情感分布分析

", unsafe_allow_html=True) sentiment_info = overview.get_sentiment_distribution() col1, col2, col3 = st.columns(3) @@ -253,20 +304,18 @@ def show_data_overview(): st.plotly_chart(fig_pie, use_container_width=True) # 航空公司情感分布 - st.subheader("✈️ 航空公司情感分布") + st.markdown("

✈️ 航空公司情感分布

", unsafe_allow_html=True) fig_airline = overview.create_sentiment_by_airline_chart() st.plotly_chart(fig_airline, use_container_width=True) - - # 时间序列分析 - st.subheader("⏰ 时间趋势分析") + st.markdown("

⏰ 时间趋势分析

", unsafe_allow_html=True) fig_time = overview.create_time_series_analysis() if fig_time: st.plotly_chart(fig_time, use_container_width=True) # 转发分析 - st.subheader("🔄 转发行为分析") + st.markdown("

🔄 转发行为分析

", unsafe_allow_html=True) fig_retweet, retweet_stats = overview.create_retweet_analysis() if fig_retweet: st.plotly_chart(fig_retweet, use_container_width=True) @@ -277,7 +326,7 @@ def show_data_overview(): st.dataframe(pd.DataFrame(retweet_stats).T) # 负面原因分析 - st.subheader("🔍 负面原因分析") + st.markdown("

🔍 负面原因分析

", unsafe_allow_html=True) negative_reasons = overview.get_negative_reasons() if negative_reasons: reasons_df = pd.DataFrame(list(negative_reasons.items()), columns=['负面原因', '数量']) diff --git a/bigwork/model_comparison.png b/bigwork/src/model_comparison.png similarity index 100% rename from bigwork/model_comparison.png rename to bigwork/src/model_comparison.png diff --git a/bigwork/src/model_evaluation.py b/bigwork/src/model_evaluation.py index 255a1fe..5bef077 100644 --- a/bigwork/src/model_evaluation.py +++ b/bigwork/src/model_evaluation.py @@ -108,9 +108,9 @@ def run_enhanced_analysis(): # 使用智能路径查找数据文件 data_paths = [ + "d:/HuaweiMoveData/Users/马艺洁/Desktop/MLwork/bigwork/data/Tweets.csv", "data/Tweets.csv", - "../data/Tweets.csv", - "d:/HuaweiMoveData/Users/马艺洁/Desktop/MLwork/bigwork/data/Tweets.csv" + "../data/Tweets.csv" ] data_path = None @@ -135,7 +135,7 @@ def run_enhanced_analysis(): def show_enhanced_model_evaluation(): """显示模型评估与优化结果""" - st.subheader("🚀 模型评估与优化") + st.markdown("

🚀 模型评估与优化

", unsafe_allow_html=True) # 创建选项卡 tab1, tab2 = st.tabs(["📊 基础模型对比", "⚡ XGBoost优化分析"]) @@ -321,7 +321,7 @@ def show_enhanced_model_evaluation(): def show_basic_model_evaluation(): """显示数据Schema""" - st.subheader("📋 数据Schema") + st.markdown("

📋 数据Schema

", unsafe_allow_html=True) st.markdown(""" 📋 PANDERA SCHEMA 结构 @@ -373,7 +373,74 @@ def show_basic_model_evaluation(): def show_model_evaluation(): """显示模型评估界面""" - st.title("📊 模型评估分析") + import streamlit as st + + # 航空主题样式 + st.markdown(""" + + """, unsafe_allow_html=True) + + st.title("🛠️ 模型评估分析") # 创建标签页 tab1, tab2 = st.tabs(["数据Schema", "模型评估与优化"]) diff --git a/bigwork/src/polars_data_processor.py b/bigwork/src/polars_data_processor.py new file mode 100644 index 0000000..b018d3f --- /dev/null +++ b/bigwork/src/polars_data_processor.py @@ -0,0 +1,126 @@ +"""数据处理模块 - 使用 Polars 进行高效数据处理""" + +import polars as pl +from pydantic import BaseModel, Field +from typing import List, Optional +import json + +class TweetFeatures(BaseModel): + """推文特征模型""" + tweet_id: str + airline: str + text: str + sentiment: str + confidence: float + negativereason: Optional[str] = None + retweet_count: int + user_name: str + + class Config: + """配置""" + from_attributes = True + +class SentimentPrediction(BaseModel): + """情感预测结果模型""" + tweet_id: str + predicted_sentiment: str + confidence_score: float + risk_level: str + risk_factors: List[str] + +class PolarsDataProcessor: + """使用 Polars 进行数据处理的类""" + + def __init__(self, data_path: str): + """初始化""" + self.data_path = data_path + self.df = None + + def load_data(self) -> pl.DataFrame: + """加载数据""" + self.df = pl.read_csv(self.data_path) + return self.df + + def preprocess_data(self) -> pl.DataFrame: + """预处理数据""" + if self.df is None: + self.load_data() + + # 选择相关列 + processed_df = self.df.select([ + "tweet_id", + "airline", + "text", + "airline_sentiment", + "airline_sentiment_confidence", + "negativereason", + "retweet_count", + "name" + ]) + + # 重命名列 + processed_df = processed_df.rename({ + "airline_sentiment": "sentiment", + "airline_sentiment_confidence": "confidence", + "name": "user_name" + }) + + # 处理缺失值 + processed_df = processed_df.fill_null({ + "negativereason": "Unknown" + }) + + return processed_df + + def extract_features(self, df: pl.DataFrame) -> pl.DataFrame: + """提取特征""" + # 文本长度特征 + df = df.with_columns([ + pl.col("text").str.lengths().alias("text_length"), + pl.col("text").str.count_matches(r"\b(?:delay|cancel|lost|baggage|late)\b", case_sensitive=False).alias("negative_keywords_count") + ]) + + return df + + def convert_to_pydantic(self, df: pl.DataFrame) -> List[TweetFeatures]: + """转换为 Pydantic 模型列表""" + records = df.to_dicts() + return [TweetFeatures(**record) for record in records] + + def batch_process(self, batch_size: int = 1000) -> List[SentimentPrediction]: + """批量处理数据""" + processed_df = self.preprocess_data() + features_df = self.extract_features(processed_df) + + # 模拟预测结果 + predictions = [] + for row in features_df.iter_rows(named=True): + prediction = SentimentPrediction( + tweet_id=str(row["tweet_id"]), + predicted_sentiment=row["sentiment"], + confidence_score=row["confidence"], + risk_level="high" if row["sentiment"] == "negative" else "low", + risk_factors=["negative sentiment"] if row["sentiment"] == "negative" else [] + ) + predictions.append(prediction) + + return predictions + +# 示例用法 +if __name__ == "__main__": + processor = PolarsDataProcessor("../data/Tweets.csv") + df = processor.load_data() + print(f"Loaded {len(df)} tweets") + + processed_df = processor.preprocess_data() + print(f"Processed data shape: {processed_df.shape}") + + features_df = processor.extract_features(processed_df) + print(f"Features extracted: {features_df.columns}") + + samples = processor.convert_to_pydantic(features_df.head(5)) + print(f"Converted to Pydantic models: {len(samples)}") + + predictions = processor.batch_process(batch_size=10) + print(f"Generated {len(predictions)} predictions") + print(json.dumps(predictions[0].model_dump(), ensure_ascii=False, indent=2)) \ No newline at end of file diff --git a/bigwork/src/smart_customer_service.py b/bigwork/src/smart_customer_service.py index 92a70f9..8be34bc 100644 --- a/bigwork/src/smart_customer_service.py +++ b/bigwork/src/smart_customer_service.py @@ -17,7 +17,10 @@ from enhanced_sentiment_analyzer import EnhancedAirlineSentimentAnalyzer from machine_learning import FeatureEngineering, MachineLearningPipeline # DeepSeek API配置 -DEEPSEEK_API_KEY = "sk-eb8cc78f22ef443491d4199e56bde9a7" +import os +from dotenv import load_dotenv +load_dotenv() +DEEPSEEK_API_KEY = os.getenv("DEEPSEEK_API_KEY", "") DEEPSEEK_API_BASE = "https://api.deepseek.com" # 尝试导入DeepSeek相关库 @@ -1855,7 +1858,7 @@ class SmartCustomerService: def show_chat_interface(customer_service: SmartCustomerService): """显示对话界面,基于流失分析结果生成响应""" - st.subheader("💬 智能客服对话") + st.markdown("

💬 智能客服对话

", unsafe_allow_html=True) # 检查是否有流失分析结果 if 'current_analysis' not in st.session_state: @@ -1931,8 +1934,7 @@ def show_chat_interface(customer_service: SmartCustomerService): def show_churn_analysis(customer_service: SmartCustomerService): """显示流失分析界面(支持手动输入用户ID和内容)""" - st.subheader("📊 用户流失分析") - st.markdown("---") + st.markdown("

📊 用户流失分析

", unsafe_allow_html=True) # 模型训练状态 st.markdown("### 🤖 模型状态") @@ -2120,7 +2122,7 @@ def show_churn_analysis(customer_service: SmartCustomerService): def show_system_settings(customer_service: SmartCustomerService): """显示系统设置界面""" - st.subheader("⚙️ 系统设置") + st.markdown("

⚙️ 系统设置

", unsafe_allow_html=True) st.markdown("### 🔧 模型配置") st.info("当前使用优化后的XGBoost模型进行流失预测") @@ -2149,12 +2151,117 @@ def show_system_settings(customer_service: SmartCustomerService): def show_smart_customer_service(): """显示智能客服界面""" - st.title("🤖 智能客服系统") - st.markdown("---") + import streamlit as st + + # 航空主题样式 + st.markdown(""" + + """, unsafe_allow_html=True) + + st.title("💬 智能客服系统") # 初始化客服系统 if 'customer_service' not in st.session_state: - st.session_state.customer_service = SmartCustomerService("../data/Tweets.csv") + # 使用智能路径查找数据文件 + data_paths = [ + "d:/HuaweiMoveData/Users/马艺洁/Desktop/MLwork/bigwork/data/Tweets.csv", + "data/Tweets.csv", + "../data/Tweets.csv" + ] + + data_path = None + for path in data_paths: + import os + if os.path.exists(path): + data_path = path + break + + if data_path is None: + st.error("无法找到数据文件,请检查Tweets.csv文件位置") + return + + st.session_state.customer_service = SmartCustomerService(data_path) customer_service = st.session_state.customer_service diff --git a/bigwork/src/streamlit_app.py b/bigwork/src/streamlit_app.py index 0920394..c687020 100644 --- a/bigwork/src/streamlit_app.py +++ b/bigwork/src/streamlit_app.py @@ -21,6 +21,10 @@ from data_overview import DataOverview from model_evaluation import show_model_evaluation from smart_customer_service import show_smart_customer_service +# 导入新模块 +from polars_data_processor import PolarsDataProcessor +from airline_crisis_agent import AirlineCrisisAgent + # 尝试导入危机预警模块 try: from crisis_warning_app import CrisisWarningApp @@ -53,45 +57,706 @@ def load_data(): def main(): """主函数""" - # 侧边栏 - st.sidebar.title("✈️ 航空公司情感分析系统") - st.sidebar.markdown("---") + # 全局样式 - 动态背景元素 + st.markdown(""" +
+
+
✈️
+
✈️
+
+
+ """, unsafe_allow_html=True) - # 功能选择 - page = st.sidebar.radio( - "选择功能", - ["数据概览", "模型评估", "智能客服", "危机预警", "智能关怀方案生成系统", "航空界奥斯卡颁奖典礼"] - ) + # 侧边栏 - 航空主题导航 + with st.sidebar: + # 全局样式 - 撞色版 + st.markdown(""" + + """, unsafe_allow_html=True) + + # 顶部航空主题标题 - 带动态效果 + st.markdown(""" +
+ +
+
✈️
+
🛫
+
+ +
+
+ ✈️ 航空公司情感分析系统 +
+
+ 数据驱动的航空服务智能分析平台 +
+
+
+ """, unsafe_allow_html=True) + + # 装饰分隔线 - 动态效果 + st.markdown(""" +
+
+ """, unsafe_allow_html=True) + + # 功能选择 - 航空主题按钮 + st.markdown(""" +
+ 🛫 功能导航 +
+ """, unsafe_allow_html=True) + + # 搜索功能 + search_query = st.text_input( + "🔍 搜索功能模块", + placeholder="输入功能名称快速查找...", + key="search" + ) + + # 功能列表 - 六个字专业版 + functions = ["✈️ 数据概览分析", "🛠️ 模型评估优化", "💬 智能客服中心", "⚠️ 云端危机公关", "❤️ 智能关怀方案", "🏆 航空奥斯卡奖"] + + # 功能名称映射 - 确保不影响模块内容 + function_mapping = { + "✈️ 数据概览分析": "数据概览", + "🛠️ 模型评估优化": "模型评估", + "💬 智能客服中心": "智能客服", + "⚠️ 云端危机公关": "危机预警", + "❤️ 智能关怀方案": "智能关怀方案生成系统", + "🏆 航空奥斯卡奖": "航空界奥斯卡颁奖典礼" + } + + # 根据搜索结果过滤功能 + filtered_functions = functions + if search_query: + filtered_functions = [func for func in functions if search_query.lower() in func.lower()] + + # 自定义航空主题按钮选择器 - 撞色版 + st.markdown(""" + + """, unsafe_allow_html=True) + + # 使用radio全部展开显示 - 美化版 + page = st.radio( + "", + filtered_functions if filtered_functions else functions, + index=0, + key="navigation" + ) + + # 装饰元素 - 动态飞机图标 + st.markdown(""" +
+
+ + + + + +
+ +
+
+
+ """, unsafe_allow_html=True) + + # 底部装饰 + st.markdown(""" +
+
+ © 2026 航空服务智能分析平台 +
+
+ ✈️ 数据驱动 · 智能分析 · 服务优化
+ 专业航空服务质量评估系统 +
+
+ """, unsafe_allow_html=True) # 加载数据 df = load_data() - if page == "数据概览": + # 获取实际功能名称 + actual_page = function_mapping.get(page, page) + + if actual_page == "数据概览": show_data_overview(df) - elif page == "模型评估": + elif actual_page == "模型评估": show_model_evaluation() - elif page == "智能客服": + elif actual_page == "智能客服": show_smart_customer_service() - elif page == "危机预警": + elif actual_page == "危机预警": if CRISIS_WARNING_AVAILABLE: crisis_app = CrisisWarningApp() crisis_app.run() else: st.error("危机预警模块不可用,缺少必要的依赖") st.info("请安装lightgbm库以使用危机预警功能") - elif page == "智能关怀方案生成系统": + elif actual_page == "智能关怀方案生成系统": show_smart_care() - elif page == "航空界奥斯卡颁奖典礼": + elif actual_page == "航空界奥斯卡颁奖典礼": show_airline_oscars() def show_smart_care(): """显示智能关怀方案生成系统""" - st.title("❤️ 数据驱动的智能关怀方案生成系统") + # 航空主题样式 + st.markdown(""" + + """, unsafe_allow_html=True) + + # 页面标题 + st.markdown('

❤️ 数据驱动的智能关怀方案生成系统

', unsafe_allow_html=True) # 系统介绍 - st.markdown("### 系统概述") - st.markdown("本系统基于真实推文数据分析,总结出用户最关心的问题,为用户生成个性化的关怀方案。") + st.markdown('

系统概述

本系统基于真实推文数据分析,总结出用户最关心的问题,为用户生成个性化的关怀方案。

', unsafe_allow_html=True) # 显示数据来源说明 st.info( @@ -116,32 +781,35 @@ def show_smart_care(): ] # step 1 :用户偏好问卷 - st.markdown("## 📝 步骤1:用户偏好问卷") + st.markdown('

📝 步骤1:用户偏好问卷

', unsafe_allow_html=True) # 基本问题 - st.markdown("**请对以下服务问题的关注度评分(1-5分,1分最低,5分最高):**") + st.markdown('

请对以下服务问题的关注度评分(1-5分,1分最低,5分最高):

', unsafe_allow_html=True) # 使用动态列布局,根据屏幕宽度自动调整 + # 增加列数,使13个问题分布更合理 if st.session_state.get('columns') is None: - st.session_state.columns = 3 # 默认3列 + st.session_state.columns = 4 # 默认4列,比原来的3列更适合显示13个问题 # 动态创建评分滑块 user_ratings = {} # 创建n列布局 - cols = st.columns(st.session_state.columns) + cols = st.columns(st.session_state.columns, gap="medium") # 为每个问题创建评分滑块 for i, problem in enumerate(common_problems): with cols[i % st.session_state.columns]: + st.markdown(f'
{problem}
', unsafe_allow_html=True) user_ratings[problem] = st.slider( - problem, - 1, 5, 3, # 范围1-5,默认3 - key=problem + label=problem, # 保留label以便屏幕阅读器使用 + min_value=1, max_value=5, value=3, # 范围1-5,默认3 + key=problem, + label_visibility="hidden" # 隐藏默认标签,使用自定义的markdown显示 ) # 其他问题 - st.markdown("### 其他问题:") + st.markdown('

其他问题:

', unsafe_allow_html=True) communication_channels = st.multiselect( "您希望航空公司如何与您沟通服务问题?", @@ -156,7 +824,7 @@ def show_smart_care(): } # step 2:生成关怀方案 - st.markdown("## 🎯 步骤2:生成关怀方案") + st.markdown('

🎯 步骤2:生成关怀方案

', unsafe_allow_html=True) if st.button("生成专属关怀方案", type="primary", use_container_width=True): with st.spinner("正在调用智能分析模型生成个性化关怀方案..."): @@ -191,27 +859,34 @@ def show_smart_care(): """ # 调用DeepSeek API生成方案 - care_plan = call_deepseek_api(prompt, max_tokens=1000, temperature=0.7) + care_plan = call_deepseek_api(prompt, max_tokens=2000, temperature=0.7) # 增加max_tokens到2000,避免回答被截断 if care_plan: st.success("个性化关怀方案生成完成!") - # 显示用户最关心的问题 - st.markdown("### 👤 您最关心的问题") - col1, col2 = st.columns(2) + # 显示用户最关心的问题和优先级权重 + col1, col2 = st.columns(2, gap="large") + with col1: + st.markdown('

👤 您最关心的问题

', unsafe_allow_html=True) for i, (problem, score) in enumerate(top_problems, 1): st.write(f"{i}. {problem}: {score}/5分") + st.markdown('
', unsafe_allow_html=True) # 显示优先级权重分布 with col2: - st.markdown("### ⚖️ 问题优先级权重") + st.markdown('

⚖️ 问题优先级权重

', unsafe_allow_html=True) for problem, weight in sorted(priority_weights.items(), key=lambda x: x[1], reverse=True): - st.progress(weight, text=f"{problem}: {weight*100:.1f}%") + # 使用markdown显示,而不是progress组件,避免显示不全 + percentage = weight * 100 + st.markdown(f"
{problem}: {percentage:.1f}%
", unsafe_allow_html=True) + st.progress(weight) + st.markdown('
', unsafe_allow_html=True) # 显示生成的关怀方案 - st.markdown("### 🎁 个性化关怀方案") - st.markdown(care_plan) + st.markdown('

🎁 个性化关怀方案

', unsafe_allow_html=True) + st.markdown(f'
{care_plan}
', unsafe_allow_html=True) + st.markdown('
', unsafe_allow_html=True) else: st.error("方案生成失败,请稍后重试。") st.info("如果问题持续存在,可能是网络连接问题或API调用限制。") @@ -220,8 +895,52 @@ def show_smart_care(): def call_deepseek_api(prompt, max_tokens=1000, temperature=0.7): """调用DeepSeek API生成响应""" try: + import os + from dotenv import load_dotenv + load_dotenv() + url = "https://api.deepseek.com/v1/chat/completions" - api_key = "sk-eb8cc78f22ef443491d4199e56bde9a7" # 使用用户提供的API密钥 + api_key = os.getenv("DEEPSEEK_API_KEY", "") # 使用环境变量 + + if not api_key: + st.warning("DeepSeek API密钥未配置,使用模拟响应") + # 返回模拟响应 + return """ +# 个性化关怀方案 + +## 方案概述 +根据您的偏好,我们为您定制了一套全面的航空服务关怀方案,重点关注您最关心的服务问题。 + +## 具体关怀措施 + +### 服务态度 +- 提供专属客服经理,确保您的需求得到及时响应 +- 建立服务质量跟踪系统,记录并改进服务体验 +- 定期进行服务满意度调查,持续优化服务流程 + +### 延误 +- 提供实时航班状态通知,提前告知延误信息 +- 为延误超过2小时的航班提供餐饮和住宿安排 +- 建立延误补偿机制,根据延误时间提供相应赔偿 + +### 客服支持 +- 24小时在线客服,确保随时能获得帮助 +- 提供多渠道沟通方式,包括电话、短信、APP等 +- 建立快速响应机制,确保问题在24小时内得到解决 + +## 实施优先级 +- P0(最高优先级,立即实施):服务态度、延误 +- P1(高优先级,短期部署):客服支持 +- P2(中优先级,中期规划):其他问题 + +## 预期效果 +- 提升您的整体出行体验满意度 +- 减少服务问题对您行程的影响 +- 建立更加透明、高效的服务沟通机制 + +## 沟通方式建议 +根据您的偏好,我们将通过短信、邮件等方式与您保持沟通,确保您及时了解服务进展和改进情况。 + """ headers = { "Content-Type": "application/json", @@ -255,6 +974,155 @@ def call_deepseek_api(prompt, max_tokens=1000, temperature=0.7): def show_airline_oscars(): """显示航空界奥斯卡颁奖典礼""" + # 航空主题和奥斯卡主题样式 + st.markdown(""" + + """, unsafe_allow_html=True) + # 加载并显示航空界奥斯卡颁奖典礼内容 st.markdown('## 🏆 航空界奥斯卡颁奖典礼') @@ -447,123 +1315,203 @@ def show_airline_oscars(): # 航空公司奖项 st.markdown('### ✈️ 航空公司奖项') - col1, col2 = st.columns(2) + # 使用更平衡的两列布局 + col1, col2 = st.columns(2, gap="large") with col1: - st.markdown('#### 最佳口碑奖') - st.success(f"🏅 **{airline_awards['最佳口碑奖']}**") + # 最佳口碑奖 + st.markdown('#### 🏅 最佳口碑奖') + st.success(f"**{airline_awards['最佳口碑奖']}**") st.caption("**解释**:拥有最多正面评价的航空公司,代表其服务质量得到了用户的广泛认可") - st.markdown('#### 最受关注奖') - st.success(f"🏅 **{airline_awards['最受关注奖']}**") + # 最受关注奖 + st.markdown('#### 🏅 最受关注奖') + st.success(f"**{airline_awards['最受关注奖']}**") st.caption("**解释**:在推文中被提及次数最多的航空公司,代表其品牌曝光度最高") - st.markdown('#### 最淡定航空公司奖') - st.success(f"🏆 **{airline_awards['最淡定航空公司奖']}**") + # 最淡定航空公司奖 + st.markdown('#### 🏆 最淡定航空公司奖') + st.success(f"**{airline_awards['最淡定航空公司奖']}**") st.caption("**解释**:负面推文中抱怨客服态度冷漠比例最低的航空公司,代表其服务人员态度较好") with col2: - st.markdown('#### 最需改进奖') - st.error(f"🏅 **{airline_awards['最需改进奖']}**") + # 最需改进奖 + st.markdown('#### 🏅 最需改进奖') + st.error(f"**{airline_awards['最需改进奖']}**") st.caption("**解释**:拥有最多负面评价的航空公司,代表其服务质量需要重点改进") - st.markdown('#### 最具争议奖') - st.warning(f"🏅 **{airline_awards['最具争议奖']}**") + # 最具争议奖 + st.markdown('#### 🏅 最具争议奖') + st.warning(f"**{airline_awards['最具争议奖']}**") st.caption("**解释**:正面评价和负面评价比例最接近的航空公司,代表用户对其评价两极分化严重") - st.markdown('#### 行李去哪儿了特别贡献奖') - st.warning(f"🎒 **{airline_awards['行李去哪儿了特别贡献奖']}**") + # 行李去哪儿了特别贡献奖 + st.markdown('#### 🎒 行李去哪儿了特别贡献奖') + st.warning(f"**{airline_awards['行李去哪儿了特别贡献奖']}**") st.caption("**解释**:行李丢失相关投诉最多的航空公司,代表其行李运输服务需要加强") - st.markdown('#### 最高可信度奖') - st.info(f"🏅 **{airline_awards['最高可信度奖']}**") + # 最高可信度奖 - 单独一行显示 + st.markdown('#### 🏅 最高可信度奖') + st.info(f"**{airline_awards['最高可信度奖']}**") st.caption("**解释**:情感判断置信度最高的航空公司,代表用户对其评价的态度最明确") # 问题类型奖项 st.markdown('### 🚨 问题类型奖项') - col1, col2 = st.columns(2) + col1, col2 = st.columns(2, gap="large") with col1: - st.markdown('#### 最受关注问题') - st.success(f"🏅 **{problem_awards['最受关注问题']}**") + # 最受关注问题 + st.markdown('#### 🏅 最受关注问题') + st.success(f"**{problem_awards['最受关注问题']}**") st.caption("**解释**:在推文中被提及次数最多的负面问题,代表用户最常遇到的困扰") - st.markdown('#### 最严重问题') - st.error(f"🏅 **{problem_awards['最严重问题']}**") + # 最严重问题 + st.markdown('#### 🏅 最严重问题') + st.error(f"**{problem_awards['最严重问题']}**") st.caption("**解释**:负面情感最强烈、置信度最高的问题,代表用户最不满的服务缺陷") with col2: - st.markdown('#### 最具影响力问题') - st.warning(f"🏅 **{problem_awards['最具影响力问题']}**") + # 最具影响力问题 + st.markdown('#### 🏅 最具影响力问题') + st.warning(f"**{problem_awards['最具影响力问题']}**") st.caption("**解释**:引发最多转发讨论的问题,代表其社会影响力最大") - st.markdown('#### 最含糊问题') - st.info(f"🏅 **{problem_awards['最含糊问题']}**") + # 最含糊问题 + st.markdown('#### 🏅 最含糊问题') + st.info(f"**{problem_awards['最含糊问题']}**") st.caption("**解释**:判断置信度最低的问题,代表用户对该问题的描述不够明确") # 用户奖项 st.markdown('### 👤 用户奖项') - col1, col2 = st.columns(2) + col1, col2 = st.columns(2, gap="large") with col1: - st.markdown('#### 最活跃评论员') - st.success(f"🏅 **{user_awards['最活跃评论员']}**") + # 最活跃评论员 + st.markdown('#### 🏅 最活跃评论员') + st.success(f"**{user_awards['最活跃评论员']}**") st.caption("**解释**:发布推文数量最多的用户,代表其对航空公司服务最为关注") - st.markdown('#### 最情绪化用户') - st.warning(f"🏅 **{user_awards['最情绪化用户']}**") + # 最情绪化用户 + st.markdown('#### 🏅 最情绪化用户') + st.warning(f"**{user_awards['最情绪化用户']}**") st.caption("**解释**:情感判断置信度最高的用户,代表其对服务质量的评价态度最鲜明") - st.markdown('#### 吐槽之王奖') - st.error(f"🔥 **{user_awards['吐槽之王奖']}**") + # 吐槽之王奖 + st.markdown('#### 🔥 吐槽之王奖') + st.error(f"**{user_awards['吐槽之王奖']}**") st.caption("**解释**:推文被转发次数最多的用户,代表其吐槽内容引起了最多共鸣") with col2: - st.markdown('#### 最具影响力用户') - st.error(f"🏅 **{user_awards['最具影响力用户']}**") + # 最具影响力用户 + st.markdown('#### 🏅 最具影响力用户') + st.error(f"**{user_awards['最具影响力用户']}**") st.caption("**解释**:推文总转发量最高的用户,代表其对航空公司服务的评价影响范围最广") - st.markdown('#### 最自信用户') - st.info(f"🏅 **{user_awards['最自信用户']}**") + # 最自信用户 + st.markdown('#### 🏅 最自信用户') + st.info(f"**{user_awards['最自信用户']}**") st.caption("**解释**:在推文中对自己观点表达最肯定的用户,代表其对评价内容最有信心") - st.markdown('#### 天气预报大师奖') - st.success(f"🌤️ **{user_awards['天气预报大师奖']}**") + # 天气预报大师奖 + st.markdown('#### 🌤️ 天气预报大师奖') + st.success(f"**{user_awards['天气预报大师奖']}**") st.caption("**解释**:提及航班延误次数最多的用户,代表其最关注航班准点问题") - st.markdown('#### 深夜情感电台奖') - st.info(f"🌙 **{user_awards['深夜情感电台奖']}**") + # 深夜情感电台奖 - 单独一行显示 + st.markdown('#### 🌙 深夜情感电台奖') + st.info(f"**{user_awards['深夜情感电台奖']}**") st.caption("**解释**:在凌晨2-4点发布投诉推文最多的用户,代表其喜欢在深夜表达不满") - # 颁奖典礼总结 + # 颁奖典礼总结 - 优化显示效果 st.markdown('## 🎉 颁奖典礼总结') - + + # 使用更突出的总结卡片 + st.markdown('
', unsafe_allow_html=True) st.markdown(f""" - 本次航空界奥斯卡颁奖典礼共颁发了 **{len(airline_awards) + len(problem_awards) + len(user_awards)}** 个奖项, - 基于对 **{len(df)}** 条推文的数据分析结果。 - +
+ 本次航空界奥斯卡颁奖典礼共颁发了 {len(airline_awards) + len(problem_awards) + len(user_awards)} 个奖项, + 基于对 {len(df):,} 条推文的数据分析结果。 +
+ ### 主要发现: - - **最佳口碑奖** 由 **{airline_awards['最佳口碑奖']}** 获得,拥有最多正面评价 - - **最需改进奖** 由 **{airline_awards['最需改进奖']}** 获得,需要在服务质量上做出改善 - - **最受关注问题** 是 **{problem_awards['最受关注问题']}**,需要航空公司重点关注 - - **最具影响力用户** 是 **{user_awards['最具影响力用户']}**,其推文获得了最多转发 - - **最淡定航空公司** 是 **{airline_awards['最淡定航空公司奖']}**,客服投诉比例最低 - - **行李最易丢失航空公司** 是 **{airline_awards['行李去哪儿了特别贡献奖']}**,行李相关投诉最多 - - **吐槽之王** 是 **{user_awards['吐槽之王奖']}**,其吐槽获得了最高关注度 - - **天气预报大师** 是 **{user_awards['天气预报大师奖']}**,最常提及航班延误问题 - - **深夜情感电台主持人** 是 **{user_awards['深夜情感电台奖']}**,最爱在深夜发投诉推文 - - 感谢所有参与本次数据分析的推文用户, + - **🏅 最佳口碑奖** 由 **{airline_awards['最佳口碑奖']}** 获得,拥有最多正面评价 + - **🏅 最需改进奖** 由 **{airline_awards['最需改进奖']}** 获得,需要在服务质量上做出改善 + - **🚨 最受关注问题** 是 **{problem_awards['最受关注问题']}**,需要航空公司重点关注 + - **👤 最具影响力用户** 是 **{user_awards['最具影响力用户']}**,其推文获得了最多转发 + - **🏆 最淡定航空公司** 是 **{airline_awards['最淡定航空公司奖']}**,客服投诉比例最低 + - **🎒 行李最易丢失航空公司** 是 **{airline_awards['行李去哪儿了特别贡献奖']}**,行李相关投诉最多 + - **🔥 吐槽之王** 是 **{user_awards['吐槽之王奖']}**,其吐槽获得了最高关注度 + - **🌤️ 天气预报大师** 是 **{user_awards['天气预报大师奖']}**,最常提及航班延误问题 + - **🌙 深夜情感电台主持人** 是 **{user_awards['深夜情感电台奖']}**,最爱在深夜发投诉推文 + +
+ 感谢所有参与本次数据分析的推文用户,
期待明年的航空界奥斯卡颁奖典礼! - """) +
+ """, unsafe_allow_html=True) + st.markdown('
', unsafe_allow_html=True) - # 页脚 + # 页脚 - 优化样式 st.markdown('---') + st.markdown('
', unsafe_allow_html=True) st.markdown('© 2026 航空界奥斯卡颁奖典礼 | 基于真实推文数据分析') + st.markdown('
', unsafe_allow_html=True) def show_data_overview(df): """显示数据概览""" - st.title("📊 航空公司情感分析数据概览") + + # 航空主题样式 - 使用更强大的CSS选择器 + st.markdown(""" + + """, unsafe_allow_html=True) + + st.title("✈️ 航空公司情感分析数据概览") if df is None: st.warning("请先准备数据文件") @@ -573,7 +1521,7 @@ def show_data_overview(df): data_overview = DataOverview("data/Tweets.csv") # 基本信息 - st.subheader("📋 数据基本信息") + st.markdown("

📋 数据基本信息

", unsafe_allow_html=True) basic_info = data_overview.get_basic_info() col1, col2 = st.columns(2) @@ -583,7 +1531,7 @@ def show_data_overview(df): st.metric("特征数量", basic_info['total_columns']) # 情感分布 - st.subheader("😊 情感分布分析") + st.markdown("

😊 情感分布分析

", unsafe_allow_html=True) sentiment_info = data_overview.get_sentiment_distribution() col1, col2, col3 = st.columns(3) @@ -597,20 +1545,18 @@ def show_data_overview(df): st.plotly_chart(fig_pie, use_container_width=True) # 航空公司情感分布 - st.subheader("✈️ 航空公司情感分布") + st.markdown("

✈️ 航空公司情感分布

", unsafe_allow_html=True) fig_airline = data_overview.create_sentiment_by_airline_chart() st.plotly_chart(fig_airline, use_container_width=True) - - # 时间序列分析 - st.subheader("⏰ 时间趋势分析") + st.markdown("

⏰ 时间趋势分析

", unsafe_allow_html=True) fig_time = data_overview.create_time_series_analysis() if fig_time: st.plotly_chart(fig_time, use_container_width=True) # 转发分析 - st.subheader("🔄 转发行为分析") + st.markdown("

🔄 转发行为分析

", unsafe_allow_html=True) fig_retweet, retweet_stats = data_overview.create_retweet_analysis() if fig_retweet: st.plotly_chart(fig_retweet, use_container_width=True) @@ -621,7 +1567,7 @@ def show_data_overview(df): st.dataframe(pd.DataFrame(retweet_stats).T) # 负面原因分析 - st.subheader("🔍 负面原因分析") + st.markdown("

🔍 负面原因分析

", unsafe_allow_html=True) negative_reasons = data_overview.get_negative_reasons() if negative_reasons: reasons_df = pd.DataFrame(list(negative_reasons.items()), columns=['负面原因', '数量']) @@ -629,7 +1575,7 @@ def show_data_overview(df): st.dataframe(reasons_df, use_container_width=True) # 数据预览 - st.subheader("📋 数据预览") + st.markdown("

📋 数据预览

", unsafe_allow_html=True) # 添加筛选选项 col1, col2, col3 = st.columns(3) @@ -660,9 +1606,6 @@ def show_data_overview(df): display_columns = ['tweet_id', 'airline', 'airline_sentiment', 'negativereason', 'text', 'tweet_created'] st.dataframe(filtered_df[display_columns].head(sample_size), use_container_width=True) - # 显示筛选统计 - st.info(f"筛选结果: {len(filtered_df)} 条推文 (总数据: {len(df)} 条)") - st.success("✅ 数据概览分析完成!") diff --git a/bigwork/src/ultimate_xgboost_optimization.py b/bigwork/src/ultimate_xgboost_optimization.py index 0767fab..5445529 100644 --- a/bigwork/src/ultimate_xgboost_optimization.py +++ b/bigwork/src/ultimate_xgboost_optimization.py @@ -30,7 +30,24 @@ def load_and_prepare_data(): """加载和准备数据""" from enhanced_sentiment_analyzer import EnhancedAirlineSentimentAnalyzer - df = pd.read_csv('../data/Tweets.csv') + # 使用智能路径查找数据文件 + data_paths = [ + "d:/HuaweiMoveData/Users/马艺洁/Desktop/MLwork/bigwork/data/Tweets.csv", + "data/Tweets.csv", + "../data/Tweets.csv" + ] + + data_path = None + for path in data_paths: + import os + if os.path.exists(path): + data_path = path + break + + if data_path is None: + raise FileNotFoundError("无法找到数据文件,请检查Tweets.csv文件位置") + + df = pd.read_csv(data_path) analyzer = EnhancedAirlineSentimentAnalyzer(random_state=42) features, y = analyzer.prepare_features(df)