当前位置:   article > 正文

Python自然语言处理------分类和标注词汇_python对单词划归词性

python对单词划归词性

 

一篇读书笔记。

1. 使用词性标注器

将词汇按它们的词性(parts-of-speech,POS)分类以及相应的标注它们的过程被称为词性标注(part-of-speech tagging, POS tagging)或干脆简称标注。词性也称为词类或词汇范畴。用于特定任务的标记的集合被称为一个标记集。

一个词性标注器处理一个词序列,为每个词附加一个词性标记。

  1. import nltk
  2. text = nltk.word_tokenize("And now for something completely different") #分词
  3. nltk.pos_tag(text) #词性标注器

输出为:

  1. [('And', 'CC'),
  2. ('now', 'RB'),
  3. ('for', 'IN'),
  4. ('something', 'NN'),
  5. ('completely', 'RB'),
  6. ('different', 'JJ')]

其中'CC'表示并列连词,'RB'表示副词,'IN'表示介词,'NN'表示名词,'JJ'表示形容词

similar()函数为一个词w找出所有上下文w1ww2,然后找出所有出现在相同上下文中的词w’即w1 w’w2

2. 标注预料库

表示已标注的标识符

按照NLTK 的约定,一个已标注的标识符使用一个由标识符和标记组成的元组来表示。我们可以使用函数str2tuple()从表示一个已标注的标识符的标准字符串创建一个这样的特殊元组:

  1. tagged_token = nltk.tag.str2tuple('fly/NN') #已标注的标识符字符串转化为元组类型
  2. tagged_token

此外,还可以可以直接从一个字符串构造一个已标注的标识符的链表。第一步是对字符串分词以便能访问单独的词/标记字符串,然后将每一个转换成一个元组:

  1. sent = '''
  2. ...The/AT grand/JJ jury/NN commented/VBD on/IN a/AT number/NN of/IN
  3. ... other/AP topics/NNS ,/, AMONG/IN them/PPO the/AT Atlanta/NP and/CC
  4. ... Fulton/NP-tl County/NN-tl purchasing/VBG departments/NNS which/WDT it/PP
  5. ... said/VBD ``/`` ARE/BER well/QL operated/VBN and/CC follow/VB generally/R
  6. ... accepted/VBN practices/NNS which/WDT inure/VB to/IN the/AT best/JJT
  7. ... interest/NN of/IN both/ABX governments/NNS ''/'' ./.
  8. ...'''
  9. [nltk.tag.str2tuple(t) for t in sent.split()]

读取已标注的预料库

NLTK 中包括的若干语料库已标注了词性。以布朗预料库为例:

nltk.corpus.brown.tagged_words()[:10]

如果语料库也被分割成句子,将有一个tagged_sents()方法将已标注的词划分成句子,而不是将它们表示成一个大链表

简化的词性标记集

 

2. 自动标注

我们将看到一个词的标记依赖于这个词和它在句子中的上下文。出于这个原因,我们将处理(已标注)句子层次
而不是词汇层次的数据。首先以加载要使用的数据开始

 

  1. from nltk.corpus import brown
  2. brown_tagged_sents = brown.tagged_sents(categories='news')
  3. brown_sents = brown.sents(categories='news')

默认标注器

最简单的标注器是为每个标识符分配同样的标记。显然这个方法并不理想。

正则表达式标注器

正则表达式标注器基于匹配模式分配标记给标识符。例如:我们可能会猜测任一以ed结尾的词都是动词过去分词,任一以's 结尾的词都是名词所有格。例如:

  1. patterns = [
  2. ... (r'.*ing$', 'VBG'), # gerunds
  3. ... (r'.*ed$', 'VBD'), # simple past
  4. ... (r'.*es$', 'VBZ'), # 3rd singular present
  5. ... (r'.*ould$', 'MD'), # modals
  6. ... (r'.*\'s$', 'NN$'), # possessive nouns
  7. ... (r'.*s$', 'NNS'), # plural nouns
  8. ... (r'^-?[0-9]+(.[0-9]+)?$', 'CD'), # cardinal numbers
  9. ... (r'.*', 'NN') # nouns (default)
  10. ... ]
  11. regexp_tagger = nltk.RegexpTagger(patterns)
  12. regexp_tagger.tag(brown_sents[3])

