1. 介紹
本文主要介紹如何使用TorchText處理文本數(shù)據(jù)集。
Torchtext是一種為pytorch提供文本數(shù)據(jù)處理能力的庫(kù), 類似于圖像處理庫(kù)Torchvision。
2. 安裝
pip install torchtext
3. 概覽

image.png
使用torchtext的目的是將文本轉(zhuǎn)換成Batch,方便后面訓(xùn)練模型時(shí)使用。過(guò)程如下:
- 使用
Field對(duì)象進(jìn)行文本預(yù)處理, 生成example - 使用
Dataset類生成數(shù)據(jù)集dataset - 使用
Iterator生成迭代器
4. 常用的類
import torch
from torchtext.data import Field, Example, TabularDataset, BucketIterator
-
Field:用來(lái)定義字段以及文本預(yù)處理方法 -
Example: 用來(lái)表示一個(gè)樣本,通常為“數(shù)據(jù)+標(biāo)簽” -
TabularDataset: 用來(lái)從文件中讀取數(shù)據(jù),生成Dataset,Dataset是Example實(shí)例的集合 -
BucketIterator:迭代器,用來(lái)生成batch, 類似的有Iterator,BucketIterator的功能較強(qiáng)大點(diǎn),支持排序,動(dòng)態(tài)padding等
5. 使用步驟
5.1 創(chuàng)建Field對(duì)象
# tokenize = lambda x: x.split()
def x_tokenize(x):
# 如果加載進(jìn)來(lái)的是已經(jīng)轉(zhuǎn)成id的文本
# 此處必須將字符串轉(zhuǎn)換成整型
# 否則必須將use_vocab設(shè)為True
return [w for w in x.split()]
def y_tokenize(y):
return y
TEXT = Field(sequential=True, tokenize=x_tokenize,
use_vocab=True, fix_length=None,
eos_token=None, init_token=None,
include_lengths=True)
LABEL = Field(sequential=False, tokenize=y_tokenize,
use_vocab=False)
參數(shù)說(shuō)明:
-
sequential: 是否把數(shù)據(jù)表示成序列,如果是False, 不能使用分詞 默認(rèn)值: True. -
use_vocab: 是否使用詞典對(duì)象. 如果是False 數(shù)據(jù)的類型必須已經(jīng)是數(shù)值類型. 默認(rèn)值: True. -
init_token: 每一條數(shù)據(jù)的起始字符 默認(rèn)值: None. -
eos_token: 每條數(shù)據(jù)的結(jié)尾字符 默認(rèn)值: None. -
fix_length: 修改每條數(shù)據(jù)的長(zhǎng)度為該值,不夠的用pad_token補(bǔ)全. 默認(rèn)值: None. -
tensor_type: 把數(shù)據(jù)轉(zhuǎn)換成的tensor類型 默認(rèn)值: torch.LongTensor. -
preprocessing:在分詞之后和數(shù)值化之前使用的管道 默認(rèn)值: None. -
postprocessing: 數(shù)值化之后和轉(zhuǎn)化成tensor之前使用的管道默認(rèn)值: None. -
lower: 是否把數(shù)據(jù)轉(zhuǎn)化為小寫 默認(rèn)值: False. -
tokenize: 分詞函數(shù). 默認(rèn)值: str.split. -
include_lengths: 是否返回一個(gè)已經(jīng)補(bǔ)全的最小batch的元組和和一個(gè)包含每條數(shù)據(jù)長(zhǎng)度的列表 . 默認(rèn)值: False. -
batch_first: Whether to produce tensors with the batch dimension first. 默認(rèn)值: False. -
pad_token: 用于補(bǔ)全的字符. 默認(rèn)值: “”. -
unk_token: 不存在詞典里的字符. 默認(rèn)值: “”. -
pad_first: 是否補(bǔ)全第一個(gè)字符. 默認(rèn)值: False.
重要的幾個(gè)方法:
-
pad(minibatch): 在一個(gè)batch對(duì)齊每條數(shù)據(jù) -
build_vocab(): 建立詞典 -
numericalize(): 把文本數(shù)據(jù)數(shù)值化,返回tensor
5.2 讀取文件生成數(shù)據(jù)集
torchtext的Dataset是繼承自pytorch的Dataset,提供了一個(gè)可以下載壓縮數(shù)據(jù)并解壓的方法(支持.zip, .gz, .tgz)
splits方法可以同時(shí)讀取訓(xùn)練集,驗(yàn)證集,測(cè)試集
TabularDataset可以很方便的讀取CSV, TSV, or JSON格式的文件,例子如下:
# 讀取文件生成數(shù)據(jù)集
fields = [('PhraseId', None), ('SentenceId', None), ('Phrase', TEXT), ('Sentiment', LABEL)]
train, test = TabularDataset.splits(
path='datasets/', format='tsv',
train='train.tsv', test='test.tsv',
skip_header=True, fields=fields)
# 構(gòu)建詞表
TEXT.build_vocab(train)
# print(train[0].__dict__.keys())
print(vars(train.examples[0]))
print(vars(test.examples[0]))
# 結(jié)果
{'Phrase': ['A', 'series', 'of', 'escapades', 'demonstrating', 'the', 'adage', 'that', 'what', 'is', 'good', 'for', 'the', 'goose', 'is', 'also', 'good', 'for', 'the', 'gander', ',', 'some', 'of', 'which', 'occasionally', 'amuses', 'but', 'none', 'of', 'which', 'amounts', 'to', 'much', 'of', 'a', 'story', '.'], 'Sentiment': '1'}
{'Phrase': ['An', 'intermittently', 'pleasing', 'but', 'mostly', 'routine', 'effort', '.']}
5.3 生成迭代器
Iterator是torchtext到模型的輸出,它提供了我們對(duì)數(shù)據(jù)的一般處理方式,比如打亂,排序,等等,可以動(dòng)態(tài)修改batch大小,這里也有splits方法 可以同時(shí)輸出訓(xùn)練集,驗(yàn)證集,測(cè)試集
參數(shù)如下:
-
dataset: 加載的數(shù)據(jù)集 -
batch_size: Batch 大小. -
batch_size_fn: 產(chǎn)生動(dòng)態(tài)的batch大小的函數(shù) -
sort_key: 排序的key -
train: 是否是一個(gè)訓(xùn)練集 -
repeat: 是否在不同epoch中重復(fù)迭代 -
shuffle: 是否打亂數(shù)據(jù) -
sort: 是否對(duì)數(shù)據(jù)進(jìn)行排序 -
sort_within_batch: batch內(nèi)部是否排序 -
device: 建立batch的設(shè)備 -1:CPU ;0,1 …:對(duì)應(yīng)的GPU
這里要注意的是sort_with_batch要設(shè)置為True,并指定排序的key為文本長(zhǎng)度,方便后面pytorch RNN進(jìn)行pack和pad。
使用方式如下:
# 生成迭代器
train_iter, test_iter = BucketIterator.splits((train, test),
batch_sizes=(3, 4),
device = torch.device("cpu"),
sort_key=lambda x: len(x.Phrase), # field sorted by len
sort_within_batch=True)
batch = next(iter(train_iter))
print(batch)
print(batch.Phrase)
print(batch.Sentiment)
print(TEXT.vocab.freqs['A'])
print(TEXT.vocab.stoi['<pad>'])
print(TEXT.vocab.itos[1])
for i, v in enumerate(TEXT.vocab.stoi):
if i == 5:
break
print(v)
# 結(jié)果
[torchtext.data.batch.Batch of size 3]
[.Phrase]:('[torch.LongTensor of size 24x3]', '[torch.LongTensor of size 3]')
[.Sentiment]:[torch.LongTensor of size 3]
(tensor([[ 2220, 13, 2],
[ 311, 3760, 51],
[ 5, 149, 1818],
[ 663, 5, 6233],
[ 15, 4, 109],
[ 17, 328, 65],
[13022, 10, 84],
[ 735, 964, 11],
[ 1028, 15, 12],
[ 6, 219, 1977],
[ 17, 3, 1696],
[14071, 15, 269],
[ 2148, 2, 455],
[ 7, 650, 10],
[ 321, 4957, 4],
[ 54, 5, 297],
[ 4, 11676, 633],
[ 8328, 12, 161],
[ 727, 4209, 14],
[ 160, 185, 4],
[ 56, 4482, 7474],
[ 6, 3, 1380],
[ 989, 9820, 704],
[ 8, 1839, 1]]), tensor([24, 24, 23]))
tensor([4, 2, 2])
2680
1
<pad>
<unk>
<pad>
the
,
a