blog9 EmbedRank中提取候选词的三个函数

本文介绍了如何使用NLTK库中的RegexpParser进行文本分析,通过extract_candidates函数提取候选词,包括处理子集问题和unique_ngram_candidates的原理。关键步骤包括利用正则表达式构建语法树、识别NP短语,并确保候选词的唯一性和无子集特性。
摘要由CSDN通过智能技术生成

2021SC@SDUSC

(续blog7)
用于提取候选词的三个函数:extract_candidates(text_obj, no_subset=False)、extract_sent_candidates(text_obj)、unique_ngram_candidates(strings)
参数以及返回值说明
根据一部分文字返回一组候选词:
参数text_obj:输入文本表示方式请参见@InputTextObj。
参数no_subset:如果为真,则一个候选词不能为另一个候选词的子集。
参数lang:语言种类,当前支持en(英语)、fr(法语)、de(德语)。
返回值:一组候选短语(每个候选词以字符串的形式)

一、extract_candidates(text_obj, no_subset=False)

创建一个空集合keyphrase_candidate

 keyphrase_candidate = set()

分析预先定义的分块语法grammar,得到多个语法规则,然后利用parser函数对句子分析,得到语法树:

 np_parser = nltk.RegexpParser(get_grammar(text_obj.lang))  # Noun phrase parser
 
 trees = np_parser.parse_sents(text_obj.pos_tagged)  # Generator with one tree per sentence

筛选出NP并做一定的处理:

for tree in trees:
        for subtree in tree.subtrees(filter=lambda t: t.label() == 'NP'):  # For each nounphrase
            # Concatenate the token with a space
            keyphrase_candidate.add(' '.join(word for word, tag in subtree.leaves()))
            
             keyphrase_candidate = {kp for kp in keyphrase_candidate if len(kp.split()) <= 5}

如果no_subset不存在一个候选词是另一个候选词子集的情况,那么将keyphrase转换成list,否则执行unique_ngram_candidates(keyphrase_candidate)函数(这个函数的作用在后面),并返回结果。

    if no_subset:
        keyphrase_candidate = unique_ngram_candidates(keyphrase_candidate)
    else:
        keyphrase_candidate = list(keyphrase_candidate)

    return keyphrase_candidate

二、extract_sent_candidates(text_obj)

这个函数只有一行代码,标记化句子(字符串)列表,每个标记由字符串中的空格分隔:

return [(' '.join(word for word, tag in sent)) for sent in text_obj.pos_tagged]

三、unique_ngram_candidates(strings)

返回在一个字符串中没有完全包含任何字符串的字符串列表:

results = []
    for s in sorted(set(strings), key=len, reverse=True):
        if not any(re.search(r'\b{}\b'.format(re.escape(s)), r) for r in results):
            results.append(s)
    return results

四、对RegexpParser类的学习补充

在函数extract_candidates(text_obj, no_subset=False)中,使用了RegexpPraser类来构造tree。在tree的构成中,分块是个重要的过程,如NP(DT,JJ,JJ,NN)可构成一个NP短语。nltk中有重要的类是RegexpParser,分析预先定义的分块语法grammar,得到多个语法规则,然后利用parser函数对句子分析,得到语法树。下面就介绍一个RegexpParser分析grammar的过程和parser函数的解析过程。

调用:cp=nltk.RegexpParser(grammar)
输入:分块语法grammar,有一个或多个识别块信息的正则表达式,如:

grammar = r"""
    NP: {<.*>*}             # start by chunking everything
    }<[\.VI].*>+{       # chink any verbs, prepositions or periods
    <.*>}{<DT>          # separate on determiners
    PP: {<IN><NP>}          # PP = preposition + noun phrase
    VP: {<VB.*><NP|PP>*}    # VP = verb words + NPs and PPs
    """

输出
过程:分析过程主要是在read_grammar函数里实现,当grammar是string类型时(如上),就调用read_grammar进行分析。下面就介绍一下分析过程中的要点:
(1)按行读取,并将每行的开头、结尾空格删除
(2)分离非终结符和规则,调用re.py里的match函数进行分离(其细节与chunk模块无关,这里就先不研究了),分离的依据仍然是正则表达式,冒号之前的是非终结符,如NP、PP、VP,冒号之后的是rule
(3)程序用stage来记录有多少个非终结符,一旦遇到非终结符就重设stage,将上一个rule记录下来(之所以记录的是上一个,是因为当前的rule尚未处理,可能存在注释,需要经过处理之后才能记录下来),因此在重设stage时需要判断rule是否为空,那么在首次记录时就不会报错
(4)对于记录rule的过程,首先设定识别chunk、chink、split和merge的规则:

{regexp}         # chunk rule
      }regexp{         # chink rule
      regexp}{regexp   # split rule
      regexp{}regexp   # merge rule  

因此,对于传入的rule,将进行如下处理:
①类似于分离非终结符和rule的方法,将rule和#注释分离,依据是#
②对于分离出的rule(不带注释),根据上面讲的规则,识别出对应的类别,分别调用ChunkRule、ChinkRule、SplitRule和MergeRule进行处理。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值