基于TF-IDF与MLP的虚假新闻检测器实战:从数据预处理到模型部署
简介这份资源是面向课程设计与机器学习入门者的互联网虚假新闻检测完整项目编号100011870核心是用Python多层感知器MLP完成新闻文本的二分类任务。项目覆盖数据预处理、分词与停用词过滤、TF-IDF或词嵌入特征工程、训练验证测试集划分、MLP模型构建与反向传播调优、测试集泛化评估等完整流程并涉及Numpy、Pandas、Scikit-learn、NLTK、TensorFlow或PyTorch等常用库适合想理解文本分类全链路的中级学习者。压缩包共19个文件约66.23MB包含py训练脚本、model模型文件、csv与pkl数据、xml配置、txt预测输出及docx实验报告结构清晰便于复现与二次开发。目前已有227人学习下载可帮助读者快速获得可运行的检测器实现、模型调参思路与实验报告参考。1. 拆开这个 MLP 虚假新闻检测器它到底能不能跑通网上关于虚假新闻检测的项目一抓一大把但真正能下载下来、解压、装完依赖、跑出准确率数字的没几个。我拿到这个编号 100011870 的压缩包时第一反应也是先看目录结构——fakenewsdetector、doc report.docx、LICENSE、ML fit.py、dataset、.idea、model、mlp_pred.txt、README.md。有数据集、有训练脚本、有模型目录、有预测输出文件还有一份 Word 报告说明这是一个完整的课程设计交付物不是半成品。它解决的核心问题很明确用 Python 的多层感知器MLP对新闻文本做二分类判断一条新闻是真实还是虚假。适合谁正在做 NLP 课程设计的学生、想快速搭一个文本分类 baseline 的工程师、以及需要理解 TF-IDF MLP 这套经典组合怎么落地的人。不适合指望开箱即用做生产级检测的人因为它的定位是教学和实验。2. 数据预处理与 TF-IDF 特征工程文本怎么变成 MLP 能吃的数字2.1 为什么选 TF-IDF 而不是词嵌入这个项目用的是 TF-IDF 向量化不是 Word2Vec 或 BERT 词嵌入。原因很实际MLP 是浅层前馈网络参数量有限TF-IDF 产生的是稀疏高维向量配合全连接层做分类在中小规模数据集上效果稳定训练速度快不需要 GPU。词嵌入虽然语义表达更强但需要额外训练或加载预训练模型对课程设计来说引入的复杂度不划算。常见做法是先用TfidfVectorizer把文本转成矩阵再喂给 MLP。这里有个关键参数max_features控制词汇表大小。设太大特征维度爆炸训练慢且容易过拟合设太小信息丢失严重。我一般会从 5000 开始试看验证集准确率再调。2.2 文本清洗与分词的可复现步骤原始新闻文本里混着 HTML 标签、URL、标点、数字这些对分类基本是噪声。下面是我按这个项目的数据特点写的预处理脚本可以直接抄import re import pandas as pd from sklearn.feature_extraction.text import TfidfVectorizer def clean_text(text): # 去掉 HTML 标签 text re.sub(r.*?, , text) # 去掉 URL text re.sub(rhttp\S|www\S, , text) # 只保留字母和空格 text re.sub(r[^a-zA-Z\s], , text) # 转小写 text text.lower() # 去掉多余空白 text re.sub(r\s, , text).strip() return text # 假设 dataset 目录下有一个 CSV列名为 text 和 label df pd.read_csv(dataset/news.csv) df[clean] df[text].apply(clean_text) # TF-IDF 向量化 vectorizer TfidfVectorizer(max_features5000, stop_wordsenglish) X vectorizer.fit_transform(df[clean]) y df[label].values逻辑说明clean_text函数按顺序去 HTML、去 URL、去非字母字符、转小写、压缩空白。顺序不能乱先去标签再去 URL否则 URL 里的斜杠和点会被后面的正则误伤。TfidfVectorizer的max_features5000是经验起点stop_wordsenglish去掉英文停用词。如果你的数据集是中文新闻需要换成 jieba 分词加中文停用词表TfidfVectorizer的tokenizer参数要指定 jieba 的cut函数。参数怎么改max_features从 3000 到 10000 之间调看验证集表现ngram_range可以设成(1,2)捕捉二元词组但维度会翻倍慎用。3. MLP 模型构建与训练层数、激活函数、优化器怎么定3.1 网络结构设计的取舍这个项目的 MLP 结构不复杂输入层维度等于 TF-IDF 特征数比如 5000然后接一到两个隐藏层最后输出层用 sigmoid 做二分类。隐藏层激活函数用 ReLU因为它在深层网络中梯度消失问题比 sigmoid 小计算也快。隐藏层节点数怎么定常见做法是第一层设 256 或 512第二层减半。比如 5000 → 256 → 64 → 1。层数不是越多越好两层隐藏层对文本分类已经够用再加层参数量上去但收益递减还容易过拟合。3.2 训练脚本与关键参数下面是一个基于 Keras 的 MLP 训练脚本对应项目里的ML fit.py思路import numpy as np from sklearn.model_selection import train_test_split from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, Dropout from tensorflow.keras.optimizers import Adam # 划分训练集和测试集70/15/15 的思路这里简化为 85/15 X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.15, random_state42 ) # 构建 MLP model Sequential([ Dense(256, activationrelu, input_shape(X_train.shape[1],)), Dropout(0.3), Dense(64, activationrelu), Dropout(0.2), Dense(1, activationsigmoid) ]) model.compile( optimizerAdam(learning_rate0.001), lossbinary_crossentropy, metrics[accuracy] ) history model.fit( X_train.toarray(), y_train, epochs20, batch_size32, validation_split0.15, verbose1 ) # 保存模型 model.save(model/mlp_model.h5)逻辑说明Dropout层放在隐藏层后面训练时随机丢弃一部分神经元防止过拟合。Adam优化器学习率设 0.001 是默认值如果 loss 震荡大就降到 0.0005。batch_size32是常见起点数据量小可以降到 16数据量大可以升到 64。epochs20配合validation_split看验证 loss 什么时候不再下降早停可以加EarlyStopping回调。注意X_train.toarray()是因为 TF-IDF 输出的是稀疏矩阵Keras 的fit不直接吃稀疏矩阵要先转稠密。如果特征维度 5000 以上转稠密后内存占用会很大这时候要么减小max_features要么改用SparseTensor输入。参数怎么改隐藏层节点数从 256 开始加到 512 看验证准确率有没有提升Dropout率从 0.3 开始过拟合严重就加到 0.5欠拟合就降到 0.2。4. 模型评估与预测输出准确率之外还要看什么4.1 评估指标的选择训练完模型model.evaluate给出的是准确率。但虚假新闻检测是个二分类问题准确率在类别不平衡时会骗人。比如 90% 是真实新闻模型全猜真实也有 90% 准确率但虚假新闻一条都抓不到。所以要看 precision、recall 和 F1。from sklearn.metrics import classification_report, confusion_matrix y_pred (model.predict(X_test.toarray()) 0.5).astype(int) print(confusion_matrix(y_test, y_pred)) print(classification_report(y_test, y_pred))confusion_matrix看假阳性和假阴性各多少classification_report看每类的 precision 和 recall。如果虚假新闻的 recall 低说明模型漏检多需要调整分类阈值或者对少数类过采样。4.2 预测输出文件 mlp_pred.txt 的生成项目里有个mlp_pred.txt应该是模型对测试集的预测结果。生成方式predictions model.predict(X_test.toarray()) with open(mlp_pred.txt, w) as f: for pred, true in zip(predictions, y_test): label fake if pred 0.5 else real f.write(f{label}\n)这个文件可以用来做后续分析比如找出模型预测置信度低的样本人工检查是不是标注错了。5. 避坑与常见问题跑不通的时候先查这几条5.1 依赖版本不匹配导致 import 报错现象import tensorflow报ModuleNotFoundError或者版本冲突。原因项目没有requirements.txt不同版本的 TensorFlow API 有差异比如tf.keras和独立keras的导入路径不同。解决装 TensorFlow 2.x 的稳定版pip install tensorflow2.13.0然后确认from tensorflow.keras.models import Sequential能正常导入。如果用的是 PyTorch 版本检查torch和torchvision版本对应关系。5.2 TF-IDF 矩阵转稠密时内存溢出现象X_train.toarray()执行时进程被 kill 或者报MemoryError。原因max_features设太大比如 50000训练集几万条转稠密后矩阵占几个 G。解决把max_features降到 5000 以内或者用SparseTensor输入。Keras 可以用tf.sparse.SparseTensor包装稀疏矩阵但需要自定义输入层。5.3 验证集准确率不动或者震荡现象训练几个 epoch 后验证准确率卡在 50% 左右或者上下大幅跳动。原因学习率太大导致梯度爆炸或者数据没有打乱或者标签编码有问题。解决先把学习率降到 0.0001 试检查train_test_split有没有设random_state保证可复现确认标签是 0 和 1 而不是字符串如果是字符串要用LabelEncoder转。5.4 中文新闻数据集分词缺失现象如果数据集是中文直接用TfidfVectorizer默认分词会把整句话当一个 token特征毫无意义。原因TfidfVectorizer默认按空格分词中文没有空格。解决用 jieba 分词TfidfVectorizer(tokenizerjieba.cut)同时把stop_words换成中文停用词表。注意 jieba 分词后要去掉单字和标点。5.5 模型保存后加载预测结果不一致现象训练时准确率 90%保存模型再加载预测准确率掉到 70%。原因保存模型时没有保存 TF-IDF 的vectorizer加载后用了新的vectorizer导致特征空间不一致。解决用joblib把vectorizer一起保存预测时先加载vectorizer再transform新文本。import joblib joblib.dump(vectorizer, model/tfidf_vectorizer.pkl) # 加载时 vectorizer joblib.load(model/tfidf_vectorizer.pkl) X_new vectorizer.transform(new_texts)6. 进阶技巧把 MLP 检测器接成可调用的预测函数课程设计交完不是终点把这个模型封装成一个能接收任意新闻文本、返回真假判断的函数才算真正跑通。下面是我常用的封装方式顺便把置信度也带出来import joblib import re import numpy as np from tensorflow.keras.models import load_model class FakeNewsDetector: def __init__(self, model_path, vectorizer_path): self.model load_model(model_path) self.vectorizer joblib.load(vectorizer_path) def _clean(self, text): text re.sub(r.*?, , text) text re.sub(rhttp\S|www\S, , text) text re.sub(r[^a-zA-Z\s], , text) return re.sub(r\s, , text).lower().strip() def predict(self, text): cleaned self._clean(text) vec self.vectorizer.transform([cleaned]).toarray() prob self.model.predict(vec, verbose0)[0][0] label fake if prob 0.5 else real confidence prob if prob 0.5 else 1 - prob return {label: label, confidence: round(float(confidence), 4)} # 使用 detector FakeNewsDetector(model/mlp_model.h5, model/tfidf_vectorizer.pkl) result detector.predict(Breaking: scientists discover new planet) print(result)这个封装做了三件事把清洗逻辑内聚到类里避免每次调用都手动预处理把vectorizer和模型绑定保证特征空间一致输出置信度方便设置阈值过滤低置信样本。置信度低于 0.6 的样本我一般会标记出来人工复核因为 MLP 在边界样本上容易摇摆。阈值怎么调默认 0.5如果虚假新闻漏检多就降到 0.4如果误报多就升到 0.6。调阈值比重新训练模型快得多先用验证集画一条 precision-recall 曲线找到 F1 最大的那个点。还有一个实用技巧把mlp_pred.txt里的预测结果和原始文本对照找出模型预测错但置信度很高的样本这些往往是标注噪声。我上次跑一个类似项目发现十几条标为 fake 的新闻其实是 real清理后验证准确率涨了 3 个点。从那以后我每次训练完都强制走一遍「高置信错误样本检查」比调参管用。希望帮到你。本文还有配套的精品资源点击获取
上一篇/下一篇内容由系统自动关联
返回资讯列表 →