简介:面向虚假新闻检测的社交媒体多模态数据集,专为自然语言处理、多媒体分析与虚假信息识别方向的学生和研究者设计,可用于训练二分类模型、验证文本图像多模态特征融合方法,以及开展不同算法间的基准对照实验。压缩包共含5个文件,包括2个CSV数据文件,用于存放社交媒体文本内容、关联图像路径及真伪标注等结构化信息,可直接加载为训练集;1个Markdown说明文档,介绍字段含义与数据采集流程;1张示例图片,展示图像模态样本样式;1个Python爬虫脚本,可自动采集新闻文本与图片,便于读者扩展数据规模。整套资源仅654KB,轻量易用,下载后就能快速开展本地实验。目前已有75人学习下载,适合作为虚假新闻识别课程设计、毕业设计或科研课题的起步资料。借助该资源,读者既能获得带标注的多模态训练数据,也能通过爬虫脚本和数据说明理解信息采集与整理流程,便于扩充语料,迁移到谣言检测、舆情监控等相近任务。
1. 面向虚假新闻检测的社交媒体多模态数据集:一张配图背后的三重信息
想象你刷到一条带图的新闻:画面里浓烟滚滚,配文写着“某地发生爆炸”,转发量过了万。文本模型看配文,觉得像突发事件;图像模型看画面,判断是合成图还是老图重发;但真正让它变成“谣言”的证据,往往埋在传播路径里——谁先转的、转发的节奏像不像机器人、评论区的情绪是不是一边倒。单靠文本或单靠图像,你都只能看到冰山一角。
面向虚假新闻检测的社交媒体多模态数据集,就是把这条链路里的文本、图像、传播结构打包成一份可以复现实验的家底。价值不在于“数据多”,而在于“模态齐”:新闻内容、配图、用户信息、转发关系在同一条时间线上对齐,模型才有机会学到事实核验之外的判断依据。
这篇文章沿着“为什么需要多模态 → 怎么解开 zip 跑通预处理 → 哪些坑让指标虚高 → 怎么验证数据质量”这条线,给正在做新闻真实性检测、舆情分析和多模态学习的研究者一份可直接上手的落地笔记。
2. 解构多模态数据集的三种模态:文本、图像与传播关系里分别藏着什么
做虚假新闻检测实验,第一件事不是选模型,而是先看数据里到底有哪些信号可以学。一个合格的社交媒体多模态数据集,通常不是简单地把文本和图片堆在一个文件夹里,而是围绕“一条新闻”组织起三个层次的证据:文本内容、视觉内容、社交传播内容。三者各有各的判别力,也各有各的坑。
常见的数据集目录会按模态分文件夹,用统一的 news_id 把不同文件串起来。拿到手先别急着训练,花半天把字段结构看清,比之后调一个月模型更值。
2.1 文本模态:标题党、情绪词和正文偏离度,三个最容易被忽略的信号
文本是虚假新闻检测里最基础也最成熟的模态。但很多人在处理时只做了“分词 + 词向量”,把文本当成普通的分类任务,丢掉了一些在假新闻场景里特别有判别力的信号。
第一个信号是标题与正文的偏离度。虚假新闻的标题往往追求点击率,会刻意夸大、制造悬念,和正文内容产生一种“语义落差”。你可以用标题的向量表示和正文的向量表示算一个余弦相似度,这个相似度本身就可以作为一维特征输入模型。计算方式很简单:把标题和正文分别编码成句向量,然后求夹角余弦,阈值可以设在 0.5 到 0.7 之间,偏离越大,虚假概率越高。
第二个信号是情绪词的密度和分布。真实新闻的正文通常保持相对中性的语气,而虚假新闻更倾向使用“震惊”“速看”“删前速转”这类高唤醒度词汇,并且在开头和结尾反复出现。统计情绪词在全文的位置分布,比单纯统计词频更有说服力。你会发现,假新闻文本的情绪词往往集中在标题和前两段,而真实新闻的情绪词分布更均匀。
第三个信号是标点和符号的异常使用。连续三个以上的感叹号、问号和省略号组合,在真实新闻里几乎不会出现,但在社交媒体传播的假新闻里却很常见。这个特征不需要任何模型,一个正则表达式就能统计出来,作为规则特征叠加到模型里,往往能稳当地提升几个点的准确率。
2.2 图像模态:EXIF 时间戳、复制粘贴痕迹和图文相关性,三个维度交叉验证
图像模态是社交媒体新闻里最“重”的一路证据,也是很多团队在数据处理阶段就放弃掉的部分。常见理由是“图像太多、GPU 不够”,但做了多模态实验你会发现,图像模态对虚假新闻检测的提升,往往就藏在对齐和相关性里,而不是硬塞一个预训练模型去抽特征。
图像侧可以提取三类信号。
第一类是 EXIF 元数据。每张从相机或手机直接产出的图片都带着拍摄时间、设备型号、GPS 信息。如果一张新闻配图的 EXIF 拍摄时间早于新闻事件发生时间好几年,那基本可以判定是旧图重发。当然,社交媒体平台会压缩图片并抹掉大部分 EXIF,但部分数据集在采集时会保留原始文件,值得检查一下。
第二类是图像本身的篡改痕迹。复制-粘贴伪造、拼接、重压缩,都会在图片的噪声模式、边缘过渡带上留下痕迹。你可以用 ELA(Error Level Analysis)做快速筛查,或者直接用预训练模型抽取深层特征,让模型自己去发现这些伪影。这类特征不需要你标注篡改区域,是弱监督的信号。
第三类是图像与文本的相关性。这个维度最容易被忽略:一张街景图配一个“某地发生地震”的文案,文本单独看没有问题,图像单独看也没有问题,但放在一起就能发现语义断裂。实现上可以把图像过一遍 OCR,把识别出来的文字和新闻文本里的地点、时间、人物实体做匹配。匹配率低的样本,大概率是图文不符。
| 模态 | 典型字段 | 对虚假新闻检测的作用 |
|---|---|---|
| 文本 | 标题、正文、评论、发布时间 | 标题党识别、情绪异常、事实偏离 |
| 图像 | 配图文件、EXIF、OCR文本 | 旧图复用、拼接篡改、图文不符 |
| 社交 | 用户ID、粉丝数、转发链、时间戳 | 机器扩散、传播速度异常、社群聚类 |
2.3 社交上下文:转发路径、用户画像和时间序列,构成第三重证据
文本和图像解决的是“这条新闻内容可不可信”,社交上下文解决的是“这条新闻是怎么扩散的”。假新闻的传播模式和真新闻有明显差异,这一点在社交媒体场景里尤其突出:机器人账号会在极短时间内制造大量转发,传播路径像一团炸开的毛线球;而真实新闻的传播往往先由核心媒体或大 V 发出,再逐级扩散,路径结构更接近树状。
社交上下文的第一个可计算特征是转发图的拓扑结构。把每个用户当作节点,转发关系当作有向边,可以统计这个图的深度、宽度、环数、平均聚类系数。虚假新闻的传播图往往深度浅、宽度大、环数少,因为大量机器账号在同一层级上互相转发。
第二个特征是用户画像的统计量。数据集中通常会有发布者和转发者的粉丝数、关注数、注册时长、历史发帖数。机器人账号的粉丝数往往虚高但互动率极低,注册时间长但历史发帖频率忽高忽低。把这些统计量拼成用户特征向量,再做传播路径上的聚合,能明显提升对“水军扩散”的识别能力。
第三个特征是时间序列的传播节奏。真实新闻的转发量在发布后会出现一个自然的衰减曲线,而假新闻配合水军投放,会在某个时间点出现突然的脉冲式转发。用一条新闻的所有转发时间戳画一个直方图,峰值个数和峰值的宽度,都是很强的判别特征。处理时建议按小时为粒度做聚合,保留 72 小时内的转发序列,太细会稀疏,太粗会丢失脉冲形态。
这三重证据加在一起,才是“多模态”这三个字的意义。接下来要做的,就是把这个 zip 包解开、把三套数据对齐成模型能吃的样子。
3. 把 zip 解压成可训练样本:目录体检、模态清洗与对齐
拿到.zip后缀的数据集,很多人第一反应是双击解压,然后直接开始敲模型代码。这个习惯在单模态数据集上或许还能容忍,但在多模态数据集上几乎一定会让你返工。多模态数据的价值需要每一步预处理都足够干净,才可能在训练阶段显现出来。先把压缩包当成一份需要清点的资产,而不是一个待解开的箱子。
3.1 解压前的目录体检:先用 unzip 看清结构,再决定怎么处理
我拿到任何数据集压缩包,第一件事不是解压,而是先看压缩包里有什么。这一步能帮你判断数据组织的成熟度,也能提前发现缺文件、路径异常、伪加密等问题。
# 查看 zip 包内文件清单,不要急着解压 unzip -l dataset.zip | head -80这条命令会列出 zip 内所有文件的路径、大小和最后修改时间。重点看三件事:文件后缀的分布、目录层级是否规整、有没有明显缺失的模态。多模态数据集一般会按text/、image/、social/分目录,文件数应该在同一量级。如果某个模态的文件数只有另外两个的十分之一,大概率是采集阶段就漏了,你需要有心理准备。
查看确认目录结构合理之后,再执行真正解压。为了保持原始时间戳并应对加密,我会优先用 7-Zip:
# 7-Zip 解压,-o 指定输出目录,-p 后面跟密码 7z x dataset.zip -o./fakenews_data -pYourPassword注意-o后面不要有空格,否则会被解析成两个参数;如果数据集没有加密,-p可以省去。解压完成后,先用du -sh看一眼总大小和磁盘余量,多模态数据集里图片占用的空间通常远超文本,别等解压到一半才发现磁盘满了。另外,官方工具和第三方解压工具对 zip 格式的兼容性不同,如果unzip报错说文件损坏,先试试 7-Zip,很多所谓“损坏”只是 zip 头信息不标准。
提示:如果解压时提示输入密码,但你确认数据集是公开的,优先尝试空密码、
123456这类常见口令。先别急着用各种“zip 密码移除”工具,多数情况下只是伪加密位被错误置位。
3.2 文本与图像清洗:两个独立但必须并行的预处理管线
解压之后,数据的原始形态往往不能直接用。社交媒体语料里充斥着 HTML 标签、URL、@提及、重复标点;图像里则混有损坏文件、重复图片和尺寸过小的占位图。这两个管线的清洗逻辑完全不同,需要并行处理,最后再对齐。
文本清洗的常见做法是先做一轮规则清理,再做归一化和去重。下面的代码以 Pandas 操作为主,适用于多数 TSV 或 CSV 格式的文本模态文件:
import pandas as pd import re df = pd.read_csv("fakenews_data/text/news_text.tsv", sep="\t") def clean_text(s): s = re.sub(r"<[^>]+>", "", s) # 去 HTML 标签 s = re.sub(r"@\w{1,30}", "[USER]", s) # 用户提及统一为占位符 s = re.sub(r"http\S+", "[URL]", s) # URL 统一替换 s = re.sub(r"[!?!?]{2,}", "[EXCL]", s) # 连续标点归一化 return s.strip() df["clean_text"] = df["text"].map(clean_text) df = df.drop_duplicates(subset=["news_id"]) print(df.shape, df["clean_text"].str.len().describe())这段代码的核心思路是“把噪声变成占位符”,而不是直接删除。把 URL 替换成[URL]而不是删掉,模型在训练时才能学到“这条新闻里有链接”这个事实,而链接本身就携带很强的风险信号。[USER]同理,既保护了用户隐私,也保留了“这条推文 @ 了很多人”的结构信息。
图像清洗的常见做法远没有文本那么成熟。先做损坏文件过滤,再做感知哈希去重。因为配图常被不同账号反复使用,完全相同的图片在数据集中出现多次,会给后续切分带来致命的数据泄漏。感知哈希可以把图片降维成一组指纹,用汉明距离判断相似度。
import imagehash from PIL import Image from pathlib import Path def validate_image(path_str): try: with Image.open(path_str) as img: img.verify() return True except Exception: return False def dedup_images(folder): seen = {} dup_pairs = [] for p in Path(folder).glob("*.jpg"): if not validate_image(p): p.unlink() # 删除损坏文件 continue with Image.open(p) as im: h = imagehash.phash(im, hash_size=16) if h in seen: dup_pairs.append((p.name, seen[h])) else: seen[h] = p.name return dup_pairs dups = dedup_images("fakenews_data/image/demo_images/") print("重复图片对数:", len(dups))phash的hash_size参数控制指纹精度:值越大对细节越敏感,值越小越宽松。处理新闻配图时,16 通常是比较稳的起点;如果发现误杀太多(视觉上不同但被判为重复),可以调整到 12,让哈希更宽松。注意删除损坏文件前先确认它的news_id是否也在文本文件里,如果该 news_id 只有这一张图,删除后这条样本就残废了,需要一并剔除。
3.3 结构对齐:用 news_id 把三套数据合并成一条训练样本
清洗完文本和图像,最后一步是把社交上下文也拉进来,用news_id作为主键做对齐。这是多模态数据集处理里最需要耐心的一步。
常见的做法是把社交上下文展平成一张宽表:一条新闻对应一个发布者,所有转发者的统计特征聚合成列表。但要注意,一条新闻往往有成千上万条转发,不能把每一条转发都展开成一行样本,否则你的数据集会膨胀到不可控,而且同一新闻的强相关样本会严重干扰验证集。正确做法是聚合到 news_id 粒度:保留转发总数、72 小时内每小时的转发数、不同用户数、平均粉丝数等聚合特征,这样每条新闻只有一行样本。
text_df = pd.read_csv("fakenews_data/text/news_text.tsv", sep="\t") img_df = pd.read_csv("fakenews_data/image/image_meta.tsv", sep="\t") social_df = pd.read_csv("fakenews_data/social/social_agg.tsv", sep="\t") # 先把 id 统一成字符串类型,避免数字和字符串混着比较 for d in (text_df, img_df, social_df): d["news_id"] = d["news_id"].astype(str).str.strip() merged = text_df.merge(img_df, on="news_id", how="inner") merged = merged.merge(social_df, on="news_id", how="inner") print("文本行数:", len(text_df)) print("合并后行数:", len(merged))合并时我默认用how="inner",只保留三个模态都齐全的样本。如果你发现合并后行数骤减到不足原来的六成,先别急着换outer,而是应该反查为什么缺。多数情况是某个模态文件里的news_id带了不可见字符,或者使用了不同的命名规则(比如文本里是id_1001,图像里是1001)。先把两边 id 的样例打出来对比,再决定是补数据还是清洗 id 格式。用outer补齐缺失模态,会让模型学到“缺失模态也能预测”,这在没有对应的部署环境时是个假能力,不建议默认采用。
4. 避坑指南:从解压到指标评估,五个常见翻车点
多模态数据集处理流程长,任何一个环节的脏数据都会在最终的指标上体现为“看起来不错、实则不可复现”。这里攒了五个高频踩坑点,每一条都是从实际操作中摔过之后总结出来的,现象、原因、解决三步到位。
4.1 解压报错或提示密码:zip 伪加密和格式兼容性问题
现象:用系统自带解压工具或unzip命令解压时,报“bad zipfile offset”或弹窗要求输入密码;有些文件解压到一半提示 CRC 校验失败。
原因:部分数据集在上传时为了让文件“防盗版”,把 zip 的加密标志位置位但并没有真正加密,这就是所谓的“伪加密”。标准解压工具检查到加密位就会要求输密码,但数据本身其实是明文的。另一种情况是文件在传输过程中头部被截断或修改,导致工具解析异常。
解决:优先换 7-Zip,它对非标准和损坏 zip 的容错能力明显更强。如果 7-Zip 也提示密码,先尝试空密码、123456、数据集发布方的域名或项目名。真正需要动用“zip 密码移除”类工具的场合很少,而且这类工具在大型压缩包上速度极慢,不如先判断是不是伪加密。
4.2 图像重复导致验证集准确率虚高
现象:训练集和验证集统计分布近似,模型在验证集上 AUC 到了 0.92,但换一批新采集的数据测试,直接掉到 0.81。
原因:同一张新闻配图被多次转载,出现在不同 news_id 的样本里。按news_id随机切分时,同一张图几乎必然同时落到训练集和验证集。模型记住了这张图的像素分布,而不是“新闻的真假模式”,一旦遇到没见过的图就原形毕露。
解决:在数据切分之前,先用 3.2 节里的感知哈希做全量去重,并按重复图片的簇重新分配集合。也就是把同一张图片的所有news_id放到同一个集合里。这一条是做多模态图像实验的底线,不做这个处理,你的指标大概率是虚的。
4.3 文本编码混乱导致模型学到乱码特征
现象:读入 CSV 后,文本列里出现大量“�”和繁体字,分词结果稀碎,模型在验证集上表现尚可,但训练日志里 loss 抖动剧烈。
原因:社交媒体采集文件混杂了 UTF-8、GBK、Big5 多种编码,而且繁简字体混用。分词器对乱码和繁体字符的处理不稳定,会在词表里引入大量无意义的“字符碎片”。
解决:读取文件时先用chardet库检测编码,统一转成 UTF-8 后再进 Pandas。分词前做一次繁简转换,可以用OpenCC,确保输入到模型的字符集是一致的。另外,把“乱码字符比例”当作一个统计特征保存下来,这个特征本身对假新闻检测也有参考价值,因为采集自可疑来源的文本通常编码更混乱。
4.4 news_id 键不一致导致样本大量丢失
现象:三个模态文件的行数都是两万左右,merge 之后只剩八千行,且没有任何报错信息。
原因:文本模态的news_id是"news_0123",图像模态是"123",社交模态是"10123",三套数据的 id 规则不一致。字符串和数字类型的隐式转换在 Pandas 中不报错,但结果就是大量匹配不上。
解决:merge 前统一astype(str)并strip(),然后分别打印三套数据news_id的前 20 个长啥样,肉眼确认格式。还有一个隐蔽问题:某些 id 开头有\ufeff之类的不可见字符,用repr()打印才能看见。这个检查做一次,能省一晚上的排查时间。
4.5 按行切分时间序列,导致训练集和验证集时间重叠
现象:训练集和验证集来自同一段时间,模型表现异常好;按发布时间的后半段作为测试集后,性能大幅衰退。
原因:一条新闻从发布到传播、辟谣,时间跨度往往超过一周。如果按单条转发记录或单条推文的时间切分,同一事件的文本和图像被切成了两半,验证集里包含了和训练集同源的内容,指标自然好看。
解决:切分必须以news_id为最小粒度,以新闻首次发布时间作为标签。如果数据集的传播记录跨时太长,训练集和测试集之间还应留出至少一周的缓冲带,防止辟谣信息或后续讨论污染测试集。时间序列上的严格隔离,是多模态虚假新闻检测里最容易暴露出模型的“真实体力”的试金石。
5. 验证这份数据是否可用:两个低成本实验
数据清洗完毕、模型还没开始调参之前,我强烈建议先做两个小实验,用来判断这份数据值不值得继续投入算力。这两个实验加起来用不了一小时,却能在很大程度上避免你把两星期时间砸在一份质量有限的数据集上。
第一个实验是“弱基线对比”。用纯文本的 TF-IDF + 逻辑回归作为基准,再训练一个最简单的多模态模型(比如把文本向量和图像向量拼接后过一层 MLP),对比两者的验证集 AUC。如果多模态模型相对文本基线的提升不足 1.5 个百分点,说明模态间的互补信息有限,你需要检查清洗过程是不是把图像信息过度压缩了。如果多模态模型反而更差,那数据对齐环节基本可以倒查重做了。
from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.linear_model import LogisticRegression from sklearn.metrics import roc_auc_score vec = TfidfVectorizer(max_features=20000) X = vec.fit_transform(merged["clean_text"]) y = merged["label"] lr = LogisticRegression(C=1.0, max_iter=1000) lr.fit(X[:8000], y[:8000]) print("文本基线 AUC:", round(roc_auc_score(y[8000:], lr.predict_proba(X[8000:])[:, 1]), 4))第二个实验是“时间分组稳定性测试”。用GroupKFold按news_id分组做 5 折交叉验证,并保证每一折内不出现相同图像。如果各折的 AUC 标准差超过 0.05,说明数据在时间分布上极不均衡,或者存在还没有被你发现的泄漏路径。相反,如果各折的标准差很小,说明这组数据对模型来说是“吃得动”的,可以放心进入正式训练。
from sklearn.model_selection import GroupKFold gfold = GroupKFold(n_splits=5) scores = [] for tr_idx, va_idx in gfold.split(X, y, groups=merged["news_id"]): lr.fit(X[tr_idx], y[tr_idx]) auc = roc_auc_score(y[va_idx], lr.predict_proba(X[va_idx])[:, 1]) scores.append(auc) print("各折 AUC:", scores)这是我做完整个流程之后养成的习惯:拿到一份新的数据集,第一件事永远是unzip -l清点目录、pHash 扫描去重,这两个动作花不了十分钟,却挡住过好几次论文返工。多模态数据集的每一条样本都是三重信号拼起来的,清洗得越细,模型才学得越稳。希望这篇笔记帮到你。
本文还有配套的精品资源,点击获取