当前位置:   article > 正文

【Pytorch】【torchtext(二)】Field详解_torchtext field

torchtext field
from torchtext.data import Field,Example,Dataset
from torchtext import vocab
import os
import nltk
  • 1
  • 2
  • 3
  • 4

一、Field

1. 参数说明

squential:数据是否为序列数据,默认为Ture。如果为False,则不能使用分词。

use_vocab:是否使用词典,默认为True。如果为False,那么输入的数据类型必须是数值类型(即使用vocab转换后的)。

init_token:文本的其实字符,默认为None。

eos_token:文本的结束字符,默认为None。

fix_length:所有样本的长度,不够则使用pad_token补全。默认为None,表示灵活长度。

tensor_type:把数据转换成的tensor类型 默认值为torch.LongTensor。

preprocessing:预处理pipeline, 用于分词之后、数值化之前,默认值为None。

postprocessing:后处理pipeline,用于数值化之后、转换为tensor之前,默认为None。

lower:是否把数据转换为小写,默认为False;

tokenize:分词函数,默认为str.split

include_lengths:是否返回一个已经补全的最小batch的元组和和一个包含每条数据长度的列表,默认值为False。

batch_first:batch作为第一个维度;

pad_token:用于补全的字符,默认为<pad>。

unk_token:替换袋外词的字符,默认为<unk>。

pad_first:是否从句子的开头进行补全,默认为False;

truncate_first:是否从句子的开头截断句子,默认为False;

stop_words:停用词;

2. 例子

# 1.数据
corpus = ["D'aww! He matches this background colour",
         "Yo bitch Ja Rule is more succesful then",
         "If you have a look back at the source"]
labels = [0,1,0]
# 2.定义不同的Field
TEXT = Field(sequential=True, lower=True, fix_length=10,tokenize=str.split,batch_first=True)
LABEL = Field(sequential=False, use_vocab=False)
fields = [("comment", TEXT),("label",LABEL)]
# 3.将数据转换为Example对象的列表
examples = []
for text,label in zip(corpus,labels):
    example = Example.fromlist([text,label],fields=fields)
    examples.append(example)
print(type(examples[0]))
print(examples[0].comment)
print(examples[0].label)
# 4.构建词表
new_corpus = [example.comment for example in examples]
TEXT.build_vocab(new_corpus)
print(TEXT.process(new_corpus))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
<class 'torchtext.data.example.Example'>
["d'aww!", 'he', 'matches', 'this', 'background', 'colour']
0
tensor([[ 8, 10, 15, 22,  5,  7,  1,  1,  1,  1],
        [23,  6, 13, 17, 12, 16, 19, 21,  1,  1],
        [11, 24,  9,  2, 14,  4,  3, 20, 18,  1]])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

二、Tokenize

Field中的参数tokenize必须是一个函数,其作用是给定一个字符串,该函数以列表的形式返回分词结果。这里以jieba分词为例:

import jieba
# jieba分词返回的是迭代器,因此不能直接作为tokenize
print(jieba.cut("我爱北京天安门"))
# 使用lambda定义新的函数cut,其直接返回分词结果的列表,这样才可以作为tokenize
cut = lambda x:list(jieba.cut(x))
cut("我爱北京天安门")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
<generator object Tokenizer.cut at 0x000002038CEFF938>
['我', '爱', '北京', '天安门']
  • 1
  • 2

三、Vocab

前面的代码中Field对象TEXT通过调用build_vocab()方法来生成一个内置的Vocab对象,即TEXT.build_vocab(new_corpus)。下面看一下Vocab对象的常见用法:

print(type(TEXT.vocab.freqs)) # freqs是一个Counter对象,包含了词表中单词的计数信息
print(TEXT.vocab.freqs['at'])
print(TEXT.vocab.itos[1]) # itos表示index to str
print(TEXT.vocab.stoi['<unk>']) # stoi表示str to index
print(TEXT.vocab.unk_index)
print(TEXT.vocab.vectors) # 词向量
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
<class 'collections.Counter'>
1
<pad>
0
0
None
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

四、Vectors

可以看到TEXT.vocab.vectors为None,因为在build_vocab()没有指定参数vectors,此时可以通过load_vectors方法来加载词向量。load_vectors的参数可以是字符串(例如:“fasttext.en.300d”),其会自动下载词向量并缓存到本地。但如果是自己训练的词向量,则需要指定词向量在本地的路径。

1. 自动下载并加载词向量

TEXT.vocab.load_vectors('fasttext.en.300d')
print(TEXT.vocab.vectors.shape)
  • 1
  • 2
torch.Size([25, 300])
  • 1

2.加载本地词向量

p = os.path.expanduser("~\\.vector_cache\\sgns.wiki.bigram-char")
TEXT.vocab.load_vectors(vocab.Vectors(p))
  • 1
  • 2

五、自定义Field

这里自定义Field,其通过字符串(例如:“nltk”、“jieba”、“str”)等方式指定tokenize,并且能够通过名称来指定自定义的词向量。

1. 定义

class MyField(Field):
    def __init__(self, tokenize="nltk",**kwargs):
        self.tokenize_name = tokenize
        tokenize = MyField._get_tokenizer(tokenize)
        super(MyField, self).__init__(tokenize=tokenize, **kwargs)
        
    @staticmethod
    def _get_tokenizer(tokenizer):
        if tokenizer=='nltk':
            return nltk.word_tokenize
        elif tokenizer=='jieba':
            return lambda x:list(jieba.cut(x))
        elif tokenizer=='split':
            return str.split
        else:
            raise ValueError("不支持的tokenizer")
    
    @classmethod
    def _get_vector_data(cls, vecs):
        if not isinstance(vecs, list):
            vecs = [vecs]
            
        vec_datas = []
        for vec in vecs:
            if not isinstance(vec, vocab.Vectors):
                if vec=="fasttext":
                    embed_file = os.path.expanduser("~\\.vector_cache\\wiki-news-300d-1M.vec")
                    vec_data = vocab.Vectors(embed_file)
                elif vec=='sgns':
                    embed_file = os.path.expanduser("~\\.vector_cache\\sgns.wiki.bigram-char")
                    vec_data = vocab.Vectors(embed_file)
                else:
                    raise ValueError("不支持的词向量类型")
                vec_datas.append(vec_data)            
            else:
                vec_datas.append(vec)
        return vec_datas
    
    def build_vocab(self, *args, vectors=None, **kwargs):
        if vectors is not None:
            vectors = MyField._get_vector_data(vectors)
        super(MyField, self).build_vocab(*args, vectors=vectors, **kwargs)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

2.调用

corpus = ["D'aww! He matches this background colour",
         "Yo bitch Ja Rule is more succesful then",
         "If you have a look back at the source"]
TEXT = MyField(sequential=True, lower=True, fix_length=10,tokenize="jieba",batch_first=True)
fields = [("comment", TEXT)]
examples = []
for text in corpus:
    example = Example.fromlist([text],fields=fields)
    examples.append(example)
data = Dataset(examples, fields)
TEXT.build_vocab(data, vectors="sgns")
print(len(TEXT.vocab.freqs))
print(TEXT.vocab.vectors.shape)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
<class 'torchtext.vocab.Vectors'>
27
torch.Size([29, 300])
  • 1
  • 2
  • 3
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/378360
推荐阅读
相关标签
  

闽ICP备14008679号