spaCy NLP自定义规则匹配器

时间:2019-08-13 13:40:26

标签: python nlp nltk spacy

我是NLP的乞gg。我正在为我的NLP项目使用spaCy python库。这是我的要求,

我有一个包含所有国家/地区名称的JSON文件。现在,我需要解析并获取文档中每个国家的金牌数量。给定 在例句下方,

"Czech Republic won 5 gold medals at olympics. Slovakia won 0 medals olympics"

我能够获取国家/地区名称,但不能获取奖牌数量。下面给出我的代码。请帮助进一步进行操作。

import json
from spacy.lang.en import English
from spacy.matcher import PhraseMatcher

with open("C:\Python36\srclcl\countries.json") as f:
    COUNTRIES = json.loads(f.read())

nlp = English()
nlp.add_pipe(nlp.create_pipe('sentencizer'))
doc = nlp("Czech Republic won 5 gold medals at olympics. Slovakia won 0 medals olympics")
matcher = PhraseMatcher(nlp.vocab)
patterns = list(nlp.pipe(COUNTRIES))

matcher.add("COUNTRY", None, *patterns)


for sent in doc.sents:
    subdoc = nlp(sent.text)
    matches = matcher(subdoc)
    print (sent.text)
    for match_id, start, end in matches:
        print(subdoc[start:end].text)

此外,如果给定的文字是,

"Czech Republic won 5 gold medals at olympics in 1995. Slovakia won 0 medals olympics"

1 个答案:

答案 0 :(得分:2)

Spacy提供了Rule-based matching,供您使用。

它们可以按如下方式使用:

import spacy
from spacy.pipeline import EntityRuler
nlp = spacy.load('en_core_web_sm', disable=["ner", "parser"])

countries = ['Czech Republic', 'Slovakia']
ruler = EntityRuler(nlp)
for a in countries:
    ruler.add_patterns([{"label": "country", "pattern": a}])
nlp.add_pipe(ruler)


doc = nlp("Czech Republic won 5 gold medals at olympics. Slovakia won 0 medals olympics")

with doc.retokenize() as retokenizer:
    for ent in doc.ents:
        retokenizer.merge(doc[ent.start:ent.end])


from spacy.matcher import Matcher
matcher = Matcher(nlp.vocab)
pattern =[{'ENT_TYPE': 'country'}, {'lower': 'won'},{"IS_DIGIT": True}]
matcher.add('medal', None, pattern)
matches = matcher(doc)


for match_id, start, end in matches:
    span = doc[start:end]
    print(span)

输出:

  

捷克共和国赢了5
  斯洛伐克赢了0

上面的代码应该可以帮助您入门。自然,您将必须编写自己的更复杂的规则,以便可以处理以下情况: “捷克共和国在1995年奥运会上获得5枚金牌就不足为奇了。” 还有其他更复杂的句子结构。