如何编写POS正则表达式的spacy matcher

时间:2017-03-16 09:39:17

标签: nlp spacy

Spacy有两个我想要合并的功能 - part-of-speech(POS)和rule-based matching

如何以整洁的方式组合它们?

例如 - 让我们说输入是单个句子,我想验证它是否符合某些POS排序条件 - 例如动词在名词后面(类似名词**动词正则表达式) 。结果应该是真的还是假的。那可行吗?或匹配器具体如示例

基于规则的匹配可以有POS规则吗?

如果没有 - 这是我目前的计划 - 将所有内容收集在一个字符串中并应用正则表达式

    import spacy
nlp = spacy.load('en')
#doc = nlp(u'is there any way you can do it')
text=u'what are the main issues'
doc = nlp(text)

concatPos = ''
print(text)
for word in doc:
    print(word.text, word.lemma, word.lemma_, word.tag, word.tag_, word.pos, word.pos_)
    concatPos += word.text +"_" + word.tag_ + "_" + word.pos_ + "-"
print('-----------')
print(concatPos)
print('-----------')

# output of string- what_WP_NOUN-are_VBP_VERB-the_DT_DET-main_JJ_ADJ-issues_NNS_NOUN-

2 个答案:

答案 0 :(得分:7)

当然,只需使用POS属性。

import spacy
nlp = spacy.load('en')
from spacy.matcher import Matcher
from spacy.attrs import POS
matcher = Matcher(nlp.vocab)
matcher.add_pattern("Adjective and noun", [{POS: 'ADJ'}, {POS: 'NOUN'}])

doc = nlp(u'what are the main issues')
matches = matcher(doc)

答案 1 :(得分:3)

Eyal Shulman的回答很有帮助,但是它使您很难对模式匹配器进行编码,而不是完全使用正则表达式。

我想使用正则表达式,所以我制定了自己的解决方案:

    pattern = r'(<VERB>)*(<ADV>)*(<PART>)*(<VERB>)+(<PART>)*' 
    ## create a string with the pos of the sentence
    posString = ""
    for w in doc[start:end].sent:
        posString += "<" + w.pos_ + ">"

    lstVerb = []
    for m in re.compile(pattern).finditer(posString):
        ## each m is a verb phrase match
        ## count the "<" in m to find how many tokens we want
        numTokensInGroup = m.group().count('<')

        ## then find the number of tokens that came before that group.
        numTokensBeforeGroup = posString[:m.start()].count('<') 

        verbPhrase = sentence[numTokensBeforeGroup:numTokensBeforeGroup+numTokensInGroup]
        ## starting at character offset m.start()
        lstVerb.append(verbPhrase)