【问题标题】:Spacy tokenizer with only "Whitespace" rule只有“空白”规则的 Spacy 分词器
【发布时间】:2020-12-05 18:04:26
【问题描述】:

我想知道 spacy 分词器是否只能使用“空格”规则来分词。 例如:

sentence= "(c/o Oxford University )"

一般情况下,使用 spacy 的如下配置:

nlp = spacy.load("en_core_news_sm")
doc = nlp(sentence)
for token in doc:
   print(token)

结果是:

 (
 c
 /
 o
 Oxford
 University
 )

相反,我想要如下输出(使用 spacy):

(c/o 
Oxford 
University
)

是否可以使用 spacy 获得这样的结果?

【问题讨论】:

  • sentence.split(),不需要 SpaCy。
  • @DYZ 不幸的是,sentence.split() 没有像nlp(sentence) 那样提供任何 NLP 信息

标签: python python-3.x nlp spacy


【解决方案1】:

让我们将nlp.tokenizer 更改为自定义Tokenizertoken_match 正则表达式:

import re
import spacy
from spacy.tokenizer import Tokenizer

nlp = spacy.load('en_core_web_sm')
text = "This is it's"
print("Before:", [tok for tok in nlp(text)])

nlp.tokenizer = Tokenizer(nlp.vocab, token_match=re.compile(r'\S+').match)
print("After :", [tok for tok in nlp(text)])

Before: [This, is, it, 's]
After : [This, is, it's]

您可以通过添加自定义后缀、前缀和中缀规则来进一步调整Tokenizer

另一种更细粒度的方法是找出为什么 it's 令牌像 nlp.tokenizer.explain() 一样被拆分:

import spacy
from spacy.tokenizer import Tokenizer
nlp = spacy.load('en_core_web_sm')
text = "This is it's. I'm fine"
nlp.tokenizer.explain(text)

您会发现拆分是由于SPECIAL 规则:

[('TOKEN', 'This'),
 ('TOKEN', 'is'),
 ('SPECIAL-1', 'it'),
 ('SPECIAL-2', "'s"),
 ('SUFFIX', '.'),
 ('SPECIAL-1', 'I'),
 ('SPECIAL-2', "'m"),
 ('TOKEN', 'fine')]

可以更新以从以下异常中删除“it's”:

exceptions = nlp.Defaults.tokenizer_exceptions
filtered_exceptions = {k:v for k,v in exceptions.items() if k!="it's"}
nlp.tokenizer = Tokenizer(nlp.vocab, rules = filtered_exceptions)
[tok for tok in nlp(text)]

[This, is, it's., I, 'm, fine]

或完全删除撇号上的拆分:

filtered_exceptions = {k:v for k,v in exceptions.items() if "'" not in k}
nlp.tokenizer = Tokenizer(nlp.vocab, rules = filtered_exceptions)
[tok for tok in nlp(text)]

[This, is, it's., I'm, fine]

注意token附加的点,这是由于没有指定后缀规则造成的。

【讨论】:

    【解决方案2】:

    您可以在 spaCy 文档中找到这个问题的解决方案:https://spacy.io/usage/linguistic-features#custom-tokenizer-example。简而言之,您创建一个函数,它接受一个字符串 text 并返回一个 Doc 对象,然后将该可调用函数分配给 nlp.tokenizer

    import spacy
    from spacy.tokens import Doc
    
    class WhitespaceTokenizer(object):
        def __init__(self, vocab):
            self.vocab = vocab
    
        def __call__(self, text):
            words = text.split(' ')
            # All tokens 'own' a subsequent space character in this tokenizer
            spaces = [True] * len(words)
            return Doc(self.vocab, words=words, spaces=spaces)
    
    nlp = spacy.load("en_core_web_sm")
    nlp.tokenizer = WhitespaceTokenizer(nlp.vocab)
    doc = nlp("What's happened to me? he thought. It wasn't a dream.")
    print([t.text for t in doc])
    

    【讨论】:

      猜你喜欢
      • 2019-12-09
      • 1970-01-01
      • 1970-01-01
      • 2020-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-28
      相关资源
      最近更新 更多