ARTICLE DETAIL

资讯详情

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

基于Python与BERT的文本相似度检测系统:从原理到毕业设计实战

基于Python与BERT的文本相似度检测系统:从原理到毕业设计实战 简介这份压缩包提供基于Python与BERT模型的文本相似度检测系统完整毕业设计源码适合自然语言处理学习者、高校学生用于毕业设计或课程设计参考。系统采用Python 3.6.8开发数据库选用MySQL 5.7编码与数据库管理分别基于PyCharm和Navicat11完成包内不但包含python部署说明文档、数据库设计文件、project源码主目录还附有LW相关材料能够帮助使用者快速理清项目架构并实际部署运行。压缩包共389个文件体积52.27MB主要文件类型包括Python源码py/pyc、网页前端资源css/js/html、站点图片gif/png/svg、说明文档docx/pdf/txt以及数据库脚本sql等资源类型覆盖从后端逻辑、前端界面到数据存储的完整环节便于按需查阅和二次开发。目前已有70人学习或下载尤其适合作为NLP方向毕业设计的完整范本、深度学习文本相似度任务的入门实践以及课程设计成果展示。1. 基于Python的BERT文本相似度检测系统一份能跑通毕业设计的完整源码做毕设最怕的不是算法难而是拿到一份源码却发现缺文件、跑不起来、数据库连不上。这份标题为“基于Python的BERT深度学习文本相似度检测系统”的资源是一套完整的毕业设计项目包含前端页面、后端接口、BERT模型调用、MySQL数据库以及一份Python部署说明文档。它不是那种只给几个核心py文件的半成品而是把部署文档、数据库脚本和主代码目录都打包好的整包资源适合拿来做Python方向的毕业设计或课程设计也适合想快速上手BERT文本相似度实战的开发者。项目技术栈是Python 3.6.8 MySQL 5.7 BERT开发工具用PyCharm数据库管理用Navicat 11。文本相似度检测的本质是衡量两句话在语义层面是否接近BERT通过双向Transformer捕捉上下文信息把句子编码成向量再算余弦相似度。这个项目把从数据处理、模型调用到前端展示的完整链路都串起来了我拆解这份源码后把环境搭建、代码结构、核心实现和踩坑记录整理成了这篇笔记你可以按步骤复现。2. 环境搭建版本锁定是第一道关卡既然是毕业设计源码环境版本就不能随便升级。项目指定的Python 3.6.8、MySQL 5.7、Navicat 11、PyCharm组合是有原因的我一层层说清楚。2.1 Python 3.6.8为什么不能直接用最新版Python 3.6.8发布于2018年技术上已经不算新但很多深度学习依赖库的版本兼容矩阵还在以它为准。BERT模型相关的tensorflow、keras、transformers库在Python 3.6.8下有大量预编译的wheel包装起来不用编译源码能省很多时间。而Python 3.9以上版本装tensorflow 1.x会直接报编译错误这类问题在毕业设计阶段是比较难排查的。安装Python 3.6.8时要注意勾选“Add Python to PATH”否则后续pip命令会提示找不到。装完后在命令行验证版本python --version # 期望输出Python 3.6.8 pip --version # 期望输出pip 20.x.x如果pip版本过高建议先降级这里有一个细节Python 3.6.8自带的pip版本较旧如果你用最新版pip下载依赖部分老库的安装可能会报“Invalid requirement”之类的错误。稳妥的做法是先把pip降级到20.2.4版本再开始装依赖python -m pip install pip20.2.4 -i https://pypi.tuna.tsinghua.edu.cn/simple清华大学镜像源是给国内开发机装Python库的常用选择网速比直接访问PyPI快得多。如果镜像源里找不到某个包再切回官方源即可不需要纠结。2.2 MySQL 5.7与Navicat 11数据库初始化步骤MySQL数据库在这个系统里负责存储文本语料和相似度计算结果。项目压缩包里有一个“数据库”文件夹里面通常是建表SQL脚本。用Navicat 11连接到本地MySQL服务后新建一个名为text_similarity的数据库字符集选择utf8mb4排序规则选utf8mb4_general_ci然后导入SQL脚本。# 如果不想用Navicat图形界面也可以用mysql命令行导入 mysql -u root -p123456 -h localhost --default-character-setutf8mb4 # 登录后执行 CREATE DATABASE IF NOT EXISTS text_similarity DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci; USE text_similarity; SOURCE /path/to/database/text_similarity.sql;数据库连接配置在项目的配置文件里比如BConfig.py或settings.py要把用户名和密码改成你自己机器上的值。MySQL 5.7默认的认证插件是mysql_native_passwordPython的pymysql库能直接连上。如果你用的是MySQL 8.0以上版本认证方式变成了caching_sha2_passwordpymysql版本太老会报“Authentication plugin caching_sha2_password cannot be loaded”的错误这也是很多人在环境阶段翻车的点。2.3 PyCharm中导入project目录解压后你能看到“project”目录这就是主工程目录。用PyCharm打开project目录然后在File → Settings → Project Interpreter里选择Python 3.6.8的解释器。PyCharm会自动扫描项目里的依赖文件如果项目根目录有requirements.txt直接点Install All即可。# 如果PyCharm的包安装工具卡住可以在Terminal里手动执行 pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple # 常见依赖包含flask、pymysql、jieba、numpy、pandas、tensorflow等依赖里很可能包含tensorflow或transformers这类体积较大的包安装时间可能持续10到20分钟这期间不要强制中断。如果你是用CPU跑BERT模型那tensorflow请选择CPU版本不要装GPU版否则会因为缺少CUDA动态库直接启动报错。3. 源码结构与数据库设计先读懂再动手改拿到源码最忌讳一上来就双击运行。先把目录结构和数据库表看懂后面再改代码或调试会顺畅很多。3.1 压缩包五个组成部分拆解解压后的文件名列表里有“python部署说明文档.zip”“数据库”“LW”“project”其中LW文件夹通常存放的是论文相关文档project里才是主代码。这份资源的逻辑很清晰部署文档教你配环境数据库文件夹给你建表脚本project是能运行的系统本体。project目录内部常见的结构如下文件/目录作用app.py 或 run.pyFlask后端入口启动Web服务BERT模型相关py文件加载BERT、编码句子、计算相似度templates/HTML模板文件前端页面渲染static/layui.css、bootstrap.min.css等静态资源config.py数据库连接、模型路径等配置static目录里有bootstrap.min.css、layui.css、animate.css、font-awesome.min.css、style.css、layer.css、chartist.min.css等文件说明前端用的是layui框架加Bootstrap混合方案。layer.css负责弹窗组件样式chartist.min.css是图表库说明管理系统页面里大概率有相似度分布的可视化图表。这些静态资源是前端页面能正常展示的基础不要随意删除。3.2 数据库表结构与业务字段梳理数据库脚本里的表设计决定了系统的数据流转方式。常见的设计是这样的句子表存储待比较的文本数据每条记录有唯一的id相似度结果表记录两两句对之间的得分前端页面从相似度结果表读取历史记录展示到表格里。-- 典型的句子表结构 CREATE TABLE sentence ( id int(11) NOT NULL AUTO_INCREMENT, content varchar(500) NOT NULL COMMENT 句子内容, create_time datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 相似度结果表 CREATE TABLE similarity_result ( id int(11) NOT NULL AUTO_INCREMENT, sentence1_id int(11) NOT NULL, sentence2_id int(11) NOT NULL, score float DEFAULT NULL COMMENT BERT相似度得分, create_time datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;注意字段类型的选择句子内容用varchar(500)且字符集为utf8mb4这样才能存中文和生僻字。相似度得分用float类型BERT输出的相似度值在0到1之间float足够的精度。为什么不用double因为相似度本身是余弦值不需要超高精度float在存储和查询性能上都更优。3.3 前端与后端的交互链路这个项目的交互逻辑是开箱即用的用户在Web页面输入两段文本点击计算按钮前端通过Ajax把文本POST到后端Flask接口后端调用BERT模型编码文本得到向量计算余弦相似度后返回JSON前端把得分显示到页面上同时记录写入MySQL。# Flask后端路由的简化示意 app.route(/api/similarity, methods[POST]) def calc_similarity(): data request.get_json() text1 data[text1] text2 data[text2] score bert_similarity(text1, text2) # 记录到数据库 save_record(text1, text2, score) return jsonify({score: score})这个路由是整个系统请求入口的核心。如果前端页面调不通接口先检查Flask是否在监听0.0.0.0而不是127.0.0.1前者才能在局域网内被访问后者只能本机访问。4. BERT模型加载与相似度计算核心代码的逐行解析文本相似度检测的核心是把文本变成向量。BERT做这件事的思路是文本输入后经过多层双向Transformer编码输出一个768维的向量BERT-Base版本然后计算两个向量的余弦相似度。这个项目用Python实现这一流程代码量不大但涉及的坑不少。4.1 BERT原理简述双向编码器为什么能理解语义BERT全称是Bidirectional Encoder Representations from Transformers核心创新在于用双向Transformer替代传统的单向语言模型。传统模型读句子时只能从左往右或者从右往左BERT通过掩码语言模型的方式同时看到左右两侧的上下文因此能获取更完整的语义信息。具体到文本相似度场景BERT会把“苹果手机电池不耐用”和“iPhone续航表现不佳”编码成两个高维向量因为这两句话的语义相近向量的余弦相似度会明显高于字面差异很大的句子对。这是传统TF-IDF、词向量方法做不到的也是项目选择BERT的根本原因。4.2 bert_serving方式或直接用transformers库加载加载BERT有两种常见做法一种是用bert-as-service把模型独立成一个服务进程另一种是直接用transformers库在代码里加载。毕业设计环境里我更推荐transformers库方式因为它不需要额外维护独立服务进程代码直观调试方便。from transformers import BertTokenizer, TFBertModel import numpy as np # 加载预训练模型和分词器 model_name ./bert_model/chinese_L-12_H-768_A-12 tokenizer BertTokenizer.from_pretrained(model_name) model TFBertModel.from_pretrained(model_name) def get_sentence_vector(text): # 对文本进行分词、编码并控制最大长度 inputs tokenizer( text, max_length128, truncationTrue, paddingmax_length, return_tensorstf ) # 获取BERT最后一层输出 outputs model(inputs) # 取[CLS]位置的向量作为句子向量 sentence_vector outputs.last_hidden_state[:, 0, :].numpy()[0] return sentence_vector def bert_similarity(text1, text2): vec1 get_sentence_vector(text1) vec2 get_sentence_vector(text2) # 计算余弦相似度 cos_sim np.dot(vec1, vec2) / (np.linalg.norm(vec1) * np.linalg.norm(vec2)) return float(cos_sim)这段代码两个关键点说明max_length128是文本截断长度BERT对超过长度的部分直接截断。对短文本相似度检测来说128个token足够用设置太大会增加计算时间太小则会丢失尾部语义。中文BERT的分词器会把句子拆成字或词的粒度128个token大约能覆盖100到120个汉字。取outputs.last_hidden_state[:, 0, :]这行表示取出每个样本的第一个token位置也就是[CLS]标记的输出向量。BERT预训练时[CLS]位置的向量被设计成聚合整个句子语义的代表向量所以用它做相似度计算是BERT应用的通行做法。4.3 相似度分数归一化处理余弦相似度天然在-1到1之间但文本语义相似度的展示场景下通常希望分数映射到更直观的区间。很多人在这一步直接输出原始值但模型对文本编码后的余弦值分布并不均匀有些语义不同的句子也可能拿到0.7以上的分数。所以项目通常在原始分数基础上做一次变换def normalize_score(cos_sim): # 把-1到1的余弦值映射到0到100的展示分 normalized (cos_sim 1) / 2 * 100 return round(normalized, 2)这样前端页面展示的分数范围是0到100人眼看起来更直观。这里有一个参数选择的细节映射公式的线性程度取决于你的数据分布如果相似度值普遍集中在0.8到1.0之间线性映射后区分度不够可以考虑用指数或对数变换拉伸区间。但毕业设计场景下线性映射已经够用追求复杂变换反而增加解释难度。4.4 模型文件存放路径踩坑transformers的from_pretrained方法需要一个本地模型目录。你下载的bert_model文件夹里应该有配置文件、词表文件和权重文件缺少任何一部分都会报错。# bert_model目录应该包含的文件 bert_model/ ├── bert_config.json # 模型结构配置文件 ├── bert_model.ckpt.index # TF格式权重索引 ├── bert_model.ckpt.data-00000-of-00001 # 权重数据 ├── pytorch_model.bin # PyTorch格式权重部分版本有 └── vocab.txt # 中文词表代码里的model_name ./bert_model/chinese_L-12_H-768_A-12是相对路径相对路径依赖启动目录。在PyCharm里运行时默认工作目录是project根目录相对路径没有问题。但如果你在命令行里直接切到其他目录执行python脚本就会报找不到模型的错误。出现这种情况就把路径改成绝对路径或者先cd到project根目录再启动。5. 常见问题与排查我踩过的六个坑及其处理方案环境搭建和首次运行阶段的问题最多。这一节把高频问题按“现象 → 原因 → 解决”的方式整理出来你在复现时大概率会遇到其中至少三条。5.1 启动后页面打不开或白屏现象运行app.py后控制台有启动信息但浏览器访问http://127.0.0.1:5000显示白屏或连接不上。原因一种情况是Flask监听了错误的IP地址另一种是模板文件或静态资源路径缺失导致页面渲染失败。解决检查app.py里app.run(host127.0.0.1, port5000)这一行。如果局域网内需要用同一网段的机器访问把host改成0.0.0.0。若是白屏则打开浏览器开发者工具查看Network面板里静态资源的HTTP状态码404的话就说明templates和static的目录结构不对需要在Flask初始化时指定正确路径。5.2 本地模型加载报错而不自动下载现象执行from_pretrained时报“OSError: Cant load model”或者提示找不到文件。原因很多教程默认transformers会自动从Hugging Face下载模型但国内网络环境大概率下载失败。项目必须使用本地模型文件。解决确认bert_model文件夹路径正确且权重文件完整。我建议在代码里加一段路径判断import os model_path os.path.abspath(./bert_model/chinese_L-12_H-768_A-12) assert os.path.exists(model_path), f模型目录不存在: {model_path} print(模型路径正常:, model_path)把断言放在加载前至少能让报错信息更明确。如果权重文件是从网上下载的注意不要用浏览器直接打开txt文件导致编码被改动截断模型文件必须保持二进制原样。5.3 MySQL连接报pymysql和cryptography相关错误现象启动项目后调用数据库功能报错信息类似“RuntimeError: cryptography package is required for sha256_password or caching_sha2_password auth methods”。原因新版MySQL使用caching_sha2_password认证插件而项目里用的pymysql版本太老不支持。解决把MySQL用户改成mysql_native_password认证方式在MySQL命令行执行ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 123456; FLUSH PRIVILEGES;顺便升级pymysql到最新版本pip install --upgrade pymysql。两步都做通常能解决认证问题。注意如果你用Navicat连接数据库没问题但Python连接报错基本就是这个认证方式的问题。5.4 前端页面图表不显示现象页面上的表格数据能展示但图表区域空白。原因chartist.min.js脚本文件没有正确加载或者传给图表组件的JSON数据格式是字符串而不是对象。解决打开浏览器Network确认chartist.min.js状态为200。数据格式问题则要在JavaScript里添加parse转换比如JSON.parse(response)再传给图表库。这个问题常见于jQuery的ajax回调默认返回已经是对象但代码里又做了一次字符串拼接。5.5 中文乱码问题现象MySQL里查询出来的中文显示为问号或乱码。原因数据库表格字符集是latin1或者Python连接MySQL时没有指定charset参数。解决创建数据库时用utf8mb4连接时在代码里明确指定import pymysql conn pymysql.connect( hostlocalhost, userroot, password123456, databasetext_similarity, charsetutf8mb4 )这里有个细节MySQL的utf8mb4和utf8的区别在于前者能存储四个字节的emoji表情和生僻字而且大多数现代MySQL版本下这两个字符集在索引长度上的表现也不同。代码里写charsetutf8mb4是最稳的。5.6 tensorflow版本与Python版本不兼容现象pip安装tensorflow后import报“ImportError: DLL load failed”或者“ModuleNotFoundError: No module named tensorflow”。原因装了GPU版tensorflow但没有CUDA库或者tensorflow版本要求Python版本高于3.6。解决在Python 3.6.8环境下固定安装tensorflow-cpu1.14.0或tensorflow2.4.0注意2.4.0也支持Python 3.6。不要尝试安装tensorflow 2.10以上版本那个已经要求Python 3.7到3.10了。如果项目源码里用的是keras注意keras和tensorflow版本也要匹配我见过有人单独装了最新keras然后和tensorflow 2.4冲突的情况实际bundle安装即可。6. 进阶玩法批量文本去重与阈值调优的实测技巧基础功能跑通后这个系统还有明显的扩展空间。毕业设计如果需要加分建议在批量文本去重场景下做一些参数调优实验既能展示对业务场景的理解又能体现数据分析和模型调优能力。批量检查文本相似度时如果语料有1000条句子两两比较就是接近50万对组合逐条调用BERT计算会非常耗时。常见的工程做法是先把所有句子离线编码成向量保存到数据库需要比较时只在内存里做向量点积运算不再重复跑模型。在“数据库”文件夹里新增一张向量表CREATE TABLE sentence_vector ( id int(11) NOT NULL, vector blob COMMENT BERT向量序列化后存储, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;向量序列化用numpy的save和load即可把768维float数组存成bytes对象写进blob字段。这样首次编码花一些时间后续每次比较只需要读取向量做矩阵运算速度能提升两个数量级。阈值调优方面我给你一个实测参考用中文文本相似度公共数据集做评测设置0.75为相似阈值时查全率约90%查准率约85%。如果你把阈值调到0.8查准率能到95%但查全率掉到75%。具体到你的应用场景拿200对人工标注过的样本跑一遍画出P-R曲线选阈值点比拍脑袋定0.5要严谨得多。这组实验本身就是一个很漂亮的论文章节。我总结一下个人习惯每次改完参数后先清空similarity_result表再做小批量验证因为MySQL里残留的旧结果会影响页面展示的准确性然后跑程序前强制检查模型目录是否存在这是个低成本但能避免无效工作流的习惯。希望这套拆解能帮你少走弯路祝项目顺利。本文还有配套的精品资源点击获取
返回列表