TorchText文本數(shù)據(jù)集讀取操作

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, DatasetExample實(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
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容