数据预处理

torchtext

Posted by abhhay on July 13, 2022

1.torchtext介绍

​ torchtext常用于文本处理,其结构主要是3大部分,分别是FieldDatasetIteration三大部分。其中Field主要是对数据字段进行预处理 ,Dataset是定义数据源信息,至于Iteration,和DataLoader很类似。

Field.sequential  输入的数据是否是序列型的如果不是将不使用tokenzie对数据进行处理

~Field.use_vocab  是否使用Vocab对象也就是使用输入的词向量这里以后会讲到如果不使用那么输入Field的对象一定是数字类型的 

~Field.init_token  给example数据的开头加一个token感觉类似<CLS>标签example之后会将

~Field.eos_token  给example数据加一个结束token

~Field.fix_length  设定序列的长度不够的进行填充

~Field.dtype  表示输入的example数据的类型

~Field.lower  是否将输入的文本变成小写

~Field.tokenize  设置一个tokenize分词器给Field用这里也有内置的一些分词器可以用

~Field.tokenizer_language  分词器tokenize的语言这里是针对SpaCy的

~Field.include_lengths  是否在返回文本序列的时候返回文本的长度这里是对LSTM的变长输入设置非常好用

~Field.batch_first  输出的数据的维度中batch的大小放到前面

~Field.pad_token  用于填充文本的关键字默认是<pad>

~Field.unk_token  用于填充不在词汇表中的关键字默认是<unk>

~Field.pad_first  是否将填充放到文本最前面

~Field.truncate_first  是否从文本开始的地方将文本截断

~Field.stop_words  停止词的设置

2.Dataset

  1. 以TabularDataset为例:
from torchtext.data import Field
from torchtext.data import TabularDataset
# 定义Field
tokenize = lambda x: x.split()
# tokenize = lambda x: jieba.lcut(x)
# def tokenizer(text): # create a tokenizer function
#    return [tok for tok in text]

TEXT = Field(sequential=True, tokenize=tokenize, lower=True, fix_length=200)
LABEL = Field(sequential=False, use_vocab=False)

# 构建Dataset
fields = [("id", None),("comment_text",TEXT),("toxic",LABEL)]
# 使用splits方法可以为多个数据集直接创建Dataset
train, valid = TabularDataset.splits(
    path='data',##路径
    train='xxx',
    validation='xxx',
    format='csv',
    skip_header=True,
    fields=fields)

test_datafields = [('text', None),('label', TEXT)]

# 直接创建Dataset(不使用splits)
test = TabularDataset(
    path=r'xxx.csv',
    format='csv',
    skip_header=True,
    fields=test_datafields
)

2.查看dataset实例

print(train[5])
print(train[5].__dict__.keys())
print(train[5].text,train[0].label)

image-20220712213307042

3.Iteration

这里使用了BucketIteratorIterator,因为BucketIterator可以自动的选择长度类似的文本组成一个batch,所以用于训练数据,而测试数据一般而言不想进行排序或者其他的操作,就使用了Iterator。BucketIerator:相比于标准迭代器,会将类似长度的样本当做一批来处理,因为在文本处理中经常会需要将每一批样本长度补齐为当前批中最长序列的长度,因此当样本长度差别较大时,使用BucketIerator可以带来填充效率的提高。除此之外,我们还可以在Field中通过fix_length参数来对样本进行截断补齐操作。

train_iterator = BucketIterator(train_dataset, batch_size=batch_size,
                                device='cuda',
                                sort_within_batch=True, shuffle=True)
test_iterator = Iterator(test_dataset, batch_size=batch_size,
                        device='cuda', train=False,
                        shuffle=False, sort=False, sort_within_batch=True)

image-20220712214039461

4.torchtext 相关函数

构建词表

bulid_vocab()方法

TEXT.build_vocab(train)

counter  这里用来计算输入的数据的频率的其实没太看明白英文翻译不过这里对应build_vocab输入的是Dataset经过build_vocab处理之后传递给torchtext.vocab.Vocab

max_size  词向量表的最大大小

min_freq  参与转换成词向量的最小词频率不满足这个词频率的直接就是<unk>

specials  需要添加到词向量表中的一些特殊字符默认的包含['<unk'>'<pad>']两种也是因为这个参数所以我们的txt文件中的词向量不需要包含这两个特殊字符

vectors  用于加载的预训练好的词向量

unk_init (callback)  用于初始化未知词汇的词向量默认是0

vectors_cache  存放缓存的目录这个不一定在这里设定在Vectors类中设置也行

specials_first  改变特征字符在词汇表中的位置是放在最前面还是放在最后面

使用预训练的词向量 在使用pytorch或tensorflow等神经网络框架进行nlp任务的处理时,可以通过对应的Embedding层做词向量的处理,更多的时候,使用预训练好的词向量会带来更优的性能,下面介绍如何在torchtext中使用预训练的词向量,进而传送给神经网络模型进行训练。

不使用的话 直接就冲了。

1.#torchtext 默认的词向量
TEXT.build_vocab(train, vectors="glove.6B.200d")
"""
支持以下的词向量(直接导入)
charngram.100d
fasttext.en.300d
fasttext.simple.300d
glove.42B.300d
glove.840B.300d
glove.twitter.27B.25d
glove.twitter.27B.50d
glove.twitter.27B.100d
glove.twitter.27B.200d
glove.6B.50d
glove.6B.100d
glove.6B.200d
glove.6B.300d
"""
2.torchtext外部预训练的向量
 默认情况下预训练词向量文件和缓存文件的目录位置都为当前目录下的 .vector_cache目录虽然通过name参数指定了预训练词向量文件存在的目录但是因为缓存文件的目录没有特殊指定此时在当前目录下仍然需要存在 .vector_cache 目录
if not os.path.exists(.vector_cache):
    os.mkdir(.vector_cache)
vectors = Vectors(name='myvector/glove/glove.6B.200d.txt')
TEXT.build_vocab(train, vectors=vectors)

  在使用预训练好的词向量时我们需要在神经网络模型的Embedding层中明确地传递嵌入矩阵的初始权重权重包含在词汇表的vectors属性中以Pytorch搭建的Embedding层为例
    # 通过pytorch创建的Embedding层
embedding = nn.Embedding(2000, 256)
# 指定嵌入矩阵的初始权重
weight_matrix = TEXT.vocab.vectors
embedding.weight.data.copy_(weight_matrix )
# 指定预训练权重的同时设定requires_grad=True
# embeddings.weight = nn.Parameter(embeddings, requires_grad=True)

参考来源: 知乎大v

CSDN

结语

励志做一个有梦想的NLPer

                                                                          坑坑 加油