资讯中心

基于Python的虚假新闻检测实战:从TF-IDF文本分类到Flask接口

📅 2026/10/9 10:14:44
基于Python的虚假新闻检测实战:从TF-IDF文本分类到Flask接口
简介面向毕业设计、课程设计与项目开发场景的Python虚假新闻检测工程覆盖文本预处理、模型训练、效果评估与Web可视化全链路。压缩包共16个文件以9个Python脚本为核心分别实现CNN、LSTM、BERT及传统机器学习等模型构建与训练流程另有4个CSV数据集、环境依赖列表和开发文档包体约6.07MB目录划分简洁便于直接定位关键模块。目前已有204人学习下载。源码已经过严格测试可直接运行参考项目包含数据构造训练集/测试集、多种模型对比、AUC指标计算以及基于Web的检测界面适合掌握Python基础、希望深入理解文本分类或快速产出课程设计成果的开发者。在完成现有流程后还可替换数据集、调整模型参数或扩展为实时新闻检测接口留有充足提升空间。1. 虚假新闻检测到底是什么一个文本分类项目凭什么能撑起毕业设计很多同学拿到“基于python开发的虚假新闻检测”这个题目第一反应是写爬虫去抓新闻再去第三方平台一条条求证真伪做着做着把自己绕成了一个舆情系统。实际上它本质是一个文本二分类任务给定一条新闻文本让模型判断它是真实还是虚假。这个题目能成为毕业设计、课程设计里的常客是因为它把自然语言处理、机器学习和 Web 接口三件事揉在了一起难度可控、演示效果好而且无论你以后走算法方向还是开发方向都能从中提取出能写进简历的产出。适合谁做想入门 NLP 的学生、需要交一个完整课设作品的人以及想用最短路径体验“数据—模型—接口—文档”全流程的初学者。下文按我实际做这类项目的顺序展开照着复现即可。2. 技术选型和数据准备把“检测”拆成可实现的分类任务2.1 为什么选 Python从语言生态到交付效率选语言这件事很多学生是随手选的 Python但答辩时被问到“为什么不用 Java”就卡住了。我的答案一般是三条第一NLP 生态几乎全在 Python 这边做文本分类要用的 sklearn、jieba、transformers、pandas 全是 Python 系的Java 那边要么封装不全要么你得自己造轮子第二模型训练和评估阶段的交互效率高写几行代码就能看到指标变化这对课程设计的时间预算非常友好第三Python 写 Web 接口不拖后腿Flask 起一个服务只要十几行代码和训练代码统一语言不用像 C 那样搞两套工程。这里有个新手常踩的坑装 Python 时没勾选“Add Python to PATH”导致命令行里python命令失效后面所有安装步骤都跟着翻车。我一般建议用 Anaconda 管理环境创建独立环境给项目用避免把系统 Python 弄乱。IDE 方面pycharm 配置 python 环境比较省心但要确认解释器选的是 conda 环境里的那个不是系统自带的老版本vscode 配置 python 环境也简单只要右下角选对解释器即可。语言版本建议 3.8 到 3.10太新的版本偶尔会和旧版第三方库有兼容问题。2.2 数据怎么来公开数据集与自建口径虚假新闻检测的数据集业内常见做法是用公开的 fake news 数据集结构一般是两列新闻文本、标签 0/10 代表真实1 代表虚假。课程设计级别 5000 到 1 万条足够跑通流程毕业设计建议准备 2 万条以上否则模型很容易过拟合。国内场景如果要自己做常见做法是用爬虫采集新闻网站的公开内容再人工标注但要注意采集合规和标注口径统一工作量比想象中大。我的建议是第一优先用现成公开数据集把时间省给模型和文档第二要检查数据集的类别分布很多公开数据里真假比例接近 1:1但实际场景中虚假新闻永远是少数训练时你心里要有这个数第三统一字段命名项目里所有脚本只认title标题、text正文、label标签三个字段后面处理会省很多事。数据文件建议按下面的结构组织源码、数据、文档分开这也是答辩老师比较认可的项目结构。目录用途说明data/raw/原始数据集从公开渠道拿到的原始 CSV不做任何修改data/processed/清洗后的数据去重、去空、标签映射之后的训练/测试集src/源码目录数据处理、训练、评估、预测的脚本都放这里models/模型输出训练好的模型文件和评估报告docs/开发文档设计说明、接口文档、答辩 PPT 素材2.3 数据清洗与标签构造先把脏数据处理成模型能吃的样子拿到原始 CSV 之后第一步不是训练而是清洗。这里面最容易翻车的点是标签列里混了字符串比如True/Fake、正文里有大量空值、同一篇新闻重复出现。我一般用 pandas 一把梭处理import pandas as pd from sklearn.model_selection import train_test_split # 加载原始数据指定列为 title/text/label df pd.read_csv(data/raw/news.csv, usecols[title, text, label]) # 标签统一为 0/1字符串映射到数值 label_map {true: 0, fake: 1, True: 0, Fake: 1} df[label] df[label].astype(str).str.lower().map(label_map) # 去掉标签缺失或无效的行 df df.dropna(subset[label]) # 正文和标题都为空的行直接丢弃 df df.dropna(subset[text], howall) df df[df[text].str.strip() ! ] # 按正文去重保留第一条 df df.drop_duplicates(subset[text], keepfirst) # 构造模型输入标题 正文拼接 df[content] df[title].fillna() df[text] # 按标签分层划分训练集和测试集保证类别比例一致 train_df, test_df train_test_split( df, test_size0.2, random_state42, stratifydf[label] ) train_df.to_csv(data/processed/train.csv, indexFalse) test_df.to_csv(data/processed/test.csv, indexFalse) print(train_df[label].value_counts())代码里几个关键点说明一下usecols只读需要的列避免把无关字段读进来干扰判断astype(str).str.lower()先把标签统一成小写字符串再做映射能兼容True和true两种写法drop_duplicates(subset[text])按照正文去重因为很多假新闻会被反复转载不去重会导致模型在重复样本上“背答案”。train_test_split的stratifydf[label]参数很重要它保证切分后训练集和测试集里真假样本比例一致否则测试集里如果恰好全是真实新闻指标会虚高。3. 模型训练与系统封装从 TF-IDF 到深度学习的落地路径3.1 快速基线TF-IDF 逻辑回归能跑多高很多教程一上来就让学生用深度学习但我做课程设计项目的习惯是先跑一个传统基线。TF-IDF 逻辑回归在虚假新闻检测上通常能到 85% 以上的准确率训练只要十几秒而且模型可解释性很强——你打印权重最高的几个词就能看到模型是根据哪些词做出的判断。这套方案用来交课程设计已经够用毕业设计则把它作为基线后面用深度模型去对比。import joblib from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.linear_model import LogisticRegression from sklearn.pipeline import Pipeline from sklearn.metrics import classification_report, accuracy_score import pandas as pd train_df pd.read_csv(data/processed/train.csv) test_df pd.read_csv(data/processed/test.csv) # 使用 TfidfVectorizer 做特征提取 vectorizer TfidfVectorizer( max_features20000, # 只保留出现频率最高的 2 万个词 ngram_range(1, 2), # 同时考虑单个词和相邻两个词 min_df2, # 至少在 2 篇文档中出现过才保留 sublinear_tfTrue, # 用 1log(tf) 平滑词频减轻高频词主导 ) model Pipeline([ (tfidf, vectorizer), (clf, LogisticRegression(C1.0, max_iter1000)), ]) # 训练并用测试集评估 model.fit(train_df[content], train_df[label]) pred model.predict(test_df[content]) print(accuracy:, accuracy_score(test_df[label], pred)) print(classification_report(test_df[label], pred, target_names[real, fake])) # 保存模型后续预测和 Web 接口都要用到 joblib.dump(model, models/lr_baseline.joblib)参数说明max_features20000控制特征维度过小会丢失低频有用词过大会让训练变慢且容易过拟合我一般从 2 万起步再调ngram_range(1, 2)是效果提升最明显的参数因为“不是假新闻”这类否定表达要靠双词组合才能捕获C1.0是逻辑回归的正则化强度C 越小正则越强避免模型过度依赖少数词sublinear_tfTrue做了词频压缩让“的”“了”这类高频词对权重的影响变小。训练完之后打印classification_report要重点看 fake阳性类的 precision 和 recall对一个检测系统来说漏掉一条假新闻比误伤一条真新闻通常更严重。3.2 进阶用预训练模型提升效果如果基线的准确率到不了你想要的分数或者导师明确要求用深度学习常见做法是上预训练模型。两个路线一是 LSTM训练快、对显存要求低但效果一般只比 TF-IDF 高两个点左右二是用中文预训练模型比如 BERT 系列效果最高但需要 6GB 以上显存训练时间按小时算。我一般建议课程设计选 LSTM毕业设计有服务器的话再考虑 BERT。import torch from torch.utils.data import Dataset, DataLoader from transformers import BertTokenizer, BertForSequenceClassification # 加载中文预训练模型的分词器和模型 model_name bert-base-chinese # 按需替换为实际可用的模型名称 tokenizer BertTokenizer.from_pretrained(model_name) model BertForSequenceClassification.from_pretrained(model_name, num_labels2) # 把新闻文本编码成模型输入格式 def encode_texts(texts, labels, max_len128): encodings tokenizer( texts, truncationTrue, paddingTrue, max_lengthmax_len, return_tensorspt ) return encodings, torch.tensor(labels) # 注意这里只演示数据装载逻辑 train_texts train_df[content].tolist()[:100] # 实际训练不应截断 train_labels train_df[label].tolist()[:100] inputs, label_tensor encode_texts(train_texts, train_labels) # 后续用 DataLoader 封装按 batch16 喂给模型这里要强调truncationTrue和max_length128必须设置否则长新闻会被模型当作超长输入导致显存溢出paddingTrue把同一批次的文本补到等长是 GPU 批量计算的前提。预训练模型的输入长度和 TF-IDF 相比更敏感我踩过 512 长度的坑——显存直接爆掉后来改成 128 长度指标只掉了零点几个点训练速度却快了三倍。如果你的计算机配置一般老老实实max_length128。3.3 把模型包成 Web 接口用 Flask 跑一个能演示的检测服务模型训练完毕项目还差最后一环把它变成能演示的东西。答辩现场不可能打开 Jupyter Notebook 跑训练更常见做法是用 Flask 起一个本地服务输入新闻文本返回检测结果。这个接口同时会写进开发文档是“源码 开发文档”交付物里最能体现工程能力的部分。import joblib from flask import Flask, request, jsonify app Flask(__name__) # 加载训练好的模型路径和 3.1 节保存的一致 model joblib.load(models/lr_baseline.joblib) app.route(/predict, methods[POST]) def predict(): data request.get_json() text data.get(text, ) if not text.strip(): return jsonify({error: text 不能为空}), 400 prob model.predict_proba([text])[0] # 预测为真/假的概率 label int(model.predict([text])[0]) # 0真实1虚假 return jsonify({ label: label, probability: round(float(prob[label]), 4), result: fake if label 1 else real, }) if __name__ __main__: # 本机演示用 5000 端口生产部署时换 gunicorn app.run(host0.0.0.0, port5000, debugFalse)这段接口逻辑里有几个工程细节用request.get_json()解析请求体前端传入{text: 新闻内容}这样一条 JSON空文本返回 400 错误避免无意义的预测predict_proba返回的是两个类别的概率数组下标 0 对应真实、1 对应虚假取prob[label]得到模型当前判断的置信度。启动后可以用 curl 做一次冒烟测试注意 Windows 下 curl 需留引号格式curl -X POST http://127.0.0.1:5000/predict \ -H Content-Type: application/json \ -d {\text\: \某地今日开始实施新交通规则所有车辆单双号限行\}4. 避坑指南虚假新闻检测项目最常翻车的 6 个节点4.1 现象训练集准确率 99%测试集只有 60%这是最典型的翻车现场原因基本是两个一是数据泄漏清洗时把标签相关的信息带进了特征里二是过拟合模型把训练集里的新闻标题背了下来。解决方法是先检查特征构造content里只能有标题和正文文本绝不能拼接来源域名、发布时间这类字段然后看训练样本量如果只有一两千条先加数据加不了就把max_features和C往小调用更强正则。4.2 现象标题和正文拼接后效果反而变差原因在于拼接顺序和权重失衡。新闻标题通常很短但信息密度高正文很长却充斥着套话直接title text会让模型被正文的长文本淹没。我一般把标题重复一遍拼在前面比如f{title} {title} {text}或者单独对标题计算 TF-IDF 特征后和正文特征拼接这两种做法都能明显提升 F1。参数上可以把ngram_range上限从 2 调到 3标题里常见的“据传”“辟谣”“紧急”往往以三词短语形式出现。4.3 现象模型把“来源缺失”当成了虚假信号如果数据里有“来源链接”字段清洗时顺手拼进了特征模型会学到“有链接 真实没链接 虚假”这种捷径。测试集里一旦出现带链接的虚假新闻模型直接判断为真实。解决方法是清洗时把字段白名单收紧只保留title和text其他字段一律不进入模型输入。这个坑在答辩时被导师问到的概率极高因为它反映的是对数据泄漏的理解深度。4.4 现象环境反复装不上torch 或 transformers 一直报错来源多是两个一是 conda 环境和 pip 环境混用包装到了不同的地方二是 Python 版本和 CUDA 版本不匹配导致 torch 装上了但 GPU 用不了。我的建议是删掉重来新建一个干净的 conda 环境然后按顺序安装先装 CPU 版 torch哪怕机器有 GPU也先跑通流程再考虑 GPU 加速再装 transformers 和 sklearn最后装 Flask。装依赖时注意pip install的输出看到ERROR: No matching distribution就确认是不是源的问题。4.5 现象开发文档写成实验报告答辩时答不上来“你做了什么”很多同学把开发文档写成了“数据预处理用了什么函数、模型用了什么算法”的流水账。实际的开发文档要有问题定义、方案对比、实验表格、接口文档和部署说明重点回答“为什么这么设计”而不是“我用了什么”。例如写特征选择你想用 TF-IDF 不是因为它比 BERT 好而是因为它能在小数据量下稳定达标、训练快速、可解释性强——这是工程权衡不是技术崇拜。源码和文档必须在同一台干净机器上能重跑答辩时这是我最爱检查的一件事。5. 把项目做成能演示、能答辩、能交付的完整作品5.1 一键运行的预测脚本前面 Flask 接口是给别人看的自己调试时更常用的是一个独立预测脚本输入一句新闻直接打印判定结果和置信度。我把这个脚本命名为predict.py放在项目根目录一句话就能跑# predict.py 使用训练好的模型对单条文本预测 import joblib import sys model joblib.load(models/lr_baseline.joblib) if len(sys.argv) 1: text .join(sys.argv[1:]) else: text input(请输入要检测的新闻文本: ) prob model.predict_proba([text])[0] label int(model.predict([text])[0]) print(f判定结果: {虚假 if label 1 else 真实}) print(f置信度: {prob[label]:.4f})运行方式就是python predict.py 你的新闻文本内容无需启动 Web 服务也能完成演示。这个脚本的价值在于演示时不需要建前端页面直接在终端里输入一句话就能看到结果答辩现场网络环境不稳定时这是最可靠的兜底方案。5.2 开发文档的黄金结构开发文档是毕业设计和课程设计评分的重要组成部分不写或写成流水账都会很吃亏。我给自己项目定的文档结构是七章你可以直接套用章节内容要点1 项目概述背景、问题定义、目标说清楚“检测虚假新闻”具体是什么任务2 需求分析功能需求、非功能需求接口输入输出、准确率目标、运行环境3 总体设计系统架构、模块划分数据模块/训练模块/接口模块的依赖关系4 详细设计与实现数据处理、特征工程、模型选型为什么选 TF-IDF 逻辑回归实验对比表格5 测试与评估测试集上的准确率、F1、样例展示放 3 到 5 条真实预测结果截图6 项目总结与展望不足与改进方向写明当前模型对短文本和反讽句识别差7 附录环境依赖、运行说明pip install -r requirements.txt可一键重建环境我做这类项目的个人习惯是每次调完参数就把旧的模型文件备份成lr_baseline_v2.joblib再覆盖不直接删除因为答辩时导师如果问“你调过哪些参数、效果怎么变化的”有历史文件作证比口头描述可信得多。这个习惯帮我避免过好几次“调参调丢了最佳模型”的悲剧。无论你最后选 TF-IDF 还是预训练模型这个项目的核心价值是让你完整走了一遍“拿到真实数据、清洗、建模型、评估、包接口、写文档”的闭环。源码能跑通是及格线能解释每个设计决策才是拿高分的关键。希望这篇实战笔记帮到你。本文还有配套的精品资源点击获取

看完文章,想为自己的企业也做一次专业网站诊断?

尧图顾问免费为您评估现有网站,并给出建站/改版建议与报价方案。

免费获取方案