【问题标题】:customize Tokenizer in spacy在 spacy 中自定义 Tokenizer
【发布时间】:2021-05-05 09:59:15
【问题描述】:

我正在使用 Spacy v2

我在文档中寻找日期,我希望分词器将它们合并

例如:

doc= 'Customer: Johnna 26 06 1989'

默认的分词器结果如下所示:

('Customer:', 'customer:', 'NUM', 'CD', 'amod', 'Xxxxx:', False, False)
('Johnna', 'Johnna ', 'PROPN', 'NNP', 'ROOT', 'xxxx', True, False)
('26', '26', 'NUM', 'CD', 'compound', 'dd', False, False)
('06', '06', 'NUM', 'CD', 'appos', 'dd', False, False)
('1989', '1989', 'NUM', 'CD', 'nummod', 'dddd', False, False)

虽然我希望它看起来像:

('Customer:', 'customer:', 'NUM', 'CD', 'amod', 'Xxxxx:', False, False)
('Johnna', 'Johnna ', 'PROPN', 'NNP', 'ROOT', 'xxxx', True, False)
('26 06 1989', '26', 'NUM', 'CD', 'compound', 'dd dd dd', False, False)

我尝试创建自定义标记器,但我不确定是否需要更改前缀或后缀_ 以及如何定义案例。

def __customize_tokenizer(self):
        prefix_re = re.compile(r'\d+\s+\d+')    
        return Tokenizer(self._nlp.vocab, prefix_search = prefix_re.search)

谢谢,

尼尔

【问题讨论】:

    标签: python spacy tokenize


    【解决方案1】:

    tokenizer 算法不支持这种模式:它的异常中不支持正则表达式,并且词缀模式不会跨空格应用。

    相反,一种选择是使用支持正则表达式的Matcher 查找这些情况,并使用重新标记器来合并标记:

    import spacy
    from spacy.matcher import Matcher
    
    nlp = spacy.blank("en")
    matcher = Matcher(nlp.vocab)
    matcher.add("DATE", [[{"ORTH": {"REGEX": "\d\d"}}, {"ORTH": {"REGEX": "\d\d"}}, {"ORTH": {"REGEX": "\d\d\d\d"}}]])
    
    text = "This is a date 01 02 2000 in a sentence."
    
    doc = nlp(text)
    
    with doc.retokenize() as retokenizer:
        for match_id, start, end in matcher(doc):
            retokenizer.merge(doc[start:end])
    
    print([t.text for t in doc])
    # ['This', 'is', 'a', 'date', '01 02 2000', 'in', 'a', 'sentence', '.']
    

    如果需要,您可以将匹配和重新标记化放入管道开头的自定义组件中,请参阅:https://v2.spacy.io/usage/processing-pipelines#custom-components

    【讨论】:

      【解决方案2】:

      你可以使用nlp.add_pipe("merge_entities"):

      将命名实体合并到一个标记中。也可以通过字符串名称"merge_entities" 获得。

      查看 Python sn-p:

      doc = nlp('Customer: Johnna 26 06 1989')
      nlp.add_pipe("merge_entities")
      print([(t.text, t.pos_, t.lemma_) for t in doc])
      # => [
      #      ('Customer', 'NOUN', 'customer'), 
      #      (':', 'PUNCT', ':'), 
      #      ('Johnna', 'PROPN', 'Johnna'),
      #      ('26 06 1989', 'NUM', '26 06 1989')
      #    ]
      

      【讨论】:

      • 谢谢,我认为它的想法相同,只是方式不同
      猜你喜欢
      • 2017-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多