regex - Spacy 自定义标记生成器仅包含连字符单词作为使用 Infix 正则表达式的标记

标签 regex nlp tokenize spacy linguistics

我想包含连字符的单词,例如:长期、自尊等等,作为 Spacy 中的单个标记。在 StackOverflow 上查看了一些类似的帖子后,Github ,其 documentationelsewhere ,我还编写了一个自定义分词器,如下所示:

import re
from spacy.tokenizer import Tokenizer

prefix_re = re.compile(r'''^[\[\("']''')
suffix_re = re.compile(r'''[\]\)"']$''')
infix_re = re.compile(r'''[.\,\?\:\;\...\‘\’\`\“\”\"\'~]''')

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 “medicine” has become a profession; and more importantly, it\'s a male-dominated profession.')
[token.text for token in doc]

所以对于这句话: '注:自十四世纪以来,“医学”实践已成为一种职业;更重要的是,这是一个男性主导的职业。”

现在,合并自定义 Spacy Tokenizer 后的标记为:

'注释', ':', '自', '该', '第十四', '世纪', '该', '实践', '的', '“医学”,'','有',';','成为','a', '职业', ',', '并且', '更多', '重要', ',', “它是”,“a”,“男性主导”,“职业”,“。”

此前,此更改之前的代币为:

'注释', ':', '自', '该', '第十四', '世纪', '该', '实践', 'of', '', '医学', '', '有', '成为', 'a', '职业', ';', '和', '更多', '重要的是', ',', '', "", 'a', '男性', ' -', '主导', '职业', '.'

并且,预期的 token 应该是:

'注释', ':', '自', '该', '第十四', '世纪', '该', '实践', 'of', '', '医学', '', '有', '成为', 'a', '职业', ';', '和', '更多', '重要的是'、'、'、''、''、'a'、'男性主导'、'职业','。'

摘要:正如人们所看到的......

  • 包含连字符以及除双引号和撇号之外的其他标点符号...
  • ...但是现在,撇号和双引号没有以前或预期的行为。
  • 我尝试了针对 Infix 的正则表达式编译的不同排列和组合,但在解决此问题方面没有任何进展。

最佳答案

使用默认的 prefix_re 和 suffix_re 给出了预期的输出:

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'''[.\,\?\:\;\...\‘\’\`\“\”\"\'~]''')
    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 “medicine” has become a profession; and more importantly, it\'s a male-dominated profession.')
[token.text for token in doc]
['Note', ':', 'Since', 'the', 'fourteenth', 'century', 'the', 'practice', 'of', '“', 'medicine', '”', 'has', 'become', 'a', 'profession', ';', 'and', 'more', 'importantly', ',', 'it', "'s", 'a', 'male-dominated', 'profession', '.']

如果您想深入了解为什么您的正则表达式不像 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

关于regex - Spacy 自定义标记生成器仅包含连字符单词作为使用 Infix 正则表达式的标记,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51012476/

相关文章:

regex - ANT 删除空格正则表达式

regex - 匹配关键字数组中的属性字符串

nlp - 过滤掉无意义的短语

java - 在 java 中解析此字符串的最佳方法?

java - 在标记以下字符串 40 println "Hello ",(5+6-4), "-4"时,显示的是单个标记,而不是单独的标记

regex - 将正则表达式传递给 perl 子程序

regex - 匹配给定字符的文本,但不包括 Perl 中单引号内出现的字符

python - 分组相似的字符串

machine-learning - 机器学习/NLP文本分类: training a model from corpus of text files - scikit learn

python - 网站域的正则表达式是什么用于标记化,同时将标点符号与单词分开?