zoukankan      html  css  js  c++  java
  • 【语言处理与Python】5.5Ngram标注

    一元标注(Unigram Tagging)

    一元标注基于简单的统计算法,对每个标识符分配这个独特的标识符最有可能的标记。

    >>>from nltk.corpusimport brown
    >>>brown_tagged_sents= brown.tagged_sents(categories='news')
    >>>brown_sents= brown.sents(categories='news')
    >>>unigram_tagger = nltk.UnigramTagger(brown_tagged_sents)
    >>>unigram_tagger.tag(brown_sents[2007])
    [('Various', 'JJ'), ('of', 'IN'), ('the', 'AT'), ('apartments', 'NNS'),
    ('are', 'BER'), ('of', 'IN'), ('the', 'AT'), ('terrace', 'NN'), ('type', 'NN'),
    (',', ','), ('being', 'BEG'), ('on', 'IN'), ('the', 'AT'), ('ground', 'NN'),
    ('floor', 'NN'), ('so', 'QL'), ('that', 'CS'), ('entrance', 'NN'), ('is', 'BEZ'),
    ('direct', 'JJ'), ('.', '.')]
    >>>unigram_tagger.evaluate(brown_tagged_sents)
    0.9349006503968017

    分离训练和测试数据

    为了能够更客观的分离训练和测试数据,一般我们的训练和测试数据不使用相同的。

    >>>size = int(len(brown_tagged_sents) *0.9)
    >>>size
    4160
    >>>train_sents = brown_tagged_sents[:size]
    >>>test_sents = brown_tagged_sents[size:]
    >>>unigram_tagger = nltk.UnigramTagger(train_sents)
    >>>unigram_tagger.evaluate(test_sents)
    0.81202033290142528

    一般的N-gram的标注

    在标注的时候,会考虑在这个词之前的n-1个词汇进行标注。

    #一个bigram tagger的例子
    >>>bigram_tagger = nltk.BigramTagger(train_sents)
    >>>bigram_tagger.tag(brown_sents[2007])
    [('Various', 'JJ'), ('of', 'IN'), ('the', 'AT'), ('apartments', 'NNS'),
    ('are', 'BER'), ('of', 'IN'), ('the', 'AT'), ('terrace', 'NN'),
    ('type', 'NN'), (',', ','), ('being', 'BEG'), ('on', 'IN'), ('the', 'AT'),
    ('ground', 'NN'), ('floor', 'NN'), ('so', 'CS'), ('that', 'CS'),
    ('entrance', 'NN'), ('is', 'BEZ'), ('direct', 'JJ'), ('.', '.')]
    >>>unseen_sent = brown_sents[4203]
    >>>bigram_tagger.tag(unseen_sent)
    [('The', 'AT'), ('population', 'NN'), ('of', 'IN'), ('the', 'AT'), ('Congo', 'NP'),
    ('is', 'BEZ'), ('13.5', None),('million', None),(',', None),('divided', None),
    ('into', None),('at', None),('least', None),('seven', None),('major', None),
    ('``', None),('culture', None),('clusters', None),("''", None),('and', None),
    ('innumerable', None),('tribes', None),('speaking', None),('400', None),
    ('separate', None),('dialects', None),('.', None)]
    #bigram标注器对于看到过的句子的词标注的很好,但是没有见过的,就会非常差。
    >>>bigram_tagger.evaluate(test_sents)
    0.10276088906608193

    组合标注器

    为了解决精度和覆盖范围之间的权衡的一个办法是,尽可能的使用更精确的算法。

    在下面举了一个组合标注器的例子,提高的评价得分。

    1. 尝试使用bigram标注器标注标识符。
    2. 如果bigram标注器无法找到一个标记,尝试unigram标注器。
    3. 如果unigram标注器也无法找到一个标记,使用默认标注器。

    >>>t0 =nltk.DefaultTagger('NN')
    >>>t1 =nltk.UnigramTagger(train_sents,backoff=t0)
    >>>t2 =nltk.BigramTagger(train_sents,backoff=t1)
    >>>t2.evaluate(test_sents)
    0.84491179108940495

    我们也可以指定一个标注器需要看到一个上下文的多少个实例才能保留它。

    nltk.BigramTagger(sents,cutoff=2,backoff=t1)

    标注生词

    在遇到生词时,不同的标注器标注的结果可能是不一样的。

    存储标注器

    将训练好的标注器保存起来,然后再重复使用。

    >>>from cPickle import dump
    >>>output= open('t2.pkl', 'wb')
    >>>dump(t2,output,-1)
    >>>output.close()
    
    >>>from cPickle import load
    >>>input = open('t2.pkl', 'rb')
    >>>tagger = load(input)
    >>>input.close()

    跨句子边界标注(句子层面的N-gram标注)

    brown_tagged_sents= brown.tagged_sents(categories='news')
    brown_sents= brown.sents(categories='news')
    size = int(len(brown_tagged_sents) *0.9)
    train_sents = brown_tagged_sents[:size]
    test_sents = brown_tagged_sents[size:]
    t0 = nltk.DefaultTagger('NN')
    t1 = nltk.UnigramTagger(train_sents,backoff=t0)
    t2 = nltk.BigramTagger(train_sents, backoff=t1)
    >>>t2.evaluate(test_sents)
    0.84491179108940495
  • 相关阅读:
    HNOI2018退役记
    codeforces 960G Bandit Blues
    codeforces 933D A Creative Cutout
    tyvj1953 Normal
    loj6119 「2017 山东二轮集训 Day7」国王
    codeforces 293E Close Vertices
    bzoj1808 [Ioi2007]training 训练路径
    bzoj2219 数论之神
    bzoj4361 isn
    loj2064[HAOI2016]找相同字符
  • 原文地址:https://www.cnblogs.com/createMoMo/p/3100086.html
Copyright © 2011-2022 走看看