【问题标题】:how to write spacy matcher of POS regex如何编写 POS 正则表达式的 spacy 匹配器
【发布时间】:2017-03-16 09:39:16
【问题描述】:

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-

【问题讨论】:

    标签: nlp spacy


    【解决方案1】:

    当然,只需使用 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)
    

    【讨论】:

    • 看起来很有趣。两个问题 - 这是什么匹配数组?我只用数字打印它.. 第二 - 我可以以某种方式整合硬编码的单词(例如“什么”等) - 比如可以在 POS 和文本上工作的正则表达式?
    • 1.查看 spacy 包目录中的 matcher.py 文件,这里是关于 Matcher 对象的 call 方法的内容 - list (entity_key, label_id, start, end) 元组的列表,描述匹配项。一个匹配元组描述了一个 span doc[start:end]。 label_id 和 entity_key 都是整数。 2. 是的,试试这个 matcher.add_pattern("形容词和名词", [{POS: 'ADJ', LOWER:'main'}, {POS: 'NOUN'}])
    • 顺便说一句,matcher.add_pattern 已被弃用并替换为 matcher.add。 spacy.io/api/matcher
    【解决方案2】:

    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)
    

    【讨论】:

      猜你喜欢
      • 2021-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多