使用spacy,如何确保字母序列不会被拆分为标记

2024-04-20 11:45:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在寻找一种方法来确保每当序列"#*"出现在文本中时,spacy都会给我标记"#*"。我尝试了各种可能的方法来添加add_special_case的特殊情况,使用prefix_searchsuffix_searchinfix_finditertoken_match构建一个自定义标记器,但是仍然存在这样的情况:如果一个"#*"出现在一个句子中,即使它被不奇怪的标记(应该毫无问题地被识别的标记)包围,也会将"#*"拆分为 [#, *]. 我能做什么?你知道吗

谢谢。你知道吗


Tags: 方法标记文本tokenaddsearchprefixspacy
1条回答
网友
1楼 · 发布于 2024-04-20 11:45:39

Spacy目前对包含前缀或后缀字符的特殊情况的处理并不理想,也不是您在所有情况下所期望的那样。你知道吗

用文本外观和标记化不起作用的地方的示例来回答这个问题会更容易一些,但是:

如果#*总是被空格包围,则应使用特殊情况:

nlp.tokenizer.add_special_case("#*", [{"ORTH": "#*"}])
print([t.text for t in nlp("a #* a")]) # ['a', '#*', 'a']

如果#*应该像to一样进行标记化,那么一个选项是从前缀和后缀中删除#*,然后这些字符与to没有任何区别。相邻的标点符号会被分割成词缀,相邻的字母/数字则不会。你知道吗

如果#*可能与任何其他字符(如#*aa#*a"#*")相邻,则最容易将其添加为前缀、后缀和中缀,将其添加到默认模式之前,以便像#这样的默认模式不会首先匹配:

prefixes = ("#\*",) + nlp.Defaults.prefixes
nlp.tokenizer.prefix_search = spacy.util.compile_prefix_regex(prefixes).search
suffixes = ("#\*",) + nlp.Defaults.suffixes
nlp.tokenizer.suffix_search = spacy.util.compile_suffix_regex(suffixes).search
infixes = ("#\*",) + nlp.Defaults.infixes + ("#\*",)
nlp.tokenizer.infix_finditer = spacy.util.compile_infix_regex(infixes).finditer

print([t.text for t in nlp("a#* a#*a #*a '#*'")])
# ['a', '#*', 'a', '#*', 'a', '#*', 'a', "'", '#*', "'"]

这是一个很好的例子,可以使用刚刚添加了标记器的新调试函数(免责声明:我是作者)。使用spacy v2.2.3,请尝试:

nlp.tokenizer.explain('#*')

输出[('PREFIX', '#'), ('SUFFIX', '*')]告诉您哪些模式负责生成的标记化。当您修改模式时,这个函数应该可以让您更容易地看到您的修改是否按预期工作。你知道吗

在上述最后一个示例中进行修改后,输出为:

nlp.tokenizer.explain("a#* a#*a #*a '#*'")
# [('TOKEN', 'a'), ('SUFFIX', '#*'), ('TOKEN', 'a'), ('INFIX', '#*'), ('TOKEN', 'a'), ('PREFIX', '#*'), ('TOKEN', 'a'), ('PREFIX', "'"), ('PREFIX', '#*'), ('SUFFIX', "'")]

相关问题 更多 >