资讯动态

电商评论情感分析系统:Django+机器学习实战全流程解析

发布时间:2026/10/8 15:16:30 来源:尧图企业网站定制
做毕业设计最怕的不是写代码而是选题选到一半发现做不下去。电商评论情感分析这个方向属于典型的“看着热门、做着顺手、答辩好讲”的题目既有 Django 这种成熟 Web 框架撑起系统界面又有机器学习模型撑起核心算法还能挂上大数据的边——数据量一大清洗和特征工程就有得聊。我这两年接触过不少类似的毕设项目也帮人调试过源码、改过模型今天就把这个项目的完整拆解、技术选型、实现流程和避坑经验一次性讲清楚。不管你是准备开题、正在开发还是拿到一份源码想跑通这篇内容都能直接用上。这个项目本质上做的是三件事把电商平台的用户评论收集起来用机器学习模型判断每条评论是正向还是负向有的还带中性最后把分析结果用图表和关键词统计的方式展示在网页上。整体不算复杂但对 Django、机器学习、数据处理、前后端协作都有覆盖非常适合作为一个提前感受“完整项目长什么样”的练手作品。1. 项目选题与整体功能拆解1.1 为什么这个选题值得做毕业设计最忌讳的是“大而空”和“难而上头”。电商评论情感分析刚好卡在中间复杂度够但不至于让人头发掉光。它的好处有几个方面我一条条说。第一数据获取门槛低。电商评论数据在很多公开数据集、比赛平台、学术数据共享站里都能找到也可以自己整理一份脱敏的 Excel 表格服务端从 CSV 导入就能开始处理。对比目标检测、语音识别这类需要采集和标注大量样本的方向评论数据的可得性和可控性都强很多。第二算法路线清晰。情感分析在中文 NLP 里属于成熟任务不需要从零造轮子。哪怕只用 jieba 分词 TF-IDF 特征 朴素贝叶斯分类器也能跑出八九十的正确率。答辩时你讲得清楚原理老师听得明白逻辑。第三展示效果好。Django 页面加上 ECharts 饼图、柱状图、词云视觉效果拉满评审老师一眼就能看出系统功能是完整的。比起纯算法调参、输出一个准确率数字这种“看得见摸得着”的系统更容易拿到好印象。第四扩展空间大。如果你后续想升级可以把朴素贝叶斯换成 LSTM也可以加时间趋势分析、商品维度对比甚至做成实时情感监控大屏。毕设题目本身不会限制你的发挥。1.2 系统核心功能模块划分我通常会把整个系统拆成五个模块这样开发的时候思路清晰答辩的时候也好分块讲用户模块登录、注册、会话管理。大多数毕设系统都有这部分用来体现系统的完整性和权限控制能力。评论管理模块支持评论数据的导入CSV/Excel、手动新增、删除、批量导入并提供分页查询和关键词筛选。分析引擎模块这是核心负责对评论进行预处理、分词、特征提取、模型预测最终输出每一条评论的情感标签正面、负面、中性和置信度。数据统计模块按商品、按时间段统计情感分布计算好评率、差评率生成趋势数据。可视化展示模块用 ECharts 渲染饼图、柱状图、折线图用词云展示高频关键词。这个划分不是拍脑袋想出来的。每个模块都有明确的职责开发时可以并行开工调试时出了问题也能快速定位是前端、后端还是算法层的事。实际写代码时我建议先做分析引擎的模型脚本再做 Django 的评论管理和可视化最后补用户模块。因为分析引擎是核心先跑通它整个项目心里就有底了。2. 技术选型Django 与机器学习如何配合2.1 为什么选 Django 而不是 Flask 或 Spring Boot先说结论做这种毕设项目Django 在大多数情况下是更省心的选择。Flask 确实更轻但很多功能ORM、Admin 后台、表单处理、分页都要自己找第三方库拼装开发效率会低一些。Spring Boot 功能强大但 Java 体系学习成本高对 Python 生态的机器学习库支持也不好。Django 最大的优势是“全家桶体验”。它的 ORM 能把数据库操作封装得极其顺手Django Admin 自带后台管理界面登录验证有现成框架CSRF 防护默认开启安全性上不会被老师挑毛病。更关键的是Django 和 Python 机器学习生态是无缝衔接的你用 sklearn 训练好模型可以直接用 joblib 保存成文件然后在 Django 视图里加载、调用不需要额外做接口中转。有人可能会问模型怎么能直接跑在 Web 服务里答案是 Django 本身就是 Python 进程加载模型文件就是一次内存操作。你把训练好的 model.pkl 放在项目目录下写一个模型服务类视图函数调用它的 predict 方法就行。这种“算法脚本 Web 框架直连”的架构比 Flask 拆微服务、比 Java 调 Python 服务都简单得多特别适合毕设的系统规模。2.2 情感分析模型选型思路模型选型是整个项目里最值得花时间对比的环节。我给出一个适合毕设的路线优先做传统机器学习分类不要一上来就冲深度学习。具体来说推荐方案是 jieba 分词 TF-IDF 向量化 朴素贝叶斯或逻辑回归。理由如下朴素贝叶斯训练快对小样本数据集非常友好几千条评论几秒钟就能训练完。逻辑回归可解释性强权重大的词语能直接当作分析依据答辩时可以拿来说明“模型学到了什么”。TF-IDF 能天然降低“的、了、是”这类停用词的影响不需要额外做太复杂的过滤。相比 LSTM、BERT传统机器学习在 CPU 环境就能跑不需要 GPU也不需要在答辩现场演示时担心显存或环境问题。当然如果你想要一点亮点可以把模型升级为 BiLSTM 或用预训练模型做微调但作为毕设来说传统模型训练快、解释清楚、效果稳定已经足够了。我在实际调试中见过很多项目强行上 BERT结果不是训练时间太长就是模型文件太大没法部署最后还得退回传统方案。所以我的建议是先把朴素贝叶斯跑通有余力再往上升级给自己留一条稳妥的后路。2.3 数据存储与运行环境搭配数据存储方面开发阶段用 SQLite 就够了零配置文件型数据库Django 默认支持。等你要部署给别人演示或需要多人同时访问时再换 MySQL。评论数据量在几万条以内SQLite 完全扛得住查询速度也不会有明显问题。运行环境的搭配我列一份我实际用过的组合操作系统Windows 10/11 或 Ubuntu 20.04 都可以Python 版本3.8 以上建议 3.9 或 3.10Django 版本4.2 LTS稳定且资料多机器学习库scikit-learn、jieba、pandas、numpy可视化库pyecharts 或前端 ECharts 后端 JSON 数据接口有一点要特别注意Django 4.x 对 Python 版本有要求Python 3.8 以下可能装不上最新版。其次scikit-learn 和 numpy 的版本也会有兼容性问题建议用 pip 一次性安装 requirements.txt避免一个个装最后版本冲突。3. 数据库设计与评论数据准备3.1 数据表设计系统数据表不要设计得太复杂满足业务逻辑就好。我常用的表结构有三张用户表用 Django 自带的 User 模型就行扩展一个头像或昵称字段就够了不需要自己重写认证逻辑。商品表字段包括商品名称、商品链接、所属分类、创建时间。这个表主要用来按商品维度统计情感分布。评论表这是整个系统的核心表。字段包括评论内容、评论评分、评论时间、所属商品、情感标签正面/负面/中性、置信度、是否已分析。一开始很多同学会把情感标签直接存在评论表里这没问题但我要提醒一句如果以后要支持“不同模型分析结果对比”最好单独建一张分析记录表把模型名称、版本、预测结果、预测时间都存下来。这样虽然多了一张表但系统扩展性会好很多。不过毕设如果不做模型对比评论表里直接存预测结果也够用没必要过度设计。3.2 评论数据的获取与清洗评论数据从哪里来这个问题经常让新手卡住。我的建议是分三种情况处理第一用公开数据集。国内一些开源社区、比赛平台有电商评论数据集比如商品评论 CSV、带情感标注的语料可以直接下载。这类数据通常已经很规范字段包含评论文本和情感标签拿来训练模型最省事。第二手工整理一份演示数据。如果你只需要系统跑通和展示完全可以自己编几千条有代表性的评论或者从自己真实网购体验里整理并脱敏。虽然没有标注但可以用评分字段代替情感标签1-2 星是负面3 星中性4-5 星正面。第三有条件的可以用电商平台开放接口或自有业务数据但我不建议在毕设里去爬大型平台的真实评论。一方面有合规风险另一方面爬下来的数据噪音很大你需要大量时间做清洗反而不划算。数据清洗是决定模型效果的关键步骤。我在做这个项目时总结了几个必做的清洗操作去除评论中的 HTML 标签、URL、乱码字符去掉重复评论很多用户会一键复制粘贴把全角字符转半角处理表情符号要么删除要么替换成对应文字比如“开心”过滤掉评论长度过短的比如少于 2 个字符的无效评论清洗后的数据格式统一为 CSV两列content评论内容和 label情感标签0 负面 / 1 正面 / 2 中性。这是我个人偏好的标准格式因为 pandas 和 sklearn 都能直接加载模型训练脚本和 Django 导入脚本可以共用这份文件。3.3 中文评论预处理细节中文评论和英文评论最大的区别是没有天然的分隔符所以分词是必须的一步。我用 jieba 已经三年多了稳定性非常好但有几个细节要特别注意第一加载停用词表。停用词建议从网上下载一个通用的中文停用词表并手动补充电商领域的常见词比如“商品、东西、感觉、真的、就是”这类对情感判断帮助不大的词。注意不要过度过滤不要把“不好、太差”里的“不”去掉否则情感就反了。第二自定义词典。如果数据集中在某个领域比如美妆、数码可以自定义词典把“性价比”“大牌”“剁手”这类词合到一起分词会更准确。这个操作非常简单jieba.load_userdict 一个方法就能搞定。第三针对“否定词 情感词”的组合比如“不好”“不行”“不高兴”如果只做统计特征朴素贝叶斯也基本能处理但如果你想提高准确率可以在预处理阶段把否定词和后面的形容词拼接起来比如“不_高兴”让模型更容易学到这种模式。这是老 NLP 玩家常用的 trick但对新手可能有点抽象我的建议是先不分看效果如果负面评论误判很多再加。预处理脚本建议单独放在一个 utils/text_preprocess.py 文件里不要和 Django 视图混在一起写。因为训练脚本要用它预测接口也要用它抽出来复用就不会出现“训练时一套处理、预测时另一套处理”的乌龙。4. 情感分析模型训练全过程4.1 TF-IDF 特征构建与模型训练代码模型训练这一部分我会按实际代码流程讲一遍。假设你已经有了清洗好的 CSV 文件训练脚本的完整逻辑是读取数据、分词、TF-IDF 向量化、划分训练集和测试集、训练模型、评估效果、保存模型。核心代码大致如下import jieba import pandas as pd from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.naive_bayes import MultinomialNB from sklearn.model_selection import train_test_split from sklearn.metrics import classification_report import joblib # 读取清洗后的数据 df pd.read_csv(comments_clean.csv) X df[content].tolist() y df[label].tolist() # 中文分词函数 def cut_words(text): return .join(jieba.lcut(text)) # 对所有评论分词 X_cut [cut_words(text) for text in X] # TF-IDF 向量化max_features 控制特征维度 vectorizer TfidfVectorizer(max_features8000) X_vec vectorizer.fit_transform(X_cut) # 划分训练集和测试集 X_train, X_test, y_train, y_test train_test_split( X_vec, y, test_size0.2, random_state42, stratifyy ) # 训练朴素贝叶斯模型 model MultinomialNB(alpha1.0) model.fit(X_train, y_train) # 评估 y_pred model.predict(X_test) print(classification_report(y_test, y_pred, target_names[负面, 正面, 中性])) # 保存模型和向量器 joblib.dump(model, models/sentiment_model.pkl) joblib.dump(vectorizer, models/tfidf_vectorizer.pkl)这个脚本我实测过很多次数据量 5000 条以上、三类标签均衡时准确率普遍在 85% 以上。如果数据不平衡比如正面评论特别多、负面评论很少一定要在 train_test_split 里加 stratifyy或者用加权参数 class_weight 来平衡否则模型会偏向多数类所有评论都预测成正面。4.2 特征维度与参数调节思路TF-IDF 里的 max_features 是我建议第一个调节的参数。默认不设置时特征数量可能是几万甚至十几万维度太高训练慢而且容易过拟合。设置为 8000 或 10000 是通用经验值。判断是否合适的方法很简单打印分类报告如果模型在测试集上的表现明显差于训练集就说明过拟合了需要减小 max_features如果两者都不高说明特征太少了加大这个参数或者补充训练数据。朴素贝叶斯的 alpha 参数是平滑系数默认 1.0 不用动。你可以试着从 0.1 到 2.0 搜索一遍看看对准确率的影响但通常变化不大。另外一个容易被忽略的问题是 jieba 分词结果的一致性。训练时用的是 jieba.lcut 默认词典预测时如果用同一个函数处理一般不会出问题。但如果预测代码里没有加载和使用同一个词典或分词函数里加了一些额外操作就可能导致线上预测结果和训练时不一致准确率明显下降。这是很多源码调不通的隐性原因我见过好几个项目都是倒在这一步上。解决方法是把 cut_words 这个函数直接复制到 Django 的工具模块里保证完全一致。4.3 模型持久化与调用方式训练好的模型用 joblib.dump 保存成文件在 Django 项目里如何加载我推荐的方式是写一个单例类模型的加载只做一次不要每次请求都重复读文件。import os import joblib class SentimentAnalyzer: _instance None def __new__(cls): if cls._instance is None: cls._instance super().__new__(cls) cls._instance._load_models() return cls._instance def _load_models(self): base_dir os.path.dirname(os.path.dirname(os.path.abspath(__file__))) self.model joblib.load(os.path.join(base_dir, models, sentiment_model.pkl)) self.vectorizer joblib.load(os.path.join(base_dir, models, tfidf_vectorizer.pkl)) def predict(self, text): from utils.text_preprocess import cut_words vec self.vectorizer.transform([cut_words(text)]) proba self.model.predict_proba(vec)[0] label int(self.model.predict(vec)[0]) confidence float(max(proba)) return label, confidence这个写法的好处是模型文件路径不会写死成绝对路径换机器也能跑模型只加载一次响应速度不需要每次都去磁盘读文件。predict_proba 返回的是各类别的概率取最大值作为置信度这个信息可以存到数据库里在网页上展示“这条评论是负面置信度 92%”会比直接显示一个标签更有说服力。5. Django 集成与可视化展示5.1 后端视图与路由设计Django 的工程结构建议按功能拆 app不要所有模型写在一个文件里。我常用的拆法是app 名称 users注册登录app 名称 comments评论管理、数据导入app 名称 analysis模型加载、情感分析调用app 名称 dashboard统计与可视化页面每个 app 各管各的事路由分配也很清晰。比如 /comments/list 是评论列表页/comments/import 是导入数据接口/dashboard/overview 是统计总览页。这种命名方式答辩时说起来也顺口。关键的视图逻辑是用户在页面上选择商品、点击“分析未处理评论”后台遍历该商品下所有 status 为未分析的评论调用 SentimentAnalyzer.predict 逐条预测把结果写回数据库。这里要注意如果评论量很大不要在前台请求里同步做全部预测否则页面会卡很久。简单处理方式是先用小数据量演示或者把预测放到一个单独的视图里用异步方式触发。毕设场景下几千条评论同步预测也就几秒钟可以接受但一两万条以上就得考虑分批处理了。5.2 ORM 查询里的性能小坑Django ORM 用起来方便但在列表页展示评论时有一个经典坑N1 查询。比如评论表关联商品表你遍历评论去取所属商品名称Django 默认会对每条评论执行一次商品查询几千条评论就会产生几千条 SQL页面加载慢得让人怀疑人生。解决办法是查询时加 select_relatedcomments Comment.objects.select_related(product).filter(status2)这一行能让 Django 使用 SQL JOIN 把商品信息一次性查出来查询次数从几千次变成一次。这个优化虽然小但答辩时能说出来会显得你确实有生产经验。分页方面用 Django 自带的 Paginator 就行。每页 20 条模板里用页码导航数据量再大也不怕。切忌一页渲染几千条数据浏览器直接卡死。5.3 统计报表与词云展示可视化部分我建议采用前后端分离的数据接口方式Django 返回 JSONECharts 在前端渲染。后端写一个统计接口返回如下格式{ labels: [正面, 负面, 中性], values: [320, 45, 87], goods_stats: [ {name: 商品A, positive: 90, negative: 5, neutral: 5} ], hot_words: [ {name: 质量, value: 120} ] }前端用 Ajax 拉取这个 JSON然后填充到 ECharts 的饼图和柱状图里。词云可以用 echarts-wordcloud 插件输入热点词及其频次即可。关于统计 SQL用 Django ORM 的 aggregate 和 annotate 方法就能实现。按商品统计情感分布一行代码搞定不要写原生 SQLfrom django.db.models import Count result Comment.objects.values(product__name, sentiment).annotate( countCount(id) )这段代码会返回每个商品、每个情感标签的数量前端自己组装成图表数据即可。6. 实操中的常见问题与排查技巧6.1 源码跑不起来的经典原因我在调试定制服务时遇到的第一个高频问题就是环境不一致导致项目跑不起来。最常见的错误是项目在 Python 3.6 下开发你本地装的是 Python 3.10跑起来报一堆语法错误或版本冲突。解决办法是严格按照 requirements.txt 安装依赖并检查 Django、sklearn、numpy 的版本是否匹配。如果实在装不上就新建一个 Python 3.8 的虚拟环境一劳永逸。第二个高频问题是模型文件缺失。很多源码里只放了训练脚本没放训练好的 .pkl 文件你拿到手之后还得自己训练。训练本身不难但要记得训练完必须同时保存 model 和 vectorizer不然预测时调用 transform 会报维度不一致的错误。第三个问题是数据库结构没迁移。Django 的项目源码里如果带了 models.py但没有 migrations 记录或者你在新机器上直接运行就会报没有表。解决办法是运行基础的三连命令python manage.py makemigrations python manage.py migrate如果还提示缺少字段说明数据库版本和模型不同步需要清空数据库再重新迁移。开发阶段用 SQLite 的话直接把 db.sqlite3 删掉重建最快。6.2 中文乱码与编码处理电商评论数据里中文乱码是最常见的问题特别是在 Windows 平台下。根源基本都是 CSV 文件的编码和 pandas 读取时的编码不匹配。CSV 文件是 UTF-8但 Excel 打开保存后变成了 GBK然后 pandas 读进来就是一堆乱码。统一的做法是在读 CSV 时显式指定编码df pd.read_csv(comments_clean.csv, encodingutf-8)如果报错 UnicodeDecodeError就改成df pd.read_csv(comments_clean.csv, encodinggbk)最稳妥的方式是把所有数据文件都转换为 UTF-8 编码后再导入数据库。Django 连接 MySQL 时也要在 settings.py 里设置编码DATABASES { default: { ENGINE: django.db.backends.mysql, NAME: sentiment_db, USER: root, PASSWORD: 123456, HOST: 127.0.0.1, PORT: 3306, OPTIONS: {charset: utf8mb4}, } }注意用 utf8mb4 而不是 utf8因为真正的 utf8 在 MySQL 里不支持四字节字符遇到表情符号会直接报错。6.3 情感预测结果与直觉不符怎么办有时候你人工看一条评论明显是负面的模型却预测成正面这是情感分析项目里最容易被老师质疑的场景。处理这类问题我有一套流程第一先看这条评论的置信度。如果置信度只有 0.5 左右说明模型本来就没把握属于边界情况不用太纠结。第二检查分词结果。打印出 jieba 分词后的词序列看是不是把关键的词切错了。比如“不划算”被切成“不划/算”特征就丢了。第三检查停用词表。如果停用词表里误加了“不”这类否定词或者“太”“很”这类程度副词模型就失去了判断情感强度的信息。遇到这种情况把否定词和程度词从停用词表里删掉。第四扩展训练样本。收集数据里被误判的评论人工修正标签后加入训练集重新训练。这是最朴素也最有效的纠错手段所谓“bad case 回流”能让模型越用越准也是生产环境里迭代模型的通用思路。6.4 页面加载慢与小数据量卡顿如果统计页面图表加载很慢先排除网络原因再看接口返回数据的耗时。一个常见坑是可视化统计时对每条评论的动态渲染做了循环判断比如模板里写了一大堆 if 条件导致渲染时间长。解决办法是后端把数据准备好前端只负责展示不要在模板里做复杂运算。还有一个 Qt 相关的问题顺带提一句有些同学会把表格卡顿优化写成 qtableview 自定义 model那是桌面端方案和 Django 没关系。Web 端如果有大数据表格卡顿优先用后端分页 前端页码导航实在要展示大量行的再用虚拟滚动方案。毕设场景下后端分批返回数据就够了。7. 部署上线与项目扩展建议7.1 本地开发环境快速搭建如果你是新手第一次跑这个项目我建议按以下顺序操作安装 Python 3.9勾选 Add to PATH创建虚拟环境python -m venv venv激活虚拟环境Windows 执行 venv\Scripts\activate安装依赖pip install -r requirements.txt数据库迁移python manage.py migrate创建管理员账号python manage.py createsuperuser启动服务python manage.py runserver这时浏览器访问 http://127.0.0.1:8000 就能看到系统首页Django Admin 后台用刚才创建的管理员账号登录。如果页面能正常打开模型文件也存在说明整个系统已经跑通了。7.2 部署到公网演示的简化方案毕设最终可能需要部署到服务器上给老师演示。我不推荐一上来就折腾 Nginx uWSGI因为面试官大概率不会检查你的部署配置但系统能在线访问确实是加分项。我建议的方式是买一台最低配的云服务器装好 Python 环境和项目依赖直接使用 Django 的开发服务器加上允许外部访问的方式运行python manage.py runserver 0.0.0.0:8000 --insecure这种方式只适合演示不安全也不能承受并发但作为毕设演示完全够用。等答辩结束再关掉就行。如果你想正经部署再用 gunicorn Nginx但在毕设场景下把核心功能做扎实比折腾服务器环境更有价值。7.3 项目可以继续扩展的方向如果你做完了基础版本还有时间和精力我建议考虑以下几个扩展点每一个都能在答辩时形成亮点多模型对比在系统里加入逻辑回归、SVM 或者 LSTM 模型做一个模型效果对比页面展示准确率、精确率、召回率。评价维度细分不止区分正负面还可以识别“物流快”“质量好”“客服差”这类属性级情感需要用依存句法或规则匹配适合能力强的学生挑战。时间趋势分析按月份统计好评率变化形成折线图能发现商品口碑随时间的变化规律。实时分析接入消息队列或者用 Celery 异步任务让用户提交评论后实时返回情感结果交互感更强。数据大屏把统计结果做成大屏展示背景、图表、动效都调好视觉效果极其惊艳老师看到第一眼就会觉得项目完成度高。我个人在实际调试这类项目时体会最深的一点是情感分析项目的瓶颈往往不在模型本身而在数据和工程细节。数据干净、特征处理好朴素贝叶斯也能出很好的效果数据一团糟再牛的模型也白搭。做这个毕设你在数据清洗、模型训练、Web 集成这些环节里积累的完整经验才是真正比别人值钱的东西。最后再分享一个实际发生的案例。我帮一个同学调试的时候发现他所有的负面评论都预测成了正面排了一整天没找到原因最后发现是 CSV 文件里 label 列的值写反了1 是正面0 是负面但训练脚本里把 0 映射成了负面1 映射成了正面数据本身又是旧的排查起来特别折磨人。后来我把标签映射和代码逻辑全部对齐才恢复正常。所以无论你的模型效果多差先检查数据标注和代码逻辑的一致性再考虑调参这个思路能节省你非常多的排查时间。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