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_SPACE
。 IS_SPACE
.
的所有其他代币将 return False
一直在尝试使用此处提到的基于规则的匹配在 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_SPACE
。 IS_SPACE
.
False