
简介本资源为基于Python与深度学习的中文情感分析系统毕业设计完整资料包面向计算机相关专业需要完成毕业设计的学生及希望学习Flask Web开发与文本分类的开发者。系统采用Flask框架搭配MySQL数据库实现用户注册登录、后台数据统计首页以及文本情感分析等核心模块可将输入文本自动判别为正面或负面评价并借助柱状图、饼图进行多维度数据汇总展示。压缩包共378个文件涵盖20个py源码、12个html模板、18个css样式、52个js脚本以及深度学习模型相关的npy、pkl、pb权重文件另附sql建库脚本、docx说明文档、pptx演示文稿与mp4演示视频整体约97.54MB。目前已有217人学习下载适合作为毕业设计参考模板帮助读者快速理解情感分析系统的整体架构、前后端交互流程与模型调用方式并在此基础上进行二次开发与功能扩展。1. 从一份 Flask 情感分析系统源码说起它到底能跑出什么结果很多同学做毕业设计时最头疼的不是写不出代码而是拼不出一套能演示、能答辩、能交差的完整系统。这份基于 Python 深度学习的中文情感分析系统用 Flask 做 Web 层、MySQL 存数据、深度学习模型做文本分类把登录注册、后台首页、文本分析、数据可视化串成了一条完整链路。它适合正在做计算机毕业设计、软件工程毕业设计或者想找一个 Flask 开发实战项目练手的人。你拿到手后能直接看到一条中文评论从输入框进去、经过模型推理、最后吐出正面或负面标签的全过程而不是只对着一个孤零零的模型脚本发呆。这套东西的价值在于它把深度学习模型和 Web 系统之间的那层胶水代码写清楚了而这恰恰是很多教程里缺失的部分。2. 拆开这套 Flask 情感分析系统模型、后端、前端怎么串起来2.1 深度学习模型在系统里扮演什么角色中文情感分析的核心任务是判断一段文本的情绪倾向。常见做法有两种一种是传统机器学习模型比如用 TF-IDF 加朴素贝叶斯或 SVM另一种是深度学习模型比如 TextCNN、BiLSTM 或者 BERT 微调。这份资源走的是深度学习路线模型部分大概率是一个 TextCNN 或 LSTM 结构因为这类模型在中文短文本分类上表现稳定训练成本也比 BERT 低得多适合毕业设计这种算力有限、时间有限的场景。模型在系统里的位置很明确它不直接面对用户而是被 Flask 后端封装成一个推理接口。用户在前端文本框里输入一段中文比如“这家店的服务态度太差了”Flask 收到请求后先做分词和序列填充再把处理好的张量喂给模型模型输出一个概率值最后后端根据阈值判定是正面还是负面把结果返回给前端渲染。这里有个关键点模型文件通常是离线训练好之后保存成.h5或.pth格式Flask 启动时加载到内存里而不是每次请求都重新训练。我一般会在 Flask 应用初始化时用model.load_weights()把权重读进来避免请求时反复 IO 导致响应慢。2.2 Flask 后端如何组织推理接口Flask 在这套系统里承担的是调度中心的角色。它要处理用户登录态、接收文本、调用模型、写数据库、返回 JSON。下面是一个典型的推理接口写法你可以直接抄到自己项目里改from flask import Flask, request, jsonify import jieba import numpy as np from tensorflow.keras.models import load_model from tensorflow.keras.preprocessing.sequence import pad_sequences app Flask(__name__) # 启动时加载模型和分词器避免每次请求重复加载 model load_model(sentiment_model.h5) tokenizer ... # 从 pickle 加载训练时保存的 tokenizer MAX_LEN 100 # 与训练时保持一致 app.route(/api/predict, methods[POST]) def predict(): data request.get_json() text data.get(text, ).strip() if not text: return jsonify({error: 文本不能为空}), 400 # 中文分词用空格拼接成模型能吃的格式 words jieba.lcut(text) seq tokenizer.texts_to_sequences([ .join(words)]) padded pad_sequences(seq, maxlenMAX_LEN, paddingpost, truncatingpost) # 模型输出概率0 到 1 之间 prob model.predict(padded)[0][0] label 正面 if prob 0.5 else 负面 return jsonify({ text: text, label: label, confidence: float(prob) }) if __name__ __main__: app.run(debugTrue, host0.0.0.0, port5000)这段代码的逻辑说明jieba.lcut做中文分词因为训练时用的也是分词后的文本推理时必须保持一致否则模型看到的输入分布和训练时不一样准确率会掉得厉害。pad_sequences把变长序列补齐到固定长度paddingpost表示在末尾补零truncatingpost表示超长时从末尾截断。model.predict返回的是 sigmoid 输出的概率值大于 0.5 判正面小于等于 0.5 判负面。参数方面MAX_LEN必须和训练时一致常见取值是 100 或 200。如果你的文本普遍较长可以调到 300但要注意模型输入维度也得跟着改。port5000是 Flask 默认端口部署到服务器时记得改成 80 或 443或者用 Nginx 做反向代理。2.3 数据库表结构和登录注册逻辑MySQL 在这套系统里存两类数据用户信息和历史分析记录。用户表一般包含id、username、password_hash、phone、create_time这几个字段。密码不能明文存常见做法是用werkzeug.security里的generate_password_hash和check_password_hash做哈希和校验。历史记录表用来存每次分析的文本、预测标签、置信度和时间戳方便后台首页做统计图表。下面是一个建表 SQLCREATE TABLE user ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL UNIQUE, password_hash VARCHAR(255) NOT NULL, phone VARCHAR(20), create_time DATETIME DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE analysis_record ( id INT AUTO_INCREMENT PRIMARY KEY, user_id INT, input_text TEXT, predict_label VARCHAR(10), confidence FLOAT, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES user(id) );登录注册的逻辑用 Flask 的 session 或 JWT 都能做。session 更简单适合毕业设计这种单机部署场景。注册时校验用户名是否已存在、手机号格式是否正确、两次密码是否一致登录时用check_password_hash比对哈希值成功则把user_id写进 session。后台首页的柱状图和饼图数据来源就是analysis_record表。常见做法是用GROUP BY predict_label统计正面和负面的数量再用 ECharts 或 Chart.js 在前端渲染。这里有个容易翻车的地方如果记录表数据量很大每次刷新首页都全表扫描会很慢我一般会加一个create_time索引并且只查最近 30 天的数据。3. 把系统跑起来环境配置、模型加载和前后端联调3.1 Python 环境与依赖安装的版本坑这套系统依赖 TensorFlow 或 PyTorch、Flask、jieba、MySQL 驱动等库。Python 版本建议用 3.8 到 3.10太新的版本可能和 TensorFlow 某些版本不兼容。我见过太多人卡在pip install tensorflow这一步要么是网络问题要么是版本冲突。常见做法是先用 conda 建一个干净环境conda create -n sentiment python3.9 conda activate sentiment pip install flask tensorflow jieba pymysql werkzeug如果你用的是 PyTorch 版本的模型把tensorflow换成torch就行。注意 TensorFlow 2.x 和 1.x 的 API 差异很大load_model的行为也不一样。这份资源如果用的是 2.x那model.predict返回的是 numpy 数组如果是 1.x可能需要用session和graph写法完全不同。拿到源码后先看requirements.txt或者模型保存时的版本注释别上来就装最新版。MySQL 驱动推荐用pymysql因为它纯 Python 实现不需要编译安装成功率高。连接数据库时记得指定charsetutf8mb4否则中文会乱码。3.2 模型文件加载与推理性能调优模型加载是 Flask 启动阶段最耗时的操作。如果模型文件有几百 MB每次flask run都要等十几秒。我一般会把模型加载放在if __name__ __main__之前确保只加载一次。如果用的是 gunicorn 多 worker 部署每个 worker 都会加载一份模型内存占用会翻倍这时候要么减少 worker 数量要么把模型推理拆成独立的服务。推理性能方面单条文本预测通常在几十毫秒到几百毫秒之间取决于模型复杂度和 CPU 性能。如果并发量不大Flask 自带的开发服务器够用如果要演示给老师看建议用gunicorn -w 2 -b 0.0.0.0:5000 app:app启动稳定性比flask run好很多。还有一个细节model.predict默认会做 batch 推理如果你一次只传一条数据可以改成model(tf.constant(padded))直接调用省掉一些开销。不过这个优化对毕业设计来说不是必须的知道有这么回事就行。3.3 前后端联调时最容易断的链路前后端联调阶段最常见的问题是跨域和请求格式不对。Flask 默认不开启 CORS如果前端是单独跑的 Vue 或 React 项目浏览器会报跨域错误。解决办法是装flask-corsfrom flask_cors import CORS CORS(app)如果前端就是 Flask 模板渲染的 HTML那不存在跨域问题直接用fetch或axios请求同源接口就行。另一个坑是请求体格式。前端如果发的是application/x-www-form-urlencoded后端用request.get_json()会拿到None。要么前端改成JSON.stringify加Content-Type: application/json要么后端用request.form.get(text)取值。我一般统一用 JSON因为结构清晰调试也方便。数据库连接方面Flask 里不要每次请求都新建连接用连接池或者flask-sqlalchemy管理会话。如果直接用pymysql记得在请求结束时关闭游标和连接否则并发一上来就会报Too many connections。4. 避坑指南这套系统跑不起来时先查这五个地方4.1 模型加载报错版本不匹配或文件损坏现象Flask 启动时报OSError: Unable to open file或ValueError: Unknown layer。原因模型保存时的 TensorFlow 版本和当前环境不一致或者.h5文件在传输过程中损坏。解决先确认requirements.txt里的版本号用pip install tensorflow2.x.x装对应版本。如果是自定义层导致Unknown layer需要在加载时用custom_objects参数把自定义层传进去。文件损坏的话重新解压资源包比对文件大小是否一致。4.2 中文乱码数据库字符集没设对现象存入数据库的中文变成???或者乱码前端显示也异常。原因MySQL 建库时用了latin1字符集或者连接字符串没指定utf8mb4。解决建库时执行CREATE DATABASE sentiment DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;连接时用pymysql.connect(..., charsetutf8mb4)。已经建好的表可以用ALTER TABLE analysis_record CONVERT TO CHARACTER SET utf8mb4;修复。4.3 分词结果与训练不一致导致准确率暴跌现象模型在测试集上准确率 90%但系统里实际用的时候感觉像随机猜。原因训练时用的分词工具或分词模式与推理时不一致。比如训练用了jieba.lcut推理用了jieba.cut或者训练时没去停用词推理时去了。解决把训练时的预处理代码原封不动搬到推理流程里包括分词、去停用词、大小写转换等。最好把预处理逻辑封装成一个函数训练和推理共用同一份代码。4.4 Flask 端口被占用或无法外部访问现象flask run报Address already in use或者本机能访问但局域网内其他设备打不开。原因5000 端口被其他程序占用或者 Flask 默认只监听127.0.0.1。解决换端口用flask run --port 5001或者启动时指定app.run(host0.0.0.0, port5000)。如果服务器有防火墙还要放行对应端口。Windows 上可以用netstat -ano | findstr :5000找到占用进程并结束。4.5 后台首页图表数据不更新现象分析了几条文本但首页柱状图还是旧数据。原因前端图表数据是页面加载时一次性获取的没有做轮询或手动刷新或者后端查询语句有缓存。解决在图表容器上加一个刷新按钮点击时重新请求/api/stats接口。后端查询时加ORDER BY create_time DESC LIMIT 100确保拿到最新记录。如果用了 Flask-Caching记得设置较短的过期时间或者手动清缓存。5. 进阶技巧用混淆矩阵验证模型真实水平别只看准确率很多人拿到这套系统后跑通就完事了答辩时被问到“模型到底靠不靠谱”就支支吾吾。我一般会强制自己做一件事在测试集上跑一遍混淆矩阵看看正面和负面到底有没有被均衡地识别出来。假设你已经有了测试集和训练好的模型下面这段代码可以直接用from sklearn.metrics import confusion_matrix, classification_report import seaborn as sns import matplotlib.pyplot as plt # X_test 是 padded 后的测试数据y_test 是真实标签 y_pred_prob model.predict(X_test) y_pred (y_pred_prob 0.5).astype(int).flatten() cm confusion_matrix(y_test, y_pred) print(classification_report(y_test, y_pred, target_names[负面, 正面])) sns.heatmap(cm, annotTrue, fmtd, cmapBlues, xticklabels[负面, 正面], yticklabels[负面, 正面]) plt.xlabel(预测标签) plt.ylabel(真实标签) plt.title(混淆矩阵) plt.show()逻辑说明model.predict输出概率用 0.5 做阈值切成 0 和 1。confusion_matrix返回一个 2x2 矩阵对角线是分对的非对角线是分错的。classification_report会给出精确率、召回率和 F1 值。如果负面样本的召回率特别低说明模型倾向于把负面判成正面这时候要么调整阈值要么检查训练数据是否正负样本不均衡。参数方面阈值 0.5 不是固定的。如果业务上更怕漏掉负面评价可以把阈值降到 0.4让更多样本被判为负面。但这样会牺牲精确率具体怎么调要看你的场景。我一般会画一条 P-R 曲线找到 F1 最高的那个阈值点。还有一个习惯每次改完模型结构或预处理逻辑都重新跑一遍混淆矩阵和上一次的结果对比。如果 F1 掉了超过 2 个百分点就说明改动有问题得回滚。这个习惯帮我省了很多次“以为优化了其实退步了”的尴尬。从那以后我每次交付类似系统前都强制走一遍混淆矩阵加分类报告不看一眼不放心。希望帮到你。本文还有配套的精品资源点击获取