简介:在中文自然语言处理(NLP)任务中,文本分类是最经典的基础应用,无论是新闻资讯内容打标、舆情系统领域识别,还是推荐系统冷启动,都依赖可靠的分类模型。THUCNews作为清华大学发布的中文新闻分类基准数据集,以84万篇真实新浪新闻、14个类别成为入门与对比实验的标配。其数据源自2005至2011年历史存档,经清洗整理后类别覆盖体育、娱乐、科技等常见频道,样本分布贴近真实业务场景。使用该数据集时,需掌握从文件读取、标签映射、分词、词表构建到词向量训练的全流程。以TextCNN为基线模型,配合word2vec预训练向量,可在几十万样本上快速验证分类效果。该数据集兼具学术规范性与工业实用性,适合作为中文文本分类技术原理学习与工程落地的桥梁。 做中文NLP这几年,但凡要跑文本分类的基线实验,THUCNews几乎是我默认的第一个数据集。84万篇新闻、14个分类,由清华大学自然语言处理实验室整理发布,这几个数字对中文自然语言处理入门的开发者来说应该非常熟悉。它最大的特点是真实:数据全部来自新浪新闻的历史存档,不是人工合成的样本,每一行都是一条完整的新闻标题加正文,拿来练手、跑基线、对比模型,都相当顺手。
这个数据集到底能做什么?文本分类是NLP里最经典的任务,无论是做新闻资讯App的内容打标,还是做舆情系统的领域识别,本质上都需要一套分类模型来兜底。THUCNews正是为这个任务量身定制的中文基准数据集,适合做算法研究的初学者上手跑通全流程,也适合需要快速验证模型效果的老手做对比实验。我会从数据下载、预处理到TextCNN基线训练,再到调试优化踩过的坑,把整个流程完整梳理一遍。
1. 数据集整体设计与价值拆解
1.1 数据集是怎么来的,为什么要14类
THUCNews由清华大学自然语言处理与社会人文计算实验室发布,数据从新浪新闻2005年至2011年的历史数据中筛选而来。原始语料规模比现在公布的版本大得多,团队经过去除低质量新闻、过滤重复内容、按新闻频道归类等一系列清洗工作,最后整理出84万篇文档的版本。官方标注为14个类别,但实验室内部还维护过更细粒度的版本,比如把体育再拆成足球、篮球、综合等子类,用于不同的评测任务。我们平时下载使用的大多是14个大类的版本,官方也提供过一份74万篇的常用教学版本,两者在样本分布上略有差异,但任务定义完全一致。
为什么是14类而不是10类或者20类?我个人理解是它直接对应新浪新闻当时的频道体系,涵盖体育、娱乐、家居、房产、教育、时尚、时政、游戏、科技、社会、财经、星座、彩票、健康这14个常见板块。类别之间边界相对清晰,不会出现“一篇新闻既算科技又算教育”这种大面积重叠,作为分类任务的标准答案非常合适。如果类别太粗,比如只有二分类,区分难度不够,模型效果的差异体现不出来;如果类别太细,又容易引入标注噪声,增加评估成本。14类的粒度在综合内容平台上刚好能对应到真实的频道运营场景,这也是它后来成为中文文本分类默认基准的重要原因。
1.2 它在中文NLP数据集里处在什么位置
做文本分类,英文圈子里最常用的数据集是AG News(4类新闻分类)和IMDb(情感二分类),规模都在几万到几十万。中文这边,情感分类有ChnSentiCorp,短文本匹配有LCQMC,但要找一个覆盖面广、条目多、多类别均衡度还可以的新闻分类数据集,THUCNews几乎是绕不开的选择。84万篇的体量比AG News大不少,14个分类也更有挑战性,同时因为是中文真实新闻,还需要解决分词、中文标点、编码等特有的问题。换句话说,训练一个THUCNews分类模型的过程,基本等同于实战演练一遍中文文本分类的完整链路。
和现在很多动辄上亿参数的预训练模型评测基准相比,THUCNews可能显得“老派”,但它始终是中文NLP文本分类的入门标配。我见过不少刚入门的同学先拿它跑通TextCNN,再替换成BERT,逐步理解从词向量、卷积到注意力机制、预训练模型的演进过程。它不追求极限难度,胜在稳定、规范、容易复现,这在学术场景里是判断一个数据集是否合格的重要标准。对工业场景来说,THUCNews也不只是拿来练手的玩具,很多新闻推荐、内容理解系统的早期原型,都是用它的分类模型做冷启动验证的。
1.3 影响范围:从论文到工业界都在用
从学术角度看,THUCNews被广泛用作中文文本分类论文的基准数据集。一些做短文本分类、不均衡分类、小样本增强、数据增强的工作,都会在THUCNews上报告结果,用来证明提出的方法在通用新闻语料上的有效性。从开源项目角度看,很多中文NLP教程和框架都内置了THUCNews的示例,比如fastnlp、pytorch-nlp-tutorial、一些BERT实战项目,入门同学几乎都能在某个仓库里见到它的身影。从教学角度看,它和IMDb、MNIST在各自领域的地位类似,是文本分类教学里最经典的案例之一。
需要说明的是,目前网络上下载THUCNews,通常来自GitHub上各大开源项目整理好的副本,常见的是cnews.14等命名方式。不同渠道拿到的文件在细微样本上可能有差异,但整体不影响使用。我自己的习惯是固定从同一个来源下载,把训练集、测试集划分固定下来,这样论文对比和后续复现都更可靠。如果团队内部多人合作,最好在项目文档里写清楚数据的来源链接和文件校验信息,避免不同成员用的副本不一致导致实验结果对不上。
2. 数据结构、格式与使用前准备
2.1 拿到手先看清文件结构
下载并解压后,目录下一般会有train.txt、test.txt、dev.txt三个文件,有的版本会多一个class.txt用来记录类别名单。常见划分是训练集约49万条,验证集约0.7万条,测试集约0.7万条,不同整理版本会有些差异,但都能满足日常实验需求。文件本身没有表头,每一行是一条样本,字段之间用Tab制表符分隔:第一列是类别标签,第二列是新闻内容。新闻内容通常由标题和正文直接拼接而成,原始新闻里的换行、空行在清洗时已经处理掉,读进来是干净的一行文本。
这里有个容易忽略的点:Windows环境下用Excel直接打开这种txt文件,容易把UTF-8编码识别成ANSI,看到一堆乱码就以为数据坏了。实际上用代码读取完全没问题,关键是指定正确的编码参数。新闻文本里偶尔会出现特别长的段落、全角半角混合标点、英文逗号、数字百分比等,这些在后续预处理环节都需要统一处理,否则分词和词表构建会受到影响。
2.2 标签体系与样本分布速览
14个类别分别是:体育、娱乐、家居、房产、教育、时尚、时政、游戏、科技、社会、财经、星座、彩票、健康。从样本数量看,体育、娱乐、科技这类大频道因为新闻生产量大,训练集中各约有6万余条;星座、彩票属于垂直内容,样本相对少一些,约4万到5万条。总体不算完全均衡,但也没有特别离谱的偏斜,这种分布反而很接近真实业务场景——热门领域天然内容更多,垂直领域内容天然更少。
类别标签在原始文件里直接用中文存储,模型训练前需要映射成整数ID。这里建议写一个固定顺序的类别映射字典,保存成json文件,训练和预测阶段都从同一个文件读入。我见过有人图省事在代码里用set去重生成映射,结果每次运行顺序不同,训练和推理阶段标签错位,最后整个模型形同虚设。这种低级错误一旦发生,排查起来反而最浪费时间,所以数据准备阶段多花两分钟,后面能省两小时。
2.3 用pandas快速读取并检查数据
读取THUCNews最直接的方式是用pandas:
import pandas as pd train_df = pd.read_csv('train.txt', sep='\t', header=None, names=['label', 'text']) dev_df = pd.read_csv('dev.txt', sep='\t', header=None, names=['label', 'text']) test_df = pd.read_csv('test.txt', sep='\t', header=None, names=['label', 'text']) print(train_df.shape, dev_df.shape, test_df.shape) print(train_df['label'].value_counts()) print(train_df['text'].str.len().describe())跑完之后检查两个维度:一是是否有缺失值、是否有空行;二是每个类别的样本量是否符合预期。我遇到过的几个版本数据质量都不错,基本没有缺失。如果发现某一行只有一个字段,多半是文本内部残留了Tab符号,可以用split('\t', 1)的方式只拆第一个分隔符,保留后续内容作为文本,这样更稳妥。另外建议顺手看一下text的长度分布,这对后面设定文本截断长度很有参考价值。
3. 从数据到模型:构建一个文本分类基线
3.1 分词与序列化:中文NLP的必经之路
中文不像英文有天然的空格分词,所以构建模型前的第一步通常是分词。我最早用的是jieba,后来也试过pkuseg和清华的thulac,综合来看jieba速度快、稳定、社区资料多,非常适合用来搭建基线。分词之后一般会去除停用词,这里推荐用一份通用中文停用词表,把“的”“了”“和”“是”这类高频虚词过滤掉。但注意不要过度去停用词,新闻分类里某些看似虚词的字眼可能承载着语气和程度信息,去掉太多反而会掉分,具体阈值需要拿验证集测一轮。
分词完成后要构建词表,按词频统计排序后截断到指定大小。常见做法是保留词频前20000到50000个词,未登录词统一映射到UNK,同时加入PAD填充符号。THUCNews的正文往往很长,全量塞进模型既不划算也没必要,我习惯把输入长度限制在300个token左右。处理时还要统一做小写转换、数字归一化等操作,虽然这些操作听起来简单,但在新闻文本里各种英文缩写、百分比、日期格式非常常见,提前处理好可以避免词表膨胀。
3.2 词嵌入:用word2vec还是随机初始化
词嵌入是TextCNN这类模型的关键输入。一种做法是直接用随机初始化的Embedding层让模型在训练中自己学习,简单省事;另一种是先用训练数据训练一个word2vec模型,把词向量作为Embedding初始值,训练过程中选择微调或冻结。我的经验是,在THUCNews这种几十万条规模的数据集上,用数据自带语料训练一个128维的word2vec当作初始化,比随机初始化稳定提升1到2个百分点,而且训练word2vec本身只需要几分钟。
这里有一个很容易踩的坑:word2vec训练时的分词逻辑必须和后续预处理保持一致,否则词表对不上,Embedding矩阵里会出现大量未登录词。我曾经先用jieba分词训练word2vec,后来在预处理时又决定去除停用词,
本文还有配套的精品资源,点击获取