spaCy处理文本的过程是模块化的,当调用nlp处理文本时,spaCy首先将文本标记化以生成Doc对象,而后,依次在几个不一样的组件中处理Doc,这也称为处理管道。语言模型默认的处理管道依次是:tagger、parser、ner等,每一个管道组件返回已处理的Doc,而后将其传递给下一个组件。git
spaCy使用的语言模型是预先训练的统计模型,可以预测语言特征,对于英语,共有en_core_web_sm、en_core_web_md和en_core_web_lg三种语言模型,使用spacy.load()函数来加载语言模型github
spacy.load(name,disable)
其中,name参数是语言模型的名词,disable参数是禁用的处理管道列表,例如,建立en_core_web_sm语言模型,并禁用ner:web
nlp = spacy.load("en_core_web_sm", disable=['ner'])
语言模型中不只预先定义了Language管道,还定义了处理文本数据的处理管道(pipeline),其中分词器是一个特殊的管道,它是由Language管道肯定的,不属于pipeline。api
{ "lang": "en", "name": "core_web_sm", "description": "Example model for spaCy", "pipeline": ["tagger", "parser", "ner"] }
在加载语言模型nlp以后,能够查看该语言模型预先定义的处理管道,也就是说,处理管道依赖于统计模型。app
1,查看nlp对象的管道模块化
>>> nlp.pipe_names ['tagger', 'parser', 'ner']
2,移除nlp的管道函数
nlp.remove_pipe(name)
3,向nlp的处理管道中增长管道ui
nlp.add_pipe(component, name=None, before=None, after=None, first=None, last=None)
Language管道是一个特殊的管道,当调用spacy.load()加载语言模型时,spaCy自动建立Lanuage管道,用于存储共享的词汇表、分词规则(Tokenization Rule)和文本注释。this
分词器管道是跟Language管道息息相关的一个管道,当建立Language管道以后,spaCy根据Language管道提供的词汇表来建立分词器。分词器用于把文本分为单词,标点符号,空格等标记,除了使用默认的分词器以外,spaCy容许用户根据须要对分词器进行调整:编码
from spacy.tokenizer import Tokenizer tokenizer = Tokenizer(vocab=nlp.vocab,rules,prefix_search, suffix_search, infix_search, token_match)
参数注释:
在文本处理的过程当中,spaCy首先对文本分词,原始文本在空格处分割,相似于text.split(' '),而后分词器(Tokenizer)从左向右依次处理token,在处理token时,spaCy作了两个check:
一个可选的布尔函数token_match,它匹配的字符串不会被拆分,覆盖之前的规则,对URL或数字之类的东西颇有用。
每一种语言都是不一样的,一般充满异常和特殊状况,尤为是最多见的单词。 其中一些例外是跨语言共享的,而其余例外则彻底具体,一般很是具体,须要进行硬编码。 spaCy.lang模块包含全部特定于语言的数据,以简单的Python文件组织,这使得数据易于更新和扩展。
每个单独的组件能够在语言模块种导入遍历,并添加到语言的Defaults对象种,某些组件(如标点符号规则)一般不须要自定义,能够从全局规则中导入。 其余组件,好比tokenizer和norm例外,则很是具体,会对spaCy在特定语言上的表现和训练语言模型产生重大影响。
例如,导入English模块,查看该模块的帮助:
from spacy.lang.en import English help(English)
经过这些模块来扩展语言,处理特殊的语法,一般在分词器(Tokenizer)中添加特殊规则和Token_Match函数来实现。
1,向分词器中添加特殊的规则
import spacy from spacy.symbols import ORTH, LEMMA, POS, TAG nlp = spacy.load("en_core_web_sm") # add special case rule special_case = [{ORTH: u"gim", LEMMA: u"give", POS: u"VERB"}, {ORTH: u"me"}] nlp.tokenizer.add_special_case(u"gimme", special_case)
2,设置特殊的规则来匹配token
建立一个自定义的分词器,使分词把https做为一个token:
import re import spacy from spacy.lang.en import English def my_en_tokenizer(nlp): prefix_re = spacy.util.compile_prefix_regex(English.Defaults.prefixes) suffix_re = spacy.util.compile_suffix_regex(English.Defaults.suffixes) infix_re = spacy.util.compile_infix_regex(English.Defaults.infixes) pattern_re = re.compile(r'^https?://') return spacy.tokenizer.Tokenizer(nlp.vocab, English.Defaults.tokenizer_exceptions, prefix_re.search, suffix_re.search, infix_re.finditer, token_match=pattern_re.match)
在处理文本时调用该分词器,把匹配到正则的文本做为一个token来处理:
nlp = spacy.load("en_core_web_sm") nlp.tokenizer = my_en_tokenizer(nlp) doc = nlp(u"Spacy is breaking when combining custom tokenizer's token_match, access https://github.com/explosion/spaCy to get details") print([t.text for t in doc])
3,自定义分词器
预先定义的分词器是按照空格来分词的,用于能够自定义分词器
### customer tokenizer class myTokenizer(object): def __init__(self, vocab): self.vocab = vocab def __call__(self, text): words=[] re_search=my_token_match(text) if re_search: for start,end in re_search.regs: if start >=0 and end>=0: words.append(text[start:end]) text=my_token_replace(text) split_words=my_token_split(text) print(split_words) words.extend([w for w in split_words if w!='']) # All tokens 'own' a subsequent space character in this tokenizer spaces = [True] * len(words) return Doc(self.vocab, words=words, spaces=spaces) ### parse the synonyms RE_SYNONYMS=parse_synonyms() def my_token_match(text): global RE_SYNONYMS return re.compile(RE_SYNONYMS).search(text) def my_token_replace(text): global RE_SYNONYMS return re.compile(RE_SYNONYMS).sub('',text) def my_token_split(text): #return re.compile('\s+|\W+|_+').split(text) return re.compile('\s+|\\+|_+').split(text)
引用自定义的分词器
nlp=spacy.load("en_core_web_sm") nlp.tokenizer = myTokenizer(nlp.vocab)
参考文档: