我是新手,使用以下脚本;
import spacy
from spacy.language import Language
from spacy.matcher import Matcher
nlp = spacy.load('en_core_web_sm')
text = "Google announced a new Pixel at Google I/O. The Google I/O is a great place to get all the updates from Google I/O."
def add_event_ent(matcher, doc, i, matches):
match_id, start, end = matches[i]
entity = doc[start:end]
print(entity.text, start, end)
pattern = [[
{"TEXT": "Google"},
{"TEXT": "I"},
{"TEXT": "/"},
{"TEXT": "O"},
{"IS_PUNCT": True, "OP": "?"}
]]
matcher = Matcher(nlp.vocab)
matcher.add("Google", pattern, on_match = add_event_ent)
doc = nlp(text)
matcher(doc)
输出:
Google I/O 11 15
[(11578853341595296054, 11, 15)]
我希望这能检测到Google I/O
的所有3次出现,但它没有,我不完全确定为什么。我尝试了一些不同的东西,但都不起作用,我认为问题已经到了尽头。
我用不同的文本和模式写了基本相同的代码片段:
text = "Hello, World! Hello, World! How are you?"
pattern = [[
{"LOWER": "hello"},
{"IS_PUNCT": True},
{"LOWER": "world"}
]]
matcher = Matcher(nlp.vocab)
matcher.add("Google", pattern, on_match = add_event_ent)
doc = nlp(text)
matcher(doc)
for ent in doc.ents:
print(f"[ENTITY] {ent.text:{15}} {ent.label_}")
print(doc)
输出:
Hello, World 0 3
Hello, World 4 7
Hello, World! Hello, World! How are you?
正如你所看到的,它确实起作用了。
我为第一个例子做了这个viz,以防它有帮助,这表明它不起作用,但我不确定为什么。
任何帮助都是感激的,让我知道如果我能提供更多的信息!
问题来自于标记化,O.
标记在此标记文本末尾包含.
字符。
不需要在pattern
中定义一个可选的标点符号,您可以用一个可选的尾随标点字符匹配任何O
符号。您可以使用正则表达式:
pattern = [[
{"TEXT": "Google"},
{"TEXT": "I"},
{"TEXT": "/"},
{"TEXT": {"REGEX": r"^O(?:_|[^ws])?$"}}
]]
输出:
Google I/O. 6 10
Google I/O 11 15
Google I/O. 25 29
这里,{"TEXT": {"REGEX": r"^O(?:_|[^ws])?$"}}
将匹配包含一个或两个字符的标记,从O
开始,然后包含一个可选的标点字符。
^
-令牌的起始(一般为字符串)O
-O
char(?:_|[^ws])?
-_
或(|
)除单词和空白字符以外的任何字符([^ws]
,一个否定的字符类,w
代表字母、数字和下划线,s
代表空白),1次或0次(由于?
量词)$
-令牌结束(一般为字符串)