美文网首页
信息提取

信息提取

作者: 青椒rose炒饭 | 来源:发表于2019-07-10 14:38 被阅读0次

    用于实体识别的基本技术是分块(chunking),如下将多个单词合并成句子的一个部分就是分块。


    分块示意图

    名词短语分块

    名词短语分块的组成:限定词(a/an/the等)AT + 一个或多个形容词(JJ)+ 名词(NN)组成。

    import nltk
    sent = "she is a beautiful girl and a good daughter"
    #分词
    words = sent.split()
    print("分词结果:",words)
    #标注词性
    t1 = nltk.DefaultTagger("NN")
    patterns = [
        (r'.*ing$',"VBG"),
        (r'.*ed$',"VBD"),
        (r'.*es$',"VBZ"),
        (r'.*ould$',"MD"),
        (r'.*\'s$',"NN"),
        (r'.*s$',"NNS"),
        (r'^-?[0-9]+(.[0-9]+)?$',"CD"),
        (r'.*',"NN")  #匹配所有单词,默认标注为NN
    ]
    t2 = nltk.RegexpTagger(patterns,backoff=t1)
    words_tagged = nltk.corpus.brown.tagged_words(categories="news")
    cfd = nltk.ConditionalFreqDist(words_tagged)
    words_pos = {w:cfd[w].max() for w in cfd.conditions()}
    t3 = nltk.UnigramTagger(model=words_pos,backoff=t2)
    # print(nltk.corpus.brown.categories())
    # brown_tagged_sents = nltk.corpus.brown.tagged_sents(categories='news')
    # print(brown_tagged_sents)
    # print(t3.evaluate(brown_tagged_sents))
    words = t3.tag(words)
    print(words)
    grammar = "NP:{<AT>?<JJ>*<NN>}"
    cp = nltk.RegexpParser(grammar)
    result = cp.parse(words)
    print(result)
    result.draw()
    
    分块

    模式标记

    一个标记模式是一个用尖括号分隔的词性标记序列,如<DT>?<JJ>*<NN>。和上面的程序例子差不多。

    探索文本语料库

    在句子中提取词性序列的短语使用分块器更方便。将布朗语料库中词性组合为V开头的词性,中间to后面也是V开头的词性的词组找出来。至于它这个tree就让我难以理解了。

    import nltk
    cp = nltk.RegexpParser("chunk:{<V.*> <TO> <V.*>}")
    brown = nltk.corpus.brown
    
    for sent in brown.tagged_sents():
        tree = cp.parse(sent)
        for subtree in tree.subtrees():
            if subtree.label() == 'chunk':print(subtree)
    

    加缝隙

    为不包含在块中的标识符序列定义一个缝隙
    下面的例子,barked/VBD at/IN就是一个缝隙。

    [the/DT little/JJ yellow/JJ dog/NN] barked/VBD at/IN [the/DT cat/NN]

    加缝隙是为了在块中去除一个标识符序列,如果整块都匹配这个标识符序列,则这个块将会被去除,如果在中间标识符部分将会被去除,以前的一个块变成两个块。如果是在块的两边去除这个标识符之后块将会减小。

    import nltk
    
    #块的震泽表达式,匹配的名字叫做NP
    # 第一行匹配任何东西
    # 第二行将句子中的VBD或者IN单独提取出来作为一部分,其他的合并成一部分
    grammar = r'''
        NP:
            {<.*>+}
            }<VBD|IN>+{
    '''
    #文本
    sentence = [("the", "DT"), ("little", "JJ"), ("yellow", "JJ"),
    ("dog", "NN"), ("barked", "VBD"), ("at", "IN"), ("the", "DT"), ("cat", "NN")]
    #解析块正则表达式
    cp = nltk.RegexpParser(grammar)
    #输出句子内容
    print(cp.parse(sentence))
    
    运行结果

    在这个程序的基础上再次来理解一下前面个那个tree使用RegexpParser 的对象解析句子之后会得到句子的结构树,从运行结果看,树的根节点为s 树有四个部分(NP + barked + at + NP),其中的NP是我们的块正则表达式中命名的。

    从运行结果可以看到,使用 }......{ 这样的正则表达式将两个符号中间的内容单独分离了出去,剩下的内容单独成为两块。

    块的表示:标记与树

    用IOB标记表示块

    I 内部 ,O外部 , B开始,标注的时候需要加上块类型的后缀,如果是内部的NP块,则标注为I-NP

    IOB标记表示块

    还有一种就是上面的树的表示方法


    树结构表示块

    相关文章

      网友评论

          本文标题:信息提取

          本文链接:https://www.haomeiwen.com/subject/ezhbhctx.html