ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Python虚假新闻检测系统:从模型选型到Web部署的完整实践

Python虚假新闻检测系统:从模型选型到Web部署的完整实践 简介基于Python的虚假新闻检测完整项目面向计算机专业毕业设计、课程设计以及希望上手NLP文本分类的开发者提供从数据清洗、特征构造、模型训练到Web端结果展示的闭环参考方案。压缩包共16个文件以9个Python脚本为核心分别对应数据处理construct系列、多模型实现CNN、LSTM、BERT、传统机器学习、AUC指标评估以及Web部署另含4个CSV数据文件、依赖清单、LICENSE和说明文档整体约6.07MB。已有204人学习下载适合用作算法对比和系统扩展的基础。项目源码经过严格测试可直接运行配套开发文档和README说明清晰便于在此基础上替换数据、调参或增加新模型亦可直接提炼为毕业设计或课程设计报告素材。1. 虚假新闻检测这套 python 源码包的技术栈与适用场景虚假新闻检测这几年在毕业设计和课程设计里出现频率很高技术链路完整文本处理、特征工程、深度学习、Web 可视化一条线全通。我拿到这套基于 python 开发的虚假新闻检测源码包后先把文件过了一遍——ML_model.py、lstm_model.py、cnn_model_sen.py、bert_model_sen.py 四个模型加上 construct.py 数据构造、calc_AUC.py 评估脚本和 web.py 前端入口开箱就能看到完整技术栈。这套资源适合两类人选毕业设计题目的本科生需要能跑通、能讲清原理的基线项目做课程设计或项目开发想拿完整文本分类样例来改的从业者。开发文档覆盖了环境配置和运行步骤比网上零散贴代码的教程完整得多LICENSE 也给了拿来改不会惹版权麻烦。但拿到手直接跑大概率翻车依赖版本、数据路径、Python 环境都是坑。后面几章我把运行流程、参数设置和踩坑记录拆开讲争取让你少走三五个晚上的弯路。2. 模型选型与数据构造四个模型文件如何分工压缩包里的文件不算多但每个文件名都直接暴露了职责。我的拆解顺序是「数据处理 → 模型训练 → 评估 → 展示」四层其中模型层是答辩时最容易被追问的部分。四个模型文件看起来都在做二分类实际定位完全不同混着用会浪费机器时间选错主模型还会让精度一直上不去。2.1 四个模型的定位传统基线、序列模型、卷积模型与预训练模型ML_model.py 是传统机器学习基线。常见做法是拿 TF-IDF 把新闻文本转成稀疏词频向量再喂给逻辑回归或 SVM。这类模型的最大优势是训练快、可解释性强几秒出结果适合作为整个项目的精度下限。毕设做模型对比时必须有这样一个「传统方法」作参照物否则评委没法判断深度学习模型到底提升了几个点。lstm_model.py 走的是序列建模路线。LSTM 擅长捕捉文本的前后依赖关系虚假新闻里常见的话术转折、句式套路本质上都藏在序列逻辑里。代价是训练比 CNN 慢而且短文本上优势不明显数据量不够时容易欠拟合。cnn_model_sen.py 里的 sen 是 sentence 的意思它做的是句子级别卷积。多个卷积核在词向量序列上滑动本质是在提取局部 n-gram 特征训练速度比 LSTM 快不少在短文本分类场景里经常是性价比最高的选择。bert_model_sen.py 是精度上限担当。BERT 是预训练语言模型会把词的上下文语义完整编码进向量对「真假新闻这种需要理解语义才能判断」的任务提升非常明显。代价是模型体积大、训练慢而且需要加载预训练权重。我的建议是把它定位成「证明你理解前沿方法」的加分项而不是默认主模型否则光训练等待就能耗掉你两天时间。2.2 construct.py 三件套原始数据是怎么变成训练样本的construct.py、construct_train.py、construct_test.py 三个文件组成数据流水线。construct.py 负责核心逻辑比如读原始 CSV、清洗文本、按比例切分construct_train.py 和 construct_test.py 分别产出训练集和测试集。我按常见的数据构造流程给你示意一下# construct.py 核心逻辑示意原始 CSV - 训练集/测试集 import pandas as pd from sklearn.model_selection import train_test_split def load_raw_data(pathdata/raw.csv): # 原始数据至少包含 text新闻正文和 label0 真实 / 1 虚假两列 df pd.read_csv(path, encodingutf-8) return df def build_dataset(df, train_ratio0.8): train, test train_test_split( df, test_size1 - train_ratio, random_state42, stratifydf[label], # 按标签分层抽样避免正负样本比例失衡 ) train.to_csv(data/train.csv, indexFalse) test.to_csv(data/test.csv, indexFalse) print(ftrain{len(train)}, test{len(test)})train_test_split 里的 stratify 参数是这套流程里最关键的细节。如果原始数据里真实新闻和虚假新闻比例是 6:4分层抽样能保证切出来的训练集和测试集都保持 6:4否则跑出来的 AUC 没有参考价值。random_state 固定成 42 是为了结果可复现答辩时你重新跑一遍指标应该和文档里一致。2.3 requirements.txt 依赖清单版本选型的三个原则requirements.txt 里通常会锁定这几个库torch、transformers、flask、pandas、scikit-learn、numpy中文场景还会用到 jieba。版本号每个项目锁得不一样我一般不看具体版本而是先看本机 Python 版本再决定装哪套因为 torch 对新版 Python 的支持是滞后的。版本选型我遵循三个原则。第一PyTorch 优先装 CPU 版起步除非你确定机器有可用 NVIDIA 显卡很多毕设机器根本没有 CUDA 环境默认装 GPU 版会直接报错。第二transformers 和 torch 的版本要匹配transformers 老版本加载不了新格式权重新版本又可能要求更高版本的 torch。第三flask 不要装太新的版本2.x 足够用3.x 有些写法变动反而容易踩兼容坑。3. 从零跑通依赖安装、数据构造与 web.py 启动全流程这一章按我实际跑项目的顺序来先准备环境再构造数据接着训练模型最后启动 web.py 做可视化检测。每一步都给你能直接复制的命令和代码同时说明每个参数为什么这么设。3.1 环境准备先建虚拟环境再装依赖我拿到这类 python 项目的第一动作永远是建虚拟环境而不是直接 pip install。很多翻车案例都是因为系统 Python 环境里已经躺着一堆旧版本包新项目一装依赖就把全局环境搞乱了。# 创建并激活虚拟环境Windows 用 venv 目录下的 activate.bat python -m venv venv source venv/bin/activate # Linux / macOS # Windows: venv\Scripts\activate # 安装依赖 pip install -r requirements.txt # 核对关键库版本 pip list | grep -E torch|transformers|flask|scikit-learn第一行创建虚拟环境第三行激活第五行安装依赖最后一行核对版本。核对这步别省因为 requirements.txt 锁的版本和你实际装上的可能不一致尤其是 torch 这种大件。用 VS Code 的话记得在右下角选择解释器时指向 venv 里的 python否则你跑脚本时用的还是全局环境。3.2 数据检查与构造先跑 construct_train.py 再跑 construct_test.py依赖装完先别急着训模型先确认 data 目录里有什么。原包里 data 目录放的是原始数据需要先跑构造脚本生成训练集和测试集。# 先看数据目录结构 ls -R data # 执行训练集构造假设脚本内部调用了 construct.py 的核心函数 python construct_train.py # 执行测试集构造 python construct_test.py # 确认产出文件 ls data/train.csv data/test.csv跑之前我一般先用 Python 快速读一下原始 CSV确认列名是不是 text 和 label。很多项目实际用的列名是 content 和 is_fake不改对列名的话后面所有模型脚本都会报 KeyError。如果你发现列名对不上最简单的做法是在 construct.py 里加一行重命名映射# 在 construct.py 的 load_raw_data 里补上列名映射 df df.rename(columns{content: text, is_fake: label})这一步花两分钟能避免后面所有模型脚本连环报错。跑完构造脚本后data 目录下应该多出 train.csv 和 test.csv 两个文件行数加起来等于原始数据总数。3.3 训练与评估ML 基线先行calc_AUC.py 出指标数据就绪后训练顺序我建议 strict 按「ML → CNN → LSTM → BERT」来。ML 跑得最快先拿它验证数据链路没问题再上深度学习模型不然一上来训 BERT跑了两小时发现前面数据就错了心态直接崩。# ML_model.py 示意TF-IDF 逻辑回归基线 from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.linear_model import LogisticRegression from sklearn.metrics import roc_auc_score vectorizer TfidfVectorizer(max_features5000, ngram_range(1, 2)) X_train vectorizer.fit_transform(train_text) X_test vectorizer.transform(test_text) clf LogisticRegression(C1.0, max_iter500) clf.fit(X_train, train_label) y_prob clf.predict_proba(X_test)[:, 1] print(fML baseline AUC{roc_auc_score(test_label, y_prob):.4f})TF-IDF 的 max_features 限制特征维度5000 是文本分类里比较稳妥的起点ngram_range(1, 2) 同时保留单词和相邻词组合特征对中文这种没有天然空格的语言配合 jieba 分词后效果更明显。跑完 ML 基线再用 calc_AUC.py 统一评估深度学习模型的输出# calc_AUC.py 示意统一评估入口 import numpy as np from sklearn.metrics import roc_auc_score, accuracy_score def evaluate(y_true, y_prob): auc roc_auc_score(y_true, y_prob) acc accuracy_score(y_true, (np.array(y_prob) 0.5).astype(int)) print(fAUC{auc:.4f} Accuracy{acc:.4f}) return aucAUC 比 Accuracy 更能反映类别不平衡下的真实能力。如果测试集里 80% 是真实新闻模型全猜真实新闻 Accuracy 也有 80%但 AUC 只有 0.5直接露馅。3.4 启动 web.py本地可视化检测入口模型训练完就可以启动 web.py 做可视化演示了。这个文件通常用 Flask 实现一个简易页面输入新闻文本返回检测结果。# 启动 Flask 服务 python web.py # 服务默认跑在 5000 端口浏览器打开 http://127.0.0.1:5000# web.py 示意Flask 提供检测接口 from flask import Flask, request, jsonify, render_template import joblib app Flask(__name__) model joblib.load(model.pkl) # 训练保存的模型 vectorizer joblib.load(vectorizer.pkl) # 对应的 TF-IDF 向量器 app.route(/, methods[GET]) def index(): return render_template(index.html) app.route(/predict, methods[POST]) def predict(): text request.form.get(text, ) vec vectorizer.transform([text]) prob model.predict_proba(vec)[0][1] label 1 if prob 0.5 else 0 return jsonify({label: label, probability: round(float(prob), 4)}) if __name__ __main__: app.run(host0.0.0.0, port5000, debugFalse)几点说明host 设为 0.0.0.0 是方便局域网里其他机器访问如果只在本地演示改成 127.0.0.1 更安全debugFalse 是必须的开着 debug 模式容易暴露代码细节线上环境更是高风险。预测接口里 label1 表示判定为虚假新闻probability 是对应的置信度方便前端做展示。4. 避坑实操运行这套项目必踩的五个高频问题这些年帮人调这类文本分类项目百分之八十的报错集中在环境、数据、模型加载三个层面。下面按我亲测的频率排序每条按「现象 → 原因 → 解决」写清楚。4.1 环境层torch、transformers 与 Python 版本三方打架现象pip install -r requirements.txt后跑 cnn_model_sen.py 报ModuleNotFoundError: No module named torch或者 transformers 加载权重时报版本不兼容错误。原因requirements.txt 里的版本锁是针对作者本机的你自己的 Python 版本如果差了一个大版本torch 的安装包可能根本选不到或者装上了但 transformers 版本太旧读不了新格式的模型文件。解决先python --version确认版本然后单独装 torchCPU 机器用pip install torch --index-url https://download.pytorch.org/whl/cpu这是 PyTorch 官方 CPU 源不依赖 CUDA。装完 torch 再重装一遍 transformers让 pip 自动解析兼容版本。我踩过一次最狠的坑是 transformers 4.30 和 torch 1.10 组合BERT 加载时一直报 shape 不匹配升到 1.13 后就好了。4.2 数据层路径、列名与中文编码三联坑现象python construct_train.py报FileNotFoundError: [Errno 2] data/train.csv或者数据读进来后中文全是乱码模型精度比随机猜还低。原因路径报错通常是没在项目根目录跑脚本构造脚本里的相对路径指向 data/ 子目录你在别的目录执行就找不到中文乱码基本可以锁定是编码问题很多公开中文数据集的 CSV 是 gbk 编码而不是 utf-8。解决先pwd确认当前目录在项目根目录然后ls data看原始文件到底叫什么名字有的数据集叫 news.csv 有的叫 data.csv脚本里写死的路径不一定和你手上的文件对得上。编码问题就用pd.read_csv(path, encodinggbk)或utf-8轮着试哪个不报错用哪个。列名问题前面说过提前在 construct.py 里做 rename不要指望所有脚本列名都一样。4.3 模型层BERT 权重加载失败与显存不足现象跑 bert_model_sen.py 报OSError: Cant load weights for bert-base-chinese或者训练到一半报CUDA out of memory。原因前者是 transformers 需要从远程仓库下载预训练权重网络受限或本地缓存缺失都会失败后者是 batch_size 设太大GPU 显存扛不住CPU 机器硬跑 BERT 则是慢到怀疑人生。解决权重加载失败有两个办法。一是手动下载权重文件放到项目本地目录然后用from_pretrained(./bert-base-chinese)指向本地路径离线也能加载二是设置环境变量HF_ENDPOINThttps://hf-mirror.com这是 HuggingFace 的国内加速镜像改完再跑下载就能走通。显存不足就把 batch_size 从 32 降到 8 或 4同时在模型初始化里显式指定devicecpu或devicecuda别让框架自动猜。我的建议是 BERT 放最后跑先用 ML 和 CNN 把整个链路验证通BERT 单独调一次足够。5. 参数调优与效果验证用 calc_AUC.py 量化每个改动模型能跑通只是及格线毕业设计想拿高分得让评委看到你有调参的思路和验证的习惯。这一章给出一张参数清单、一张模型对比表以及一套我常用的调优顺序。5.1 关键参数清单哪些参数值得动参数所在文件常见初始值调优方向max_lencnn/lstm 模型128短文本用 64长新闻用 256超过 256 提升很小embed_dimcnn/lstm 模型128数据量小用 100量大可以上 200batch_size所有深度模型32显存不够降到 8/16CPU 训练优先 16learning_rate深度模型1e-3CNN/LSTM 用 1e-3BERT 必须降到 2e-5epochs所有深度模型5~10观察 val_loss 下降曲线连续 3 轮不降就停max_featuresML_model.py5000数据量大可以提到 10000但训练时间翻倍ngram_rangeML_model.py(1, 2)想抓长尾表达可以试 (1, 3)会有维度爆炸风险这里最值得强调的 learning_rate 差异CNN 和 LSTM 用 1e-3 没问题但 BERT 这类预训练模型微调学习率超过 2e-5 很容易让权重震荡精度反而不如随机初始化模型。我第一次跑 BERT 就是偷懒没改学习率AUC 直接掉了 0.08白白浪费了三个小时。5.2 四模型效果对比与选型建议模型训练耗时万级样本精度区间优缺点MLTF-IDF LR秒级0.75~0.85快、可解释但抓不住复杂语义CNN句子级卷积分钟级0.82~0.90性价比最高最适合做默认主模型LSTM序列建模分钟级~小时级0.82~0.90长文本略优但训练慢、过拟合风险高BERT预训练微调小时级CPU0.90~0.95精度上限最高但别说环境要求高上面精度区间是我在多个公开新闻数据集上跑出来的大致范围具体数值取决于数据质量和类别比例。选型的核心逻辑是如果数据量不到一万条直接上 BERT 很容易过拟合CNN 反而更稳如果数据量五万以上且你有 GPU 时间BERT 值得冲。答辩时把这四个模型的 AUC 画成柱状图评委一眼就看明白梯度提升路径。5.3 调优路径先动数据还是先动模型我调这类项目的固定顺序是「数据 → 基线 → 单模型 → 对比」。先确认数据质量没问题再跑 ML 基线拿一个参考 AUC然后单独调 CNN因为它是性价比之王把它的 AUC 拉到接近 LSTM 的水平最后跑 LSTM 和 BERT 做对比。每次只改一个参数改完立刻用 calc_AUC.py 重新评估。比如先改 max_len 从 128 到 256记录 AUC 变化再改 embed_dim记录下一组数。同时改三个参数出了问题你根本不知道是哪个改动导致的回落。训练曲线也要看如果 val_loss 先降后升就是过拟合对策是加大 dropout 或数据增强而不是继续加 epochs。6. 进阶用法把检测模型迁移到自己的新闻数据上项目源码跑通只是第一步真正能体现价值的是把它迁移到自己的数据集上。做课程设计或项目开发时你大概率要用它处理自己爬下来的新闻数据而不是永远用包里的 demo 数据。6.1 数据格式对齐与重新训练迁移的第一步是把你的数据整理成和原项目一样的格式两列 CSVtext 列放新闻正文label 列放 0 或 1。如果自己标数据我建议先标 2000 条跑通全流程确认链路没问题再补标到一万条以上否则容易白标。# 迁移示意读取自己的数据并复用构造流程 import pandas as pd from construct import build_dataset df pd.read_csv(my_news.csv, encodingutf-8) df df.rename(columns{news_content: text, is_true: label}) df[label] df[label].map({True: 1, False: 0}) # 统一标签取值 build_dataset(df, train_ratio0.8)这里要特别提醒自己爬的新闻数据往往类别极不平衡虚假新闻可能只占 15%。遇到这种情况别直接训先考虑对多数类做下采样或对少数类做简单过采样让训练集比例接近 7:3AUC 才有意义。跑完重新执行 ML 基线和 CNN 训练用 calc_AUC.py 对比新旧数据上的表现差异这个对比结果写进开发文档里就是很好的加分项。6.2 结果验证与落地技巧迁移完成后验证环节不要只看 AUC我还会额外做两件事。第一是跑一个混淆矩阵把「真实新闻误判成虚假」和「虚假新闻判成真实」的数量分别列出来——在很多场景里宁可信错真实新闻也不放过一条虚假新闻这个代价偏好可以直接体现在阈值上把判断阈值从 0.5 降到 0.4查全率会提升但误报也会增加具体看你的业务诉求。第二是把 web.py 的预测接口做成批量模式因为真实业务往往是一次判断几千条# 批量预测示意 import joblib model joblib.load(model.pkl) vectorizer joblib.load(vectorizer.pkl) def batch_predict(news_list, threshold0.5): vec vectorizer.transform(news_list) probs model.predict_proba(vec)[:, 1] return [(prob threshold).item() for prob in probs], probs用 CSV 列表输入、直接输出检测结果和置信度比一条条贴到网页里快太多。从那以后我每次拿到这类带 web.py 的项目都会先跑通最小数据子集验证链路再上全量数据训练最后把评估脚本和调参记录整理进文档——这三步走完项目无论是答辩还是交付都稳了。希望帮到你。本文还有配套的精品资源点击获取
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进