简介这是一份面向计算机相关专业学生和开发者的酒店评论情感分析系统项目可用于毕业设计或课程作业。项目基于机器学习与自然语言处理技术内置Flask Web应用程序用户输入评论文本即可获得情感预测结果同时提供了逻辑回归与XGBoost两种模型供对比选择。资源共11个文件6.78MB主要包括4个pkl模型与向量器文件、3个HTML页面模板、1个Python主程序、1个Jupyter笔记本及说明文档。其中Jupyter笔记本完整记录了数据集探索、模型训练和性能评估过程便于学习者复现实验细节。目前已有179人浏览学习适合需要上手实践情感分析任务、快速搭建Web演示系统或参考项目架构的读者。下载后按照README指引安装依赖即可运行通过浏览器与模型交互操作直观具备较好的学习与二次开发价值。1. 需求切入酒店评论情感分析这套资源到底解决什么问题住过酒店的人都有这种经历翻评论翻到手指发酸也分不清哪些是真实体验、哪些是情绪发泄。对平台来说评论数量一多人工审核和排序就变成黑匣子光靠打分根本看不出用户真正满意什么。对做毕设的学生来说这个场景则是一个很标准的自然语言处理入门题有公开数据集、有可解释的模型、有可交互的界面做完之后能讲清楚「从文本到预测结果」的整条链路。这套酒店评论情感分析系统核心就是让用户输入一段评论文本马上得到正面或负面的预测结果同时把逻辑回归和 XGBoost 两个模型的选型、训练、对比、部署都落在一个 Flask Web 应用里。适合的人群有两类。一类是人工智能或计算机科学与技术专业的毕业生拿它当毕设主体可以顺着「数据清洗—特征工程—模型训练—Web 封装」这条线写论文另一类是正在做课程设计的学生需要一个能跑起来、能演示、能截图进报告的项目。这套资源包已经把模型文件和 Notebook 都训练好了到手之后不需要从零跑一遍完整训练流程重点在于理解它的设计逻辑并且能在答辩时把每个文件的作用讲清楚。2. 总体设计Flask 应用与双模型双向量器的四层职责划分2.1 系统模块拆解五个文件各管一段先看资源包里的核心文件它其实对应了一套很完整的工程结构。app.py 是 Flask 入口脚本负责启动 Web 服务、加载模型、处理请求templates 目录下有三个 HTML 模板——index.html 是用户输入评论的主页面hotel_detail.html 展示单条评论的分析明细recommendations.html 给出基于情感分数的推荐结果两个模型文件 logreg_model.pkl 和 xgboost_model.pkl 分别对应逻辑回归和 XGBoost 两套情感预测方案vectorizer.pkl 和 tfidf_vectorizer.pkl 是两套文本向量化工具作用是把中文评论文本转换成模型能读的数字矩阵sentimentAnalysisofHotelReviews.ipynb 记录了从数据探索到模型评估的完整过程。这个拆法的合理性在于它把「训练」和「预测」彻底分开了。Notebook 负责离线训练产出的 pkl 文件只做推理。Web 端永远不碰原始数据集只用向量器和模型做转换和预测这样做的好处是启动速度快、代码逻辑简单而且模型文件可以被替换——想换成别的算法只要训练新模型导出 pklapp.py 里的加载路径改一行就行。2.2 请求处理链路一段评论文本是如何变成情感标签的一段用户输入的评论文本在系统里的流转路径是固定的先由前端表单提交到 Flask 路由路由把文本交给向量器做 TF-IDF 或词频向量化向量化的结果是一个固定维度的稀疏矩阵这个矩阵喂给已经加载好的模型模型输出一个 0 到 1 之间的概率值最后按照 0.5 阈值映射为「正面」或「负面」标签随概率值一起渲染到结果页面。这条链路里最容易被忽略的是维度对齐问题。训练时用 vectorizer.pkl 拟合评论语料得到了一个固定长度的词汇表预测时也必须用同一个向量器去转换新文本不能重新 fit否则特征维度对不上模型会直接报错。app.py 里加载模型和向量器的顺序也有讲究我一般会先加载向量器再加载模型这样如果两个文件有版本兼容问题能更早暴露出来。2.3 双模型设计的价值逻辑回归与 XGBoost 不是重复造轮子很多人会问一个情感分析系统为什么要放两个模型逻辑回归和 XGBoost 在这里不是简单重复。逻辑回归是线性模型在 TF-IDF 向量化后的高维稀疏特征上表现稳定训练快、可解释性强适合作为基线模型论文里可以说「以 LR 为基准验证特征工程有效性」。XGBoost 是梯度提升树模型能捕捉特征之间的非线性关系在同样特征下往往能拿到略高的准确率但训练时间和模型体积都更大。两个模型并存的直接价值是答辩时能拿同一份测试集跑对比实验用一张表展示两个模型的精确率、召回率和 F1 值这是很加分的实验设计。从资源包的命名也能看出来作者特意保留了 logreg_model.pkl 和 xgboost_model.pkl 两个文件而不是只留效果最好的那个。Web 应用里没有做模型切换界面但 app.py 的预测函数里保留了选择模型的参数入口想看效果对比的话手动改一行代码就能切换预测引擎。3. 模型实现从数据集到两个 pkl 文件的完整训练流程3.1 Notebook 里的标准步骤探索、清洗、训练、评估sentimentAnalysisofHotelReviews.ipynb 是这套系统里最能体现工作量的一份文件。它通常遵循四条主线读入酒店评论数据集后先看标签分布和评论文本长度分布确认是否存在类别不平衡接着做文本清洗包括去标点、去停用词、统一小写化等操作这一步直接影响向量化的质量然后把数据集按比例拆成训练集和测试集在训练集上拟合向量器并转换特征再分别训练逻辑回归和 XGBoost最后在测试集上输出分类报告和混淆矩阵。如果你打算把它写进毕设论文这里有一个很关键的操作细节向量器必须只在训练集上 fit然后在训练集和测试集上分别 transform绝对不能在整个数据集上先 fit 再拆分。否则测试集的信息会泄漏进训练过程导致评估指标虚高答辩时被老师问一句「你的测试集是怎么处理的」就可能翻车。3.2 向量器选型的差异CountVectorizer 与 TF-IDF 各自的适用场景资源包里同时出现了 vectorizer.pkl 和 tfidf_vectorizer.pkl。vectorizer.pkl 对应的通常是 CountVectorizer它统计每个词在文本中出现的次数简单直观tfidf_vectorizer.pkl 对应的就是 TF-IDF 向量器它不仅统计词频还考虑了词在多少篇文档中出现过能压低「的」「了」这类高频词的权重突出真正有区分度的词。从工程角度讲逻辑回归对原始词频特性和 TF-IDF 特性都兼容但 TF-IDF 做逻辑回归的特征时对「好」「差」「干净」「吵」这类情感词的辨识度更高。XGBoost 这种树模型对稀疏矩阵的处理能力不强做树模型的特征时可以仍然用 TF-IDF也可以对原始词频做二值化处理看哪组效果更好。资源包保留了两种向量器用意就是让你分别跑一轮实验以测试集 F1 为准选最优组合这个对比过程在论文里非常值钱。3.3 训练脚本示意以 LR 为主模型的加载与预测代码在 app.py 中预测逻辑一般长这样import joblib import numpy as np from flask import Flask, request, render_template app Flask(__name__) # 加载训练好的模型和向量器 vectorizer joblib.load(vectorizer.pkl) model joblib.load(logreg_model.pkl) app.route(/predict, methods[POST]) def predict(): review_text request.form[review] if not review_text.strip(): return render_template(index.html, error评论内容不能为空) # 向量器负责将文本转为模型输入格式 features vectorizer.transform([review_text]) prob model.predict_proba(features)[0][1] label 正面 if prob 0.5 else 负面 return render_template(hotel_detail.html, reviewreview_text, sentimentlabel, probabilityround(float(prob), 4))predict_proba 返回的是一个二维数组[0][1] 取的是「属于正类」的概率。很多人第一次写这里会直接取 [0]拿到的是负类的概率导致预测结果完全反了这是一个很容易掉进去的坑。阈值 0.5 是默认值如果训练集类别不平衡可以改成 0.4 或 0.6 来调整召回率与精确率的平衡具体的值需要看验证集的 ROC 曲线来定不要凭感觉拍脑袋。4. Web 交互层三个 HTML 模板如何支撑完整的产品体验4.1 index.html提交入口的设计逻辑index.html 是整个系统的门面它只需要做一件事提供一个文本框和提交按钮把评论文本以 POST 方式交给 /predict 路由。表单的 action 指向 Flask 路由地址method 必须是 post不然中文文本放在 URL 参数里会出现编码问题。页面上还可以放一条示例评论比如「房间很干净位置也方便就是隔音不太好」方便演示时快速填入。模板里可以留一个隐藏字段标记当前使用的是哪个模型这样后续如果要加模型切换功能不用改模板结构。评论输入框要设置 maxlength 限制长度不然用户在页面上粘贴一篇几千字的评论向量器转换出的稀疏矩阵虽然不至于崩但响应时间会明显变慢。对演示场景来说输入 200 字以内的评论是最舒适的体验区间。4.2 hotel_detail.html预测结果的展示规范hotel_detail.html 负责把预测结果呈现给用户。建议展示三块内容原始评论文本、情感标签、正类概率值。标签可以用不同的 CSS 颜色区分正面用绿色、负面用红色概率值保留四位小数同时显示「模型判定该评论为正面/负面置信度 xx%」。这种设计的价值在于它把黑匣子结果透明化了——用户看到的不只是「正面」两个字还能看到概率知道模型有多确定。模板里再加一个返回按钮允许用户连续测试多条评论这个细节在演示时很稳妥能避免答辩现场因为回头操作麻烦而冷场。要注意的是Flask 端返回 hotel_detail.html 时用的 render_template 参数名必须和模板里的变量名一一对应少传一个参数模板直接报 UndefinedError。4.3 recommendations.html基于情感分布的推荐思路recommendations.html 是这套资源里比较灵活的部分不同版本里它可能有不同形态。一种常见设计是用户输入多条评论后系统对每条评论做情感预测统计正面评论占比按占比排序给出一个「推荐指数」。这种设计比单条预测更能体现情感分析在真实业务里的价值——平台可以用它来筛选高分酒店也可以识别差评集中的门店。实现上可以在 app.py 里加一个 /recommend 路由接收一个包含多条评论的列表来自表单 textarea 多行输入逐条做预测汇总结果。为了展示效果模板里放一个表格每一行是一条评论的原文、情感预测和概率表格下方是正面评论条数和占比汇总。这一页如果做进课程设计报告可以配一段话说明「本模块模拟了情感分析在用户决策支持场景中的应用」很容易讲清楚。5. 常见问题与排查指南五个最容易翻车的点5.1 pkl 文件加载失败报错显示维度不匹配现象是启动 app.py 后第一次提交评论就报错错误信息类似 ValueError: X has 2500 features, but LogisticRegression is expecting 3200 features。原因是训练模型时的特征维度和加载的向量器转换出的维度不一致也就是向量器换错文件了。比如用 tfidf_vectorizer.pkl 转换文本却加载了 logreg_model.pkl 这个基于 CountVectorizer 训练的模型。解决办法是配对加载vectorizer.pkl 配 logreg_model.pkltfidf_vectorizer.pkl 配 xgboost_model.pkl不要交叉使用。如果两个模型都是用同一份数据训练的理论上向量器可以互换但不同向量器的词汇表规模不同特征维度就对不上。动手之前先看 README.md里面有明确的加载组合说明。5.2 中文文本预测不准出现「正面」概率徘徊在 0.5 附近现象是无论输入什么评论预测概率都接近 0.5模型给不出很确定的判断。原因是训练集里样本可能以英文评论为主或者数据量偏少中文泛化能力弱。很多公开的酒店评论数据集是英文的中文的标注语料不多资源包里的训练集可能在文本模式上与你要测试的中文评论差异较大。解决办法是把 Notebook 里的训练过程在自己的数据上重跑一遍或者直接换用逻辑回归加载原始英文语料测试效果。如果必须测中文找少量中文酒店评论并手动标注追加进训练集重新训练模型替换掉原来的 pkl 文件。别指望预训练好的模型对完全不在分布内的语言照样有效这是自然语言处理的基础认知。5.3 类别不平衡问题模型全部预测为负面有一种很隐蔽的翻车情况训练集中负面样本占比超过 85%逻辑回归学到的决策倾向是「宁可错杀不可放过」测试集准确率看着很高但真实输入一些正面评论时全部被判负面。查看 Notebook 里的分类报告可以发现负类的 F1 很高正类的召回率可能只有 0.2 左右。解决办法是在训练前做类别重采样对少数类做过采样或者给模型加 class_weightbalanced 参数。XGBoost 里也有 scale_pos_weight 参数可以调整正负样本权重。如果数据集本身比较均衡就看测试集上两个类别的 F1 是否都在 0.8 以上达不到就先处理类别不平衡再谈调参。5.4 Flask 用开发服务器跑生产演示时卡死或报 500取这个标题是因为很多同学在演示时直接用 python app.py 启动没开 debug 模式出错后页面只显示 500 Internal Server Error排查困难。而且开发服务器是单进程的同时有多个人访问性能很差。资源包定位是课设和毕设演示单机演示没问题但不代表它可以不做错误处理。解决办法是app.py 里显式声明 app.errorhandler(500) 捕获异常并输出错误信息到日志文件同时把 app.run(debugTrue) 设置在单独的入口条件里避免部署环境误开 debug。演示时建议先用本地浏览器完整走一遍流程确认没有明显报错再考虑给别人访问。5.5 安装依赖时版本冲突sklearn 新版无法加载旧版 pkl现象是 pip install scikit-learn 装的是最新版本运行 app.py 时 joblib.load 报 ModuleNotFoundError 或 AttributeError。原因是部分模型文件由旧版本 scikit-learn 训练导出不同大版本的模型序列化格式不完全兼容。这个问题在课程设计里出现频率极高。解决办法是先在 README.md 里查看写明的依赖版本要求按那个版本装环境或者用 conda 建一个独立环境在环境里安装 requirements.txt 中的固定版本。装完之后跑一遍 Noteb员工ok 里的模型训练单元确认当前环境能正常生成和加载 pkl 文件这一步可以作为环境是否就绪的冒烟测试。6. 验收与答辩你该怎么向老师和同学展示这套系统验收一个情感分析系统要按三个层次来走每一层都有明确的可操作标准。功能层验收最简单也最关键打开浏览器访问首页输入一条明显正面的评论「服务很好早餐很丰富下次还会来」预测结果应该显示正面且概率明显大于 0.5再输入一条「房间很脏床单有异味不会再住」预测结果应该显示负面。这两条测试用例能跑通说明 Web 链路是通的。再测一个边界用例输入空白文本或只有标点符号的评论页面应该给出友好提示而不是报错。模型层验收要看分类报告逻辑回归在测试集上的准确率不应该低于 0.8F1 值至少达到 0.75 以上才算合格XGBoost 如果效果明显低于逻辑回归要能解释原因通常是因为树模型在稀疏高维特征上的优势没有发挥出来需要更多的特征工程。把两个模型的精确率、召回率、F1 值、训练时间放在一张对比表里这页 PPT 就是整个答辩的实验核心。答辩现场的高频问题十有八九会出现在预测逻辑上。老师很可能会问「你的系统怎么判断一条评论是正面的还是负面的」这时候你要讲清楚文本先被 TF-IDF 向量化变成稀疏矩阵然后逻辑回归给每个词学到一个权重正面词权重为正负面词权重为负最后把所有词的加权分数求和再映射到 0 到 1 之间。为了应对这个问题可以在 Notebook 里额外加一个步骤输出权重绝对值排名前 20 的词用来证明模型学到了有意义的语义信息这是很亮眼的一个展示。我留下一个习惯每次演示前都会先在本地跑一遍完整的最小路径——启动服务、输一条正面评论、输一条负面评论、确认结果页渲染正常全程不超过两分钟。这套流程看起来简单但技术演示翻车的概率八成不是模型不工作而是小问题没提前暴露。走到答辩现场才第一次开项目那才是真的后悔药都找不到。希望这篇拆解能帮你在拿到资源包后更快地把它变成一份自己讲得清楚、老师挑不出硬伤的设计方案。本文还有配套的精品资源点击获取