spaCy 'IS_SPACE' 标志不起作用

spaCy 'IS_SPACE' flag doesn't work

一直在尝试使用此处提到的基于规则的匹配在 spaCy 上匹配“$125.00/share”之类的东西 https://github.com/explosion/spaCy/issues/882。但是,在尝试时

nlp = en_core_web_sm.load()
matcher = Matcher(nlp.vocab)

doc = nlp(u'5.00/share, $ 125 / share, $ 125.00 / share, $ 125 . 00 / share')

token_pattern = [{'NORM': '$'}, {'IS_DIGIT': True}, {'ORTH': '.', 'OP': '?'}, 
             {'IS_DIGIT': True, 'OP': '?'}, {'ORTH': '/'}, {'LOWER': 'share'}]

def matched_pattern (matcher, doc, i, matches):
    match_id, start, end = matches[i]
    span = doc[start: end]
    print ('matched!', span)

matcher.add('SharePrice', matched_pattern, token_pattern)

matches = matcher(doc)

我回来了,

('matched!', $125/股)
('matched!', 125 . 00 美元/股)

相反,我想匹配像“$125.00/share”这样的模式,中间没有空格。尝试时,

 token_pattern = [{'NORM': '$'}, {'IS_SPACE': False}, {'IS_DIGIT': True}, {'IS_SPACE': False},{'ORTH': '.', 'OP': '?'}, {'IS_SPACE': False}, 
             {'IS_DIGIT': True, 'OP': '?'}, {'IS_SPACE': False}, {'ORTH': '/'}, {'IS_SPACE': False}, {'LOWER': 'share'}]

我的表情不符合任何模式。请帮忙!

这里的问题是匹配模式中的每个字典都描述了一个实际的、现有的标记——所以{'IS_SPACE': False}将匹配任何不是白色的标记space 字符(例如,带有文本 "dog" 或“123”或任何其他内容的标记)。匹配器无法匹配 缺少令牌

我刚刚尝试了您的示例,默认情况下,spaCy 的分词器将“$125.00/share”拆分为两个分词:['$', '125.00/share']。当匹配器遍历标记时,它不会匹配,因为它正在寻找货币符号 + 非 space 字符 + 数字 + 一堆其他标记。

因此,为了匹配令牌“125.00/share”的更具体部分——比如数字、正斜杠和 "share"——你必须确保 spaCy 将它们拆分成单独的部分令牌。您可以通过 customising the tokenization rules 并添加一个新的中缀规则来拆分 / 个字符上的标记。这将导致“$125.00/share”→ ['$', '125.00', '/', 'share'],这将与您的模式相匹配。

顺便说一句,一些关于白色space 标记的背景:在标记化过程中,spaCy 在单个白色space 字符上拆分标记。这些字符将不能作为单独的标记使用(但为了确保没有信息丢失,可以通过 .text_with_ws_ 属性访问它们)。但是,如果存在多个白色 space 字符,spaCy 会将这些字符保留为标记,这将 return True for IS_SPACEIS_SPACE.

的所有其他代币将 return False