ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

基于Django和机器学习的电商评论情感分析系统实现

基于Django和机器学习的电商评论情感分析系统实现 每年到毕业季总有不少同学围着“选题”打转。如果你正在电商、数据或者 Web 开发方向徘徊“基于 Django 和机器学习的电商评论情感分析”是一个性价比很高的选择。它不是一个只调库的玩具项目而是一个从数据处理、模型训练到 Web 展示的完整闭环能一次性讲清楚后端框架、机器学习算法和自然语言处理三件事。这个题目好在哪里适合计算机专业、软件工程、电子商务和数据科学相关方向的学生拿来做毕业设计。哪怕你是刚接触 Python 不久的人只要愿意按步骤把整套流程走一遍也能在答辩现场拿出一个能看、能点、能出结果的作品。不过要注意网上类似的源码很多真正拉开差距的是你对每个环节“为什么这么做”的理解深度。这篇就结合我实际开发时踩过的坑把整个项目从设计到实现拆开讲清楚。1. 项目拆解光看标题你可能忽略了这些点1.1 这一个题目里藏了三个技术栈很多人第一眼看到“基于 Django 和机器学习的电商评论情感分析”觉得它只是一个普通网站加一个预测按钮。实际上题目背后藏着三个相对独立又互相衔接的技术栈第一是 Web 开发。Django 负责搭建用户界面、处理表单提交、展示预测结果还要管理数据记录。这部分考察的是 MTV 架构、路由、模板和 ORM 操作属于后端开发的基本功。第二是机器学习。你要把评论文本变成模型能理解的数字训练一个情感分类器让它能判断“这个手机拍照很清晰”是正向评价“快递太慢客服不回复”是负向评价。这里涉及文本分类、特征提取、模型评估等核心概念。第三是自然语言处理。中文分词、停用词过滤、向量化表示这些都是 NLP 的基础操作。跟英文不同中文没有天然的空格分词所以需要额外处理这也是很多同学第一次接触时会卡住的地方。这三个部分单独拿出来都可以展开做一个小课题凑在一起就是一个完整的系统。毕业设计最讲究的就是技术覆盖面这个题目天然就能让答辩老师看到你的工作量。1.2 电商评论情感分析到底在解决什么问题从业务角度看电商平台上的评论量非常大靠人工去读不现实。商家想知道用户对某个产品整体是夸还是骂运营想找出最近负面口碑集中在哪里这些需求背后都指向同一个技术任务——情感分类。情感分析本质上是文本分类问题。最简单的方案是二分类只区分正向和负向也可以做三分类把中性评价单独分出来。毕业设计场景下我建议做三分类因为电商评论里大量存在“一般般”“还行吧”这种没有强烈倾向的文本如果强制分成正负两类模型效果会很难看答辩时不好解释。这个任务的技术难度适中但又足够有代表性它需要你处理非结构化文本需要做特征工程需要训练模型还要把模型包装成线上可用的服务。整套流程恰好对应企业里一个最小可用的 NLP 应用。把这一套走通以后看其他分类任务比如垃圾邮件过滤、新闻分类、舆情监控思路几乎是通用的。2. 技术选型与整体方案设计2.1 为什么是 Django 而不是 Flask 或 FastAPI毕业设计选框架不要只看流行度要看它跟题目匹配不匹配。Django 是一个重框架自带 ORM、Admin 后台、模板系统、表单处理和用户认证意味着你不太需要再去拼第三方库。举个例子Flask 很轻量但要做用户登录、数据建模、后台管理你得自己挑一堆扩展拼起来。FastAPI 性能好、写接口舒服但在模板渲染和 Admin 后台方面可参考的毕业设计案例相对少。Django 生成项目时自动帮你建好了 admin 站点训练好的评论数据可以直接在里面管理答辩演示时打开后台给老师看立刻多一个亮点。Django 的另一个优势是 MTV 架构清晰。models.py 定义数据结构views.py 写业务逻辑templates 放页面你可以在答辩 PPT 里画一张分层图老师一看就懂。同时Django 的 ORM 在日常操作中非常顺手比如筛选负面评论只需要CommentRecord.objects.filter(sentimentnegative)要删除记录就调用.delete()。对应到网上那些“django执行查询-删除对象”的搜索热词核心就是先取 QuerySet 再操作这个点面试也常问。不过要提醒一句Django 自带数据库是 SQLite适合开发和学习。如果数据量特别大建议换成 MySQL在 settings.py 里改数据库配置并安装驱动就行。毕业设计直接用 SQLite 完全够用别在这上面花太多时间折腾。2.2 情感分析算法怎么选从传统模型到深度学习我见过不少同学一上来就想用 BERT觉得深度学习更有排面。但真到训练的时候数据集只有两三千条显卡也跟不上光跑一个 epoch 就要等半天。对于毕业设计项目如果目标是拿到一个稳定可解释的结果传统机器学习模型是更务实的选择。推荐优先尝试这三个模型朴素贝叶斯MultinomialNB实现简单收敛快小样本下表现稳定是文本分类的经典 baseline。逻辑回归LogisticRegression可解释性最强能直接输出每个特征对结果的影响权重答辩时可以说清楚“哪些词把评论推向正面”。线性 SVMLinearSVC分类边界更明确在特征维度较高时精度通常比朴素贝叶斯好一点但调参要稍微花点时间。我的建议是先用逻辑回归跑通全流程因为它训练速度和准确率平衡得很好。等流程稳定了再对比朴素贝叶斯和线性 SVM把三者的准确率、F1 值放进论文的对比表格里比一开始就追求复杂模型更有说服力。至于 LSTM、BERT 这些深度学习方法可以放在“后续改进与展望”章节里写。这样既展示了视野又不会因为环境配置问题拖垮你的开发计划。如果你确实想尝试建议用 Hugging Face 上的中文预训练模型做微调至少需要 1 万条以上标注数据才看得出效果否则很容易过拟合。2.3 数据从哪来公开数据集与合规采集数据是整个项目的地基。最省事的方式是使用公开的电商评论语料很多高校和开源社区都提供带情感标签的中文评论数据。使用公开数据的三个好处标注质量有保障、可以省去大量人工标注时间、论文里可以直接引用对比。如果你不想用现成数据也可以自己写爬虫去电商平台采集评论。但这里必须提醒只能用于个人学习和研究要遵守网站的访问规则控制请求频率不要批量抓取非公开数据。更不要碰那些跟攻击、破解相关的灰色方式这个圈子千万别沾。数据规模上三分类任务建议不少于 5000 条最好能到 1 万条。数据越少模型方差越大随便一条噪声都会显著影响准确率。另外数据集要做基本平衡让正向、中性、负向的比例不要相差太悬殊。如果实际采集到的负向评论很少会导致模型整体倾向预测正向看起来准确率不低实际没什么用。拿到数据后按照 8:2 或 7:3 划分训练集和测试集。注意划分要在预处理之前做避免测试集信息泄漏到模型训练里。这一点论文里也会重点讲做了就是加分项。3. 核心模块实现从数据清洗到 Django 集成3.1 环境准备与 Django 工程搭建统一环境是少踩坑的第一要素。我建议用 Anaconda 创建独立虚拟环境Python 版本选 3.9 或 3.10Django 用 4.x。版本太新有时会跟某些依赖库冲突没什么必要去追新。安装依赖推荐一次装齐pip install django pandas numpy scikit-learn jieba joblib matplotlib然后创建项目和 appdjango-admin startproject sentiment_project cd sentiment_project python manage.py startapp review把review加到settings.py的INSTALLED_APPS里不然 Django 不认这个 app。接着配置时区LANGUAGE_CODE zh-hans TIME_ZONE Asia/Shanghai USE_TZ True到这里一个最小可运行的 Django 项目就成了。你可以先跑python manage.py runserver浏览器打开 127.0.0.1:8000 看到默认页面再往里面加业务代码。第一次做 Django 的同学尤其要养成“小步快跑”的习惯每加一点功能就跑一下别指望一次性写完再调试。3.2 文本清洗与中文分词模型输入的是文本但文本必须转成数字才能训练。转换之前得先把原始评论洗干净。这里每一步都要想清楚目的去除 HTML 标签因为爬回来的评论里可能残留标签代码去除 URL链接对情感判断没有帮助去除各种符号让后续分词更干净。另外评论里的“好评”“五星”这类词单独出现时情感标记很强保留即可。中文分词我用 jieba它会把“物流很快”切分成“物流 / 很快”。停用词表要去下载一份常见的中文停用词表网上有很多开源版本。但停用词表不能乱用我实际踩过一个大坑有些停用词表把“不”“没”“很”也列进去了结果“很不满意”被切成了“很 / 满意”模型直接把负面评论判断成正面整体准确率掉了 5 个点。正确的做法是只删除代词、语气词、连词这些高频无意义词保留带情感倾向的否定词和程度副词。可以把预处理函数写成下面这样import re import jieba def clean_text(text): text re.sub(r.*?, , text) text re.sub(rhttp\S, , text) text re.sub(r[^\u4e00-\u9fa5a-zA-Z0-9], , text) return text def cut_text(text, stopwords): words jieba.lcut(clean_text(text)) words [w for w in words if w.strip() and w not in stopwords] return .join(words)预处理函数建议单独放在一个preprocess.py里训练和预测都要调用同一个函数避免出现“训练时处理了但线上预测时没处理”这种不一致。3.3 特征工程与模型训练把分词后的文本变成向量毕业设计里最常用的就是 TF-IDF。TF 表示词在当前文本里出现得多不多IDF 表示这个词在整体语料里罕不罕见。两者相乘既保留了文本内部的信息又压制了“的”“了”“是”这类在每篇文章里都出现的常见词。在 scikit-learn 里用 TfidfVectorizer 一行就能完成。训练时先切分数据再用训练集 fit然后只 transform 测试集和数据from sklearn.model_selection import train_test_split from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.linear_model import LogisticRegression X_train, X_test, y_train, y_test train_test_split( texts, labels, test_size0.2, random_state42, stratifylabels ) vectorizer TfidfVectorizer(max_features5000, ngram_range(1, 2), sublinear_tfTrue) X_train_vec vectorizer.fit_transform(X_train) X_test_vec vectorizer.transform(X_test) model LogisticRegression(C1.0, max_iter1000, class_weightbalanced) model.fit(X_train_vec, y_train) print(model.score(X_test_vec, y_test))代码里有几个容易被忽视的点。第一测试集只能调用 transform不能 fit_transform否则会把测试集的信息混进词表里。第二ngram_range(1, 2)非常值得加它会把相邻两个词作为一个组合特征能捕捉“不好”和“不 好”的区别。第三class_weightbalanced可以在类别不均衡时自动调整权重。训练完成后模型要保存到磁盘否则 Django 每启动一次就得重新训练一遍。用 joblibimport joblib joblib.dump(vectorizer, vectorizer.pkl) joblib.dump(model, model.pkl)3.4 模型评估与可视化准确率只是一个最基础的指标在类别不平衡时会造成误导。我建议至少输出 classification_report看每个类别的精确率、召回率和 F1 值。精确率是“模型说是正面的里面有多少真的是正面”召回率是“真正的正面里有多少被找了出来”两者都重要。还可以画一个混淆矩阵热力图能直观看出模型把中性评论误判成了哪一边。用 matplotlib 和 seaborn几十行代码就能完成生成的图直接放论文里比大段文字说明更清楚。评估通过后再考虑调参。下面章节会讲到具体参数。这里先提一个策略不要在测试集上反复调参否则会把你对测试集的“记忆”当成真实效果。更规范的做法是再切出一部分验证集或者直接用交叉验证最后再用测试集做一次最终评估。3.5 将模型集成到 Django 页面模型训练好了接下来就是把它塞进 Django 系统里。最容易犯的错是在 views.py 函数内部加载模型这样每个请求都会重新读一次磁盘预测接口会慢到让人怀疑人生。正确做法是把模型和向量器放到模块顶部只加载一次import joblib from django.shortcuts import render from .preprocess import cut_text model joblib.load(model.pkl) vectorizer joblib.load(vectorizer.pkl) def predict_view(request): if request.method POST: comment request.POST.get(comment, ).strip() if not comment: return render(request, index.html, {error: 请输入评论文本}) words cut_text(comment, stopwords) vec vectorizer.transform([words]) label model.predict(vec)[0] proba model.predict_proba(vec)[0] return render(request, result.html, { comment: comment, label: label, positive_prob: round(proba[2], 4), neutral_prob: round(proba[1], 4), negative_prob: round(proba[0], 4), }) return render(request, index.html)urls.py 里加一条路由模板里写一个表单页和一个结果页项目就跑起来了。如果想把每次预测记录保存到数据库可以建一个模型记录评论内容、预测结果、概率和时间顺带还能演示 Django Admin 后台管理数据。这里推荐一个小技巧给结果页加一个简单的进度条按预测概率的百分比显示正负情感强度。这个视觉效果很讨巧答辩老师录入一条评论页面立刻出现红色和绿色的进度条比单纯显示一串文字直观得多。4. 训练效果与参数调优经验4.1 如何判断模型效果不同的数据集规模、类别数量和任务难度下准确率没有统一标准。但如果你的数据是公开标注语料、三分类任务、训练集 8000 条左右我可以给你一个参考范围准确率 0.75 以下数据清洗或特征工程大概率有问题也可能是标签标注质量差。0.75 到 0.85属于正常水平说明流程跑通但模型还有提升空间。0.85 到 0.90相当不错可以在论文里作为主结果展示。0.90 以上需要警惕过拟合重点看一下测试集是否被你手滑放进了训练过程。二分类任务通常比三分类高 5 个点左右。如果你只想快速出成果二分类就能用但论文深度会弱一些。三分类能讲更多的分析和调优故事所以我更推荐。不同模型也有差异。我拿一份 1 万条电商评论做过快速实验朴素贝叶斯准确率大约 0.82逻辑回归 0.87线性 SVM 0.86。也就是说逻辑回归在这类任务上常常是最稳的选择而且可以通过查看特征权重解释模型。你在自己的数据上可以也跑一个基线对比放进论文的表格里比空口说“我的模型准确率很高”更有说服力。4.2 参数调优的几个关键点调优不要随机试。先盯两个模块文本向量化和分类器正则化强度。TfidfVectorizer 里最重要的参数是 max_features 和 ngram_range。max_features 控制特征总数。设太小词表覆盖不全设太大训练变慢还容易过拟合。5000 到 10000 是一个比较合理的区间。ngram_range 刚才说过尽量使用 (1, 2)对否定表达很有帮助。还可以关注 min_df 和 max_df。min_df5 表示只在少于 5 条评论中出现的词直接丢弃能过滤掉生僻噪声max_df0.8 表示在超过 80% 评论中都出现的词会被忽略这类词通常没有区分度。分类器方面逻辑回归最常调的是 C。C 是正则化强度的倒数C 越小正则越强越不容易过拟合。默认 C1.0如果训练集准确率远高于测试集可以把 C 降到 0.1 试试如果欠拟合再适当调大。想同时调多个参数用 GridSearchCVfrom sklearn.model_selection import GridSearchCV from sklearn.pipeline import Pipeline pipe Pipeline([ (tfidf, TfidfVectorizer()), (clf, LogisticRegression(max_iter1000)) ]) params { tfidf__max_features: [3000, 5000, 8000], tfidf__ngram_range: [(1, 1), (1, 2)], clf__C: [0.1, 1.0, 10.0] } grid GridSearchCV(pipe, params, cv5, scoringf1_macro) grid.fit(X_train, y_train) print(grid.best_params_)用 Pipeline 的好处是能保证交叉验证时向量化和分类器同步更新不会出现数据泄漏。调优结果应该报告交叉验证均值而不是单次分割的运气分。4.3 在论文里怎么呈现这些结果论文不需要包含所有实验细节但几个关键点一定要有数据集来源和规模、数据预处理的规则、模型选择的原因、评估指标的定义、实验结果对比表、混淆矩阵图、以及 Web 系统截图。一个很有说服力的展示方式是把逻辑回归模型里权重最大的前 20 个正向词和负向词列出来。比如“不错”“很快”“满意”权重高“差劲”“退货”“客服”权重低。这种特征级分析在答辩现场很容易吸引老师追问而你能解释清楚分数自然就上去了。Web 页面截图也不要随便截。至少要有三张用户输入评论的页面、预测结果展示页面、历史记录列表页面。如果做了数据可视化图表比如评论情感分布的饼图也可以放一张。5. 毕设开发中的常见问题与排查技巧5.1 环境与依赖问题环境问题是最磨人的。常见情况是在自己电脑跑得好好的换到另一台电脑就报错。根源是 Python 版本、依赖版本不一致。解决办法是立刻在项目根目录生成一个 requirements.txtpip freeze requirements.txt换环境时执行pip install -r requirements.txt另外一个很实际的经验是虚拟环境独一档不要把包直接装到系统 Python 里。Anaconda 的 conda 环境就可以很好地隔离不同项目的依赖。如果你需要请别人帮你远程看问题最稳妥的方法不是共享屏幕而是让对方用同样的 Python 版本和 requirements.txt 复现一遍。这样双方环境一致问题定位起来会快很多。把训练脚本、预处理函数和依赖文件都提交到 git 仓库比隔着屏幕口头描述更有用。5.2 中文编码与乱码中文编码是新手必踩的坑。用 pandas 读取 CSV 时如果文件是用 Excel 另存为 CSV 的默认编码可能是 GBK直接读会报UnicodeDecodeError。解决方法是读取时指定编码data pd.read_csv(comments.csv, encodingutf-8-sig)utf-8-sig会自动处理文件开头的 BOM 头比utf-8更稳妥。如果文件是 GBK就改成encodinggbk。Windows 系统下控制台用 print 输出中文也可能乱码这通常不是代码的问题而是控制台编码不是 UTF-8。启动前先执行set PYTHONIOENCODINGutf-8或者直接在代码里指定。Django 页面乱码则要检查 HTML 模板的 meta 标签meta charsetutf-8只要数据源头按 UTF-8 处理后面保存到数据库再读取展示基本不会出现乱码。5.3 模型加载与预测速度问题用 runserver 启动时每次请求都去 load 一次模型速度会慢到难以接受。解决办法刚才已经说过把joblib.load放到模块顶层。这样第一个请求之后模型对象一直在内存里预测单条评论只需要毫秒级。如果你的模型 pkl 文件很大比如十几 MB加载时间可能会让用户等待。这时可以调低 max_features或者把向量化后的特征压缩。另外Django 自带的 runserver 只适合开发不能扛高并发。线上部署可以用 Gunicorn 加 Nginx但毕业设计一般只要求演示runserver 够用了。需要提醒的是模型文件、向量器文件和预处理函数要在部署时一起拷贝。很多人只拷贝了模型文件忘记带向量器导致线上预测直接报错。5.4 数据不平衡问题电商评论里只给了默认好评的用户很多而正经写负面评论的人少所以数据集常见正向偏多。如果不处理模型会把所有评论都猜成正面因为这样也能拿到很高的准确率。这就是准确率的高分陷阱。解决办法有三个方向。一是收集更多负面和中性样本也就是在数据层面做平衡。二是调整分类器参数逻辑回归里设置class_weightbalanced朴素贝叶斯里可以用类别先验。三是在评估时多关注 F1 macro它会对少数类更敏感。我在实际做评估时还遇到过一种情况单独看每个类别的准确率都不错但整体准确率很低。这通常是因为不同类别使用了不同的数据处理逻辑或者标签映射混乱。遇到这种问题先检查数据分布和类别映射再去怀疑模型。5.5 答辩前检查清单最后整理一份我在交付前会逐项检查的清单代码是否在全新环境里能跑通不依赖 IDE 里的隐藏配置。模型文件、向量器文件是否已经生成并且能被项目代码正常加载。预处理函数在训练和预测中是否完全一致尤其是分词和停用词表。README 里是否写清楚环境安装、数据来源、训练命令和启动命令。论文里的截图是否跟当前系统界面一致避免出现旧版本截图。准备 5 条测试评论覆盖正向、中性和负向临场演示时不要现场想。如果老师要传一个新句子测试你要能清空历史记录并快速得到结果。这些细节看起来琐碎但在答辩现场能顺利运行一次完整演示比任何口头解释都更有说服力。最后多提一句整个项目里最值得花时间优化的不是漂亮页面而是数据处理和评估那一段。页面整洁能用就行真正决定项目质量的是模型训练流程是否规范、结论是否可信。把这个主线抓牢毕业设计就不会跑偏。
返回列表