美文网首页
复习句子分块

复习句子分块

作者: 青椒rose炒饭 | 来源:发表于2019-07-11 16:27 被阅读0次

    分块的意义何在?

    以我现在的水平我觉得,将句子相关的部分合并成一块之后,对于理解句子的机构,提取句子中的关键信息比较方便。

    import nltk
    from nltk.corpus import brown
    
    tagged_sents = brown.tagged_sents()
    #简单的正则比表达式对句子进行分块,ALL是任意取的名字,{}表示匹配其中的内容
    #<>匹配的是词性如<NN>匹配名词 <.*>+匹配所有词性 至少一次
    #}{中间的内容是为分块加间隙,将词性为DT的单独隔离
    grammar = '''
        ALL:{<.*>+}
        }<DT>+{
    '''''
    #进行分块的都应该是下面这样的句子,(单词,词性)组合
    sentence = [("the", "DT"), ("little", "JJ"), ("yellow", "JJ"), ("dog", "NN"), ("barked", "VBD"), ("at", "IN"), ("the", "DT"), ("cat", "NN")]
    #解析分块正则表达式
    cp = nltk.RegexpParser(grammar)
    #分块句子
    data = cp.parse(sentence)
    #输出分块结果的时候有的单词会被单独出来,不是树结构,也没有label方法
    for subtree in data:
        if isinstance(subtree,type(data)):
            print(subtree.label())
            print(subtree)
    
    print("句子分块的树表示:\n",data)
    print("句子分块的IOB表示")
    print(nltk.chunk.tree2conlltags(data))
    
    
    print('-----------------------------------------------')
    #简单的评估和基准
    from nltk.corpus import conll2000
    #空正则表达式,所有单词都标注为 O(块之外)
    cp = nltk.RegexpParser("")
    test_sents = conll2000.chunked_sents("test.txt",chunk_types=['NP'])
    #输出数据的树表示
    print(test_sents)
    tree2conlltag = [nltk.chunk.tree2conlltags(tree) for tree in test_sents ]
    #输出第11条数据的IOB表示
    print(tree2conlltag[10])
    print(cp.evaluate(test_sents))
    
    #尝试一个初级的正则表达式分类器
    gramma = '''
        NP:{<[CDJNP].*>+}
        O:{<^[CDJNP].*>+}
    '''
    cp2 = nltk.RegexpParser(gramma)
    print(cp2.evaluate(test_sents))
    
    print("去除所有块中非NP的块")
    test_sents = [tree for tree in test_sents if isinstance(tree,type(test_sents)) and
                  tree.label() == 'NP'
                  ]
    #去除掉其中除NP之外的块,再次测试,结果应该是100%
    print(cp2.evaluate(test_sents))
    
    #使用unigram标注器来进行分块
    #这个的大体意思应该是将每个单词分配一个IOB标记以此来对句子进行分块
    #所以训练数据也是使用的单词词性 + 块标记
    train_sents = conll2000.chunked_sents("train.txt",chunk_types=['NP'])
    test_sents = conll2000.chunked_sents("test.txt",chunk_types=['NP'])
    #将分块句子转换为训练数据(词性 + IOB标记)
    #下面的这个拼接就很灵性,先按照树拼接为列表,然后将多个列表拼接成列表
    train_set = [[(p,t) for (w,p,t) in nltk.chunk.tree2conlltags(tree)]
                 for tree in train_sents
                 ]
    print("一条查询标注器的训练数据:",train_set[2])
    chunker = nltk.UnigramTagger(train_set)
    test_set = [[(p,t)for (w,p,t) in nltk.chunk.tree2conlltags(tree)]
                for tree in test_sents
                ]
    print(chunker.evaluate(test_set))
    

    总结

    • 正则表达式匹配的是词性,
    • 分块的对象(parse()的参数)是单词词性元组
    • 查询标注器的训练数据(单词,词性)组成句子链表,句子链表再组成训练数据。
    • 评估的时候数据也应该和训练数据一样。
    • chunk模块下有树/IOB标记 之间的相互转换函数

    相关文章

      网友评论

          本文标题:复习句子分块

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