关于nlp:Spacy自定义标记生成器,使用Infix正则表达式仅包含连字符作为标记

Spacy custom tokenizer to include only hyphen words as tokens using Infix regex

我想包括连字词,例如:长期,自尊等,作为Spacy中的单个标记。在查看了StackOverflow,Github,其文档和其他地方的一些类似文章之后,我还编写了一个自定义令牌生成器,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import re
from spacy.tokenizer import Tokenizer

prefix_re = re.compile(r'''^[\\[\\("']''')
suffix_re = re.compile(r'''[\\]\\)"']$''')
infix_re = re.compile(r'''[.\\,\\?\\:\\;\\...\\a€?\\a€?\\`\\a€?\\a€?"\'~]''')

def custom_tokenizer(nlp):
    return Tokenizer(nlp.vocab, prefix_search=prefix_re.search,
                                suffix_search=suffix_re.search,
                                infix_finditer=infix_re.finditer,
                                token_match=None)

nlp = spacy.load('en_core_web_lg')
nlp.tokenizer = custom_tokenizer(nlp)

doc = nlp(u'Note: Since the fourteenth century the practice of a€?medicinea€? has become a profession; and more importantly, it\'s a male-dominated profession.')
[token.text for token in doc]

所以这句话:
注意:自14世纪以来,"医学疗法"的实行已经成为一种职业;而且更重要的是,它是男性主导的职业。\\'

现在,合并自定义Spacy令牌生成器后的令牌为:

\\'Note \\',\\':\\',\\'Since \\',\\'the \\',\\'第十四\\',\\'世纪\\',\\'the \\',\\'实践\\' ,\\'of \\',
\\'a€?medicine \\',\\'a€?\\',\\'has \\',\\'; \\',\\'成为\\',\\'a \\',
\\'专业\\',\\',\\',\\'和\\',\\'更多\\',\\'重要\\',\\',\\',
" it \\'s ",\\'a \\',\\'男性主导\\',\\'专业\\',\\'。\\'

之前,此更改之前的令牌为:

\\'Note \\',\\':\\',\\'Since \\',\\'the \\',\\'第十四\\',\\'世纪\\',\\'the \\',\\'实践\\' ,\\'of \\',\\'a€?\\',\\'medicine \\',\\'a€?\\',\\'has \\',\\'成为\\',\\'a \\',\\'专业\\',\\'; \\',\\'和\\',\\'更多\\',\\'重要\\',\\',\\',\\'it \\'," \\'s ",\\'a \\',\\'male \\',\\'-\\',\\'dominated \\',\\'profession \\',\\'。\\'

而且,预??期令牌应为:

\\'Note \\',\\':\\',\\'Since \\',\\'the \\',\\'第十四\\',\\'世纪\\',\\'the \\',\\'实践\\' ,\\'of \\',\\'a€?\\',\\'medicine \\',\\'a€?\\',\\'has \\',\\'成为\\',\\'a \\',\\'专业\\',\\'; \\',\\'和\\',\\'更多\\',\\'重要\\',\\',\\',\\'it \\'," \\'s ",\\'a \\',\\'男性主导\\',\\'专业\\',\\'。\\'

摘要:正如大家所看到的...

  • 包括连字符,除双引号和撇号外的其他标点符号也包括在内。
  • ...但是现在,单引号和双引号没有更早的行为或预期的行为。
  • 我为Infix尝试了正则表达式的不同排列和组合,但没有解决此问题的进度。


使用默认的prefix_re和suffix_re为我提供了预期的输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import re
import spacy
from spacy.tokenizer import Tokenizer
from spacy.util import compile_prefix_regex, compile_infix_regex, compile_suffix_regex

def custom_tokenizer(nlp):
    infix_re = re.compile(r'''[.\\,\\?\\:\\;\\...\\a€?\\a€?\\`\\a€?\\a€?"\'~]''')
    prefix_re = compile_prefix_regex(nlp.Defaults.prefixes)
    suffix_re = compile_suffix_regex(nlp.Defaults.suffixes)

    return Tokenizer(nlp.vocab, prefix_search=prefix_re.search,
                                suffix_search=suffix_re.search,
                                infix_finditer=infix_re.finditer,
                                token_match=None)

nlp = spacy.load('en')
nlp.tokenizer = custom_tokenizer(nlp)

doc = nlp(u'Note: Since the fourteenth century the practice of a€?medicinea€? has become a profession; and more importantly, it\'s a male-dominated profession.')
[token.text for token in doc]

['Note',':','Since','the','第十四','century','the','practice','of','a€?','medicine'," a€?","有","成为"," a","专业",";","和","更多","重要",",","它"," s" ," a","男性主导","职业","。"]

如果您想深入了解为什么正则表达式不能像SpaCy一样正常工作,请参见以下相关源代码的链接:

此处定义的前缀和后缀:

https://github.com/explosion/spaCy/blob/master/spacy/lang/punctuation.py

参考此处定义的字符(例如,引号,连字符等):

https://github.com/explosion/spaCy/blob/master/spacy/lang/char_classes.py

以及用于编译它们的函数(例如compile_prefix_regex):

https://github.com/explosion/spaCy/blob/master/spacy/util.py