查询标注器

让我们找出100 个最频繁的词,存储它们最有可能的标记。然后我们可以使用这个信息作为“查找标注器”的模型:

  1. fd = nltk.FreqDist(brown.words(categories='news'))
  2. cfd = nltk.ConditionalFreqDist(brown.tagged_words(categories='news'))
  3. most_freq_words = fd.keys()[:100]
  4. likely_tags = dict((word, cfd[word].max()) for word in most_freq_words)
  5. baseline_tagger = nltk.UnigramTagger(model=likely_tags)
  6. baseline_tagger.evaluate(brown_tagged_sents)

但是该模型在未标注的输入文本上,很多不在这100个最频繁的词中的词会被分配为“None”标注,在这些情况下,考虑到在所有情况中名词“NN”是最多的,所以直接默认分配为NN。只需对上述baseline_tagger添加一个backoff参数指向默认标注器即可。

  1. baseline_tagger = nltk.UnigramTagger(model=likely_tags,
  2. ... backoff=nltk.DefaultTagger('NN'))

3.N-gram标注

一元标注(Unigram Tagging)

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

一般的N-gram标注

一个n-gram标注器是一个 unigram 标注器的一般化,它的上下文是当前词和它前面n-1 个标识符的词性标记。

当n=1时即为一元标注器(unigram tagger),n=2时称为二元标注器(bigram taggers),n=3时称为三元标注器(trigram taggers)。

NgramTagger 类使用一个已标注的训练语料库来确定对每个上下文哪个词性标记最有可能。

组合标注器

解决精度和覆盖范围之间的权衡的一个办法是尽可能的使用更精确的算法,但却在很多时候落后于具有更广覆盖范围的算法。例如:我们可以按如下方式组合bigram 标注器、unigram 标注器和一个默认标注器:

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

  1. t0 = nltk.DefaultTagger('NN')
  2. t1 = nltk.UnigramTagger(train_sents, backoff=t0)
  3. t2 = nltk.BigramTagger(train_sents, backoff=t1)
  4. t2.evaluate(test_sents)

跨句子边界标注

当使用Ngram标注器,如果遇到句子的第一个词时,trigram标注器将使用前面两个标识符的词性标记,这通常会是前面句子的最后一个词和句子结尾的标点符号。然而,在前一句结尾的词的类别与下一句的开头通常没有关系。

为了应对这种情况,我们可以使用已标注句子的链表来训练、运行和评估标注器。

  1. brown_tagged_sents = brown.tagged_sents(categories='news')
  2. brown_sents = brown.sents(categories='news')
  3. size = int(len(brown_tagged_sents) * 0.9)
  4. train_sents = brown_tagged_sents[:size]
  5. test_sents = brown_tagged_sents[size:]
  6. t0 = nltk.DefaultTagger('NN')
  7. t1 = nltk.UnigramTagger(train_sents, backoff=t0)
  8. t2 = nltk.BigramTagger(train_sents, backoff=t1)
  9. t2.evaluate(test_sents)

4. 如何确定一个词的分类

形态学线索

一个词的内部结构可能为这个词分类提供有用的线索。举例来说:-ness 是一个后缀,与形容词结合产生一个名词,如happy→happiness,ill→illness。因此如果我们遇到的一个以-ness 结尾的词,很可能是一个名词。同样的,-ment 是与一些动词结合产生一个名词的后缀,如govern→government和 establish→establishment。

句法线索

另一个信息来源是一个词可能出现的典型的上下文语境。。例如:假设我们已经确定了名词类。那么我们可以说,英语形容词的句法标准是它可以立即出现在一个名词前,或紧跟在词be 或very 后。

语义线索

一个词的意思对其词汇范畴是一个有用的线索。。例如:名词的众所周知的一个定义是根据语义的:“一个人、地方或事物的名称。”

 

以上~

2018.06.15

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/696450
推荐阅读
相关标签
  

闽ICP备14008679号