赞
踩
tokenizers是数据模块中的一个子模块,在里面主要包含了token与tokenizer的定义和使用,现在做一个简单的介绍,描述字符串是如何载入到TextFields中的。
简单的token抽象,其属性包括文本,偏移量,pos tag,依存关系等,tokenizer的输出被定义为一连串(list)的Token。
分词器类,Tokenizers将字符串分割成独立的token,如果需要自己定义一个分词类的话,通过重写其tokenize
方法便可以实现,可分为word-level与character-level。Allennlp
里一般有如下三种方法:
Characters
(“AllenNLP is great” → [“A”, “l”, “l”, “e”, “n”, “N”, “L”, “P”, " ", “i”, “s”, " ", “g”, “r”, “e”, “a”, “t”])Wordpieces
(“AllenNLP is great” → [“Allen”, “##NL”, “##P”, “is”, “great”])Words
(“AllenNLP is great” → [“AllenNLP”, “is”, “great”])需要注意的是在Characters
中,空格也是一个字符,Wordpieces
和Words
相似,但是进一步将单词分为子单词单元。在AllenNLP
中,如果每个单词有单独的向量很重要,用户选择的分词法决定了哪些对象将在模型中被分配单个向量(例如,这样用户就可以为它预测一个NER或POS标记),即使希望该向量依赖于字符级表示,用户也需要从词级分割开始。
常用的Tokenizers
如下:
spaCy’s tokenizer
,支持多种语言,不过需要科学上网;PretrainedTransformerTokenizer
,使用Hugging Face
的transformers
库中的 tokenizer
。CharacterTokenizer
,它将字符串拆分为单个字符,包括空格。WhitespaceTokenizer
,默认已经按照空格分好了词,将字符串按照空格切分LettersDigitsTokenizer
,按照数字与标点符号进行切分下面是tokenizer
的代码示例:
from allennlp.data.tokenizers.letters_digits_tokenizer import LettersDigitsTokenizer from allennlp.data.tokenizers import CharacterTokenizer, WhitespaceTokenizer from allennlp.data.tokenizers import Tokenizer, Token from typing import List from overrides import overrides import jieba english_text = "hello world ! Today is sunday ! I'm going to play Civilization6 ." chinese_text = "大家好啊!今天是星期日!我准备玩文明6。" # 按照空格切分 print("white space tokenizer result:", WhitespaceTokenizer().tokenize(english_text)) print("white space tokenizer result:", WhitespaceTokenizer().tokenize(chinese_text)) # 按照字符切分 print("character tokenizer result:", CharacterTokenizer().tokenize(english_text)) print("character tokenizer result:", CharacterTokenizer().tokenize(chinese_text)) # 除了空格,按照数字与标点符号进行切分 print("letter digits tokenizer result:", LettersDigitsTokenizer().tokenize(english_text)) print("letter digits tokenizer result:", LettersDigitsTokenizer().tokenize(chinese_text)) # 自定义jieba分词类,实现中文分词 class JiebaTokenizer(Tokenizer): @overrides def tokenize(self, text: str) -> List[Token]: return [Token(_) for _ in list(jieba.cut(text))] print("jieba tokenizer result:", JiebaTokenizer().tokenize(chinese_text))
在tokenizers
模块中还有sentence_splitter
模块,实现了分句接口。
tokenizer
都实现了一个tokenize()方法
,该方法返回Token
列表。Token
是一个轻量级的数据类,类似于spaCy
的Token
。
即文本字段,继承了SequenceField,代表一连串字符token。在建立本对象之前,需要先使用
Tokenizer类对原始文本进行分词。构造函数须有tokens,token_indexers两个参数。
TextField
从Tokenizers
获取Token
列表,并将每个Token
表示为一个数组,模型可以将该数组转换为向量。 TextFields
实现了Field API
,该API包括以下方法:对词汇表项目进行计数,将字符串转换为整数,然后转换为张量,并使用适当的填充将若干张量组合在一起。 为了在实际操作中保持灵活性,TextField
将这些操作的大部分功能转移给了TokenIndexers
集合,该集合实际上负责确定如何表示每个Token
。 创建一个TextField
,代码编写如下:
tokenizer = ... # Whatever tokenizer you want
sentence = "We are learning about TextFields"
tokens = tokenizer.tokenize(sentence)
token_indexers = {...} # we'll talk about this in the next section
text_field = TextField(tokens, token_indexers)
...
instance = Instance({"sentence": text_field, ...})
通过上面的代码,我们知道了text经过tokenizer的处理,得到一连串的token,而这些token将会作为初始化参数实例化TextField类,同时TextField类的实例化还需要传入token_indexers,在下一节,将介绍token_indexers是什么和怎么使用。
参考资料
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。