使用 spacy 和 Matcher 提取 NER 主题 + 动词的问题
Problem to extract NER subject + verb with spacy and Matcher
我在一个 NLP 项目上工作,我必须使用 spacy 和 spacy Matcher 来提取所有命名实体,它们是 nsubj(主题)和它相关的动词:我的 NE nsubj 的控制动词。
示例:
Georges and his friends live in Mexico City
"Hello !", says Mary
我需要在第一句中提取“Georges”和“live”,在第二句中提取“Mary”和“says”,但我不知道我的命名实体和它所涉及的动词。所以我决定更多地探索 spacy Matcher。
所以我正在努力在 Matcher 上写一个模式来提取我的 2 个单词。当 NE 主语在动词之前时,我得到了很好的结果,但我不知道如何编写一个模式来匹配与它相关的单词之后的 NE 主语。根据指南,我也可以用“常规空间”来完成这项任务,但我不知道该怎么做。 Matcher 的问题在于我无法管理 NE 和 VERB 之间的依赖类型并获取好的 VERB。我是 spacy 的新手,我一直在使用 NLTK 或 Jieba(针对中文)。我什至不知道如何用 spacy 标记句子中的文本。但我选择将整个文本分成句子以避免两个句子之间的错误匹配。
这是我的代码
import spacy
from nltk import sent_tokenize
from spacy.matcher import Matcher
nlp = spacy.load('fr_core_news_md')
matcher = Matcher(nlp.vocab)
def get_entities_verbs():
try:
# subjet before verb
pattern_subj_verb = [{'ENT_TYPE': 'PER', 'DEP': 'nsubj'}, {"POS": {'NOT_IN':['VERB']}, "DEP": {'NOT_IN':['nsubj']}, 'OP':'*'}, {'POS':'VERB'}]
# subjet after verb
# this pattern is not good
matcher.add('ent-verb', [pattern_subj_verb])
for sent in sent_tokenize(open('Le_Ventre_de_Paris-short.txt').read()):
sent = nlp(sent)
matches = matcher(sent)
for match_id, start, end in matches:
span = sent[start:end]
print(span)
except Exception as error:
print(error)
def main():
get_entities_verbs()
if __name__ == '__main__':
main()
即使是法语,我可以向你保证我得到了很好的结果
Florent regardait
Lacaille reparut
Florent baissait
Claude regardait
Florent resta
Florent, soulagé
Claude s’était arrêté
Claude en riait
Saget est matinale, dit
Florent allait
Murillo peignait
Florent accablé
Claude entra
Claude l’appelait
Florent regardait
Florent but son verre de punch ; il le sentit
Alexandre, dit
Florent levait
Claude était ravi
Claude et Florent revinrent
Claude, les mains dans les poches, sifflant
我有一些错误的结果,但 90% 是好的。我只需要抓住每行的第一个和最后一个字就可以得到我的夫妇 NE/verb。
所以我的问题是。当 NE 与它与 Matcher 相关的动词相关时,如何提取 NE 或者简单地如何使用 spacy(不是 Matcher)来做到这一点?有很多因素需要考虑。即使不可能 100%,您是否有一种方法来获得尽可能好的结果。
在这个模式之后,我需要一个匹配 VERB governor + NER subj 的模式:
pattern = [
{
"RIGHT_ID": "person",
"RIGHT_ATTRS": {"ENT_TYPE": "PERSON", "DEP": "nsubj"},
},
{
"LEFT_ID": "person",
"REL_OP": "<",
"RIGHT_ID": "verb",
"RIGHT_ATTRS": {"POS": "VERB"},
}
]
此模式全部归功于 polm23
这是依赖匹配器的完美用例。如果您在 运行 之前将实体合并为单个标记,它也会使事情变得更容易。此代码应满足您的需要:
import spacy
from spacy.matcher import DependencyMatcher
nlp = spacy.load("en_core_web_sm")
# merge entities to simplify this
nlp.add_pipe("merge_entities")
pattern = [
{
"RIGHT_ID": "person",
"RIGHT_ATTRS": {"ENT_TYPE": "PERSON", "DEP": "nsubj"},
},
{
"LEFT_ID": "person",
"REL_OP": "<",
"RIGHT_ID": "verb",
"RIGHT_ATTRS": {"POS": "VERB"},
}
]
matcher = DependencyMatcher(nlp.vocab)
matcher.add("PERVERB", [pattern])
texts = [
"John Smith and some other guy live there",
'"Hello!", says Mary.',
]
for text in texts:
doc = nlp(text)
matches = matcher(doc)
for match in matches:
match_id, (start, end) = match
# note order here is defined by the pattern, so the nsubj will be first
print(doc[start], "::", doc[end])
print()
我在一个 NLP 项目上工作,我必须使用 spacy 和 spacy Matcher 来提取所有命名实体,它们是 nsubj(主题)和它相关的动词:我的 NE nsubj 的控制动词。 示例:
Georges and his friends live in Mexico City
"Hello !", says Mary
我需要在第一句中提取“Georges”和“live”,在第二句中提取“Mary”和“says”,但我不知道我的命名实体和它所涉及的动词。所以我决定更多地探索 spacy Matcher。 所以我正在努力在 Matcher 上写一个模式来提取我的 2 个单词。当 NE 主语在动词之前时,我得到了很好的结果,但我不知道如何编写一个模式来匹配与它相关的单词之后的 NE 主语。根据指南,我也可以用“常规空间”来完成这项任务,但我不知道该怎么做。 Matcher 的问题在于我无法管理 NE 和 VERB 之间的依赖类型并获取好的 VERB。我是 spacy 的新手,我一直在使用 NLTK 或 Jieba(针对中文)。我什至不知道如何用 spacy 标记句子中的文本。但我选择将整个文本分成句子以避免两个句子之间的错误匹配。 这是我的代码
import spacy
from nltk import sent_tokenize
from spacy.matcher import Matcher
nlp = spacy.load('fr_core_news_md')
matcher = Matcher(nlp.vocab)
def get_entities_verbs():
try:
# subjet before verb
pattern_subj_verb = [{'ENT_TYPE': 'PER', 'DEP': 'nsubj'}, {"POS": {'NOT_IN':['VERB']}, "DEP": {'NOT_IN':['nsubj']}, 'OP':'*'}, {'POS':'VERB'}]
# subjet after verb
# this pattern is not good
matcher.add('ent-verb', [pattern_subj_verb])
for sent in sent_tokenize(open('Le_Ventre_de_Paris-short.txt').read()):
sent = nlp(sent)
matches = matcher(sent)
for match_id, start, end in matches:
span = sent[start:end]
print(span)
except Exception as error:
print(error)
def main():
get_entities_verbs()
if __name__ == '__main__':
main()
即使是法语,我可以向你保证我得到了很好的结果
Florent regardait
Lacaille reparut
Florent baissait
Claude regardait
Florent resta
Florent, soulagé
Claude s’était arrêté
Claude en riait
Saget est matinale, dit
Florent allait
Murillo peignait
Florent accablé
Claude entra
Claude l’appelait
Florent regardait
Florent but son verre de punch ; il le sentit
Alexandre, dit
Florent levait
Claude était ravi
Claude et Florent revinrent
Claude, les mains dans les poches, sifflant
我有一些错误的结果,但 90% 是好的。我只需要抓住每行的第一个和最后一个字就可以得到我的夫妇 NE/verb。 所以我的问题是。当 NE 与它与 Matcher 相关的动词相关时,如何提取 NE 或者简单地如何使用 spacy(不是 Matcher)来做到这一点?有很多因素需要考虑。即使不可能 100%,您是否有一种方法来获得尽可能好的结果。 在这个模式之后,我需要一个匹配 VERB governor + NER subj 的模式:
pattern = [
{
"RIGHT_ID": "person",
"RIGHT_ATTRS": {"ENT_TYPE": "PERSON", "DEP": "nsubj"},
},
{
"LEFT_ID": "person",
"REL_OP": "<",
"RIGHT_ID": "verb",
"RIGHT_ATTRS": {"POS": "VERB"},
}
]
此模式全部归功于 polm23
这是依赖匹配器的完美用例。如果您在 运行 之前将实体合并为单个标记,它也会使事情变得更容易。此代码应满足您的需要:
import spacy
from spacy.matcher import DependencyMatcher
nlp = spacy.load("en_core_web_sm")
# merge entities to simplify this
nlp.add_pipe("merge_entities")
pattern = [
{
"RIGHT_ID": "person",
"RIGHT_ATTRS": {"ENT_TYPE": "PERSON", "DEP": "nsubj"},
},
{
"LEFT_ID": "person",
"REL_OP": "<",
"RIGHT_ID": "verb",
"RIGHT_ATTRS": {"POS": "VERB"},
}
]
matcher = DependencyMatcher(nlp.vocab)
matcher.add("PERVERB", [pattern])
texts = [
"John Smith and some other guy live there",
'"Hello!", says Mary.',
]
for text in texts:
doc = nlp(text)
matches = matcher(doc)
for match in matches:
match_id, (start, end) = match
# note order here is defined by the pattern, so the nsubj will be first
print(doc[start], "::", doc[end])
print()