自然语言处理的数据预处理过程主要包括如下步骤:
(1)文本数据集的划分(训练集、验证集和测试集);
(2)文本数据的导入;
(3)分词;
(4)词汇表的构建;
(5)文本数据对于词汇表的编码和映射;
(6)词向量的生成;
(7)批文本数据的生成。
torchtext是一个高效、有力的文本预处理库(其对NLP的作用类似于torchvision之于CV),提供了涵盖上述诸步骤的一站式文本预处理功能。其预处理结果不仅可用于pytorch,也可用于其他框架的使用。
torchtext的整体处理流程如上图所示,其主要的类对象包括:
(1)DataSet, 作用类似于torch.utils.data.DataSet
,提供了完整的数据载入和切片功能;
(2)Example,为DataSet的一个文本数据,其可有text和对应的label构成;
(3)Field,定义了文本处理的配置信息;
(4)Vocab,记录了文本中涉及的词汇表单
(5)Vector,词向量
(6)Iterator,作用类似于torch.unitls.data.DataLoader
,为一个迭代器,每次迭代记录了一个batch的文本数据
(7)Pipeline,将各子功能模块进行连接的管道工具。
用torchtext来处理文本的的一般流程归纳如下:
(1)定义Field
对象,配置文本处理(包括text和label)的分词、停用词、文本长度、填充词、未知词等一系列工具;
(2)定义DataSets
对象,加载原始语料(字符串数据),利用参数fields
设置相关预处理工具,并利用splits
实现各数据集的划分,划分结果中为一个个的Example
对象;
(3)利用Field.build_vocab
创建词汇表对象Vocab
;
(4)定义Iteator
对象,实现对DataSets
对象的封装,返回可迭代的批量化文本向量数据,供下游NLP任务使用。
下面通过一个例子,来简单实践下上述的基本流程:
步骤一:准备好合适的原始语料
这里通过将文本存为csv格式,方便后续的处理。csv主要包括两个字段,texts为文本,label为文本分类。对于不同的NLP任务,需要定义不同的字段和原始语料格式。
import pandas as pd
def raw_corpus():
# 进行一些语料的清洗和预处理工作
corpus = pd.DataFrame({'text':texts, 'label':label})
corpus.to_csv('corpus.csv', index=False, sep='\t') # 注意这里的sep符号,后面要用到
步骤二:定义分词工具、停用词等,然后配置Field对象,进行数据集的划分和词汇表生成
from torch.text import data
import jieba
# 定义分词工具
def tokenizer(text):
return [wd for wd in jieba.cut(text, cut_all=False)]
# 定义停用词表
stopwords = open('stopwords', encoding='utf-8').read().strip().split('\n')
# 定义text和label的Field对象,相关参数说明见下
TEXT = data.Field(sequential=True, use_vocab=True, fix_length=20, tokenize=tokenizer, stop_words=stopwords, batch_first=True)
LABEL = data.Field(sequential=False, use_vocab=False)
# 划分数据集,相关参数说明见下
train, val = data.TabularDataset.splits(
path='./data', train='train_corpus.csv',validation='valid_corpus.csv',format='csv',
skip_header=True, csv_reader_params={'delimiter': '\t'},fields =[('text',TEXT),('label',LABEL)] )
# 根据训练数据,生成词汇表
TEXT.build_vocab(train)
上面用到了两个重要对象Field
和TabularDataset
,Field
对象前文已提及用于定义文本预处理的配置,可将语料一站式生成张量;而TabularDataset
是前文DataSet
对象的子类,专门用于处理表格类型原始语料(如json、csv和tsv)的加载。下面分别进行介绍:
1) Field
对象,其主要参数配置包括:
Field对象可实现如下重要方法:
2) TabularDataset
对象,其利用splits
函数进行语料的划分和Field
处理,主要参数配置包括:
步骤三:创建数据迭代器Iterator,并通过splits函数进行划分
train_iter, val_iter = data.Iterator.splits((train, val), batch_sizes=(10, 5), device="cuda",
sort_key=lambda x:len(x.text),sort_within_batch=False, repeat=False)
其中的重要参数设置包括:
步骤四:将各batch数据导入下游任务中
for epoch in range(3):
for batch in train_iter:
feature, target = batch.text, batch.label # 这里的text和label即为TabularDataset.splits中feild参数里的别名
# 后续任务
由上可见,torchtext可以提高文本数据预处理的效率和封装性,值得一试。
【Reference】