1.4 词性标注

5.中,我们建立了一个正则表达式标注器,通过查找词内部的组成,为词选择词性标记。然而,这个正则表达式标注器是手工制作的。作为替代,我们可以训练一个分类器来算出哪个后缀最有信息量。首先,让我们找出最常见的后缀:

  1. >>> from nltk.corpus import brown
  2. >>> suffix_fdist = nltk.FreqDist()
  3. >>> for word in brown.words():
  4. ... word = word.lower()
  5. ... suffix_fdist[word[-1:]] += 1
  6. ... suffix_fdist[word[-2:]] += 1
  7. ... suffix_fdist[word[-3:]] += 1
  1. >>> common_suffixes = [suffix for (suffix, count) in suffix_fdist.most_common(100)]
  2. >>> print(common_suffixes)
  3. ['e', ',', '.', 's', 'd', 't', 'he', 'n', 'a', 'of', 'the',
  4. 'y', 'r', 'to', 'in', 'f', 'o', 'ed', 'nd', 'is', 'on', 'l',
  5. 'g', 'and', 'ng', 'er', 'as', 'ing', 'h', 'at', 'es', 'or',
  6. 're', 'it', '``', 'an', "''", 'm', ';', 'i', 'ly', 'ion', ...]

接下来,我们将定义一个特征提取器函数,检查给定的单词的这些后缀:

  1. >>> def pos_features(word):
  2. ... features = {}
  3. ... for suffix in common_suffixes:
  4. ... features['endswith({})'.format(suffix)] = word.lower().endswith(suffix)
  5. ... return features

特征提取函数的行为就像有色眼镜一样,强调我们的数据中的某些属性(颜色),并使其无法看到其他属性。分类器在决定如何标记输入时,将完全依赖它们强调的属性。在这种情况下,分类器将只基于一个给定的词拥有(如果有)哪个常见后缀的信息来做决定。

现在,我们已经定义了我们的特征提取器,可以用它来训练一个新的“决策树”的分类器(将在4讨论):

  1. >>> tagged_words = brown.tagged_words(categories='news')
  2. >>> featuresets = [(pos_features(n), g) for (n,g) in tagged_words]
  1. >>> size = int(len(featuresets) * 0.1)
  2. >>> train_set, test_set = featuresets[size:], featuresets[:size]
  1. >>> classifier = nltk.DecisionTreeClassifier.train(train_set)
  2. >>> nltk.classify.accuracy(classifier, test_set)
  3. 0.62705121829935351
  1. >>> classifier.classify(pos_features('cats'))
  2. 'NNS'

决策树模型的一个很好的性质是它们往往很容易解释——我们甚至可以指示 NLTK 将它们以伪代码形式输出:

  1. >>> print(classifier.pseudocode(depth=4))
  2. if endswith(,) == True: return ','
  3. if endswith(,) == False:
  4. if endswith(the) == True: return 'AT'
  5. if endswith(the) == False:
  6. if endswith(s) == True:
  7. if endswith(is) == True: return 'BEZ'
  8. if endswith(is) == False: return 'VBZ'
  9. if endswith(s) == False:
  10. if endswith(.) == True: return '.'
  11. if endswith(.) == False: return 'NN'

在这里,我们可以看到分类器一开始检查一个词是否以逗号结尾——如果是,它会得到一个特别的标记","。接下来,分类器检查词是否以"the"尾,这种情况它几乎肯定是一个限定词。这个“后缀”被决策树早早使用是因为词”the”太常见。分类器继续检查词是否以”s”结尾。如果是,那么它极有可能得到动词标记VBZ(除非它是这个词”is”,它有特殊标记BEZ),如果不是,那么它往往是名词(除非它是标点符号“.”)。实际的分类器包含这里显示的 if-then 语句下面进一步的嵌套,参数depth=4 只显示决策树的顶端部分。