- 1.4 词性标注
1.4 词性标注
第5.中,我们建立了一个正则表达式标注器,通过查找词内部的组成,为词选择词性标记。然而,这个正则表达式标注器是手工制作的。作为替代,我们可以训练一个分类器来算出哪个后缀最有信息量。首先,让我们找出最常见的后缀:
>>> from nltk.corpus import brown
>>> suffix_fdist = nltk.FreqDist()
>>> for word in brown.words():
... word = word.lower()
... suffix_fdist[word[-1:]] += 1
... suffix_fdist[word[-2:]] += 1
... suffix_fdist[word[-3:]] += 1
>>> common_suffixes = [suffix for (suffix, count) in suffix_fdist.most_common(100)]
>>> print(common_suffixes)
['e', ',', '.', 's', 'd', 't', 'he', 'n', 'a', 'of', 'the',
'y', 'r', 'to', 'in', 'f', 'o', 'ed', 'nd', 'is', 'on', 'l',
'g', 'and', 'ng', 'er', 'as', 'ing', 'h', 'at', 'es', 'or',
're', 'it', '``', 'an', "''", 'm', ';', 'i', 'ly', 'ion', ...]
接下来,我们将定义一个特征提取器函数,检查给定的单词的这些后缀:
>>> def pos_features(word):
... features = {}
... for suffix in common_suffixes:
... features['endswith({})'.format(suffix)] = word.lower().endswith(suffix)
... return features
特征提取函数的行为就像有色眼镜一样,强调我们的数据中的某些属性(颜色),并使其无法看到其他属性。分类器在决定如何标记输入时,将完全依赖它们强调的属性。在这种情况下,分类器将只基于一个给定的词拥有(如果有)哪个常见后缀的信息来做决定。
现在,我们已经定义了我们的特征提取器,可以用它来训练一个新的“决策树”的分类器(将在4讨论):
>>> tagged_words = brown.tagged_words(categories='news')
>>> featuresets = [(pos_features(n), g) for (n,g) in tagged_words]
>>> size = int(len(featuresets) * 0.1)
>>> train_set, test_set = featuresets[size:], featuresets[:size]
>>> classifier = nltk.DecisionTreeClassifier.train(train_set)
>>> nltk.classify.accuracy(classifier, test_set)
0.62705121829935351
>>> classifier.classify(pos_features('cats'))
'NNS'
决策树模型的一个很好的性质是它们往往很容易解释——我们甚至可以指示 NLTK 将它们以伪代码形式输出:
>>> print(classifier.pseudocode(depth=4))
if endswith(,) == True: return ','
if endswith(,) == False:
if endswith(the) == True: return 'AT'
if endswith(the) == False:
if endswith(s) == True:
if endswith(is) == True: return 'BEZ'
if endswith(is) == False: return 'VBZ'
if endswith(s) == False:
if endswith(.) == True: return '.'
if endswith(.) == False: return 'NN'
在这里,我们可以看到分类器一开始检查一个词是否以逗号结尾——如果是,它会得到一个特别的标记","
。接下来,分类器检查词是否以"the"
尾,这种情况它几乎肯定是一个限定词。这个“后缀”被决策树早早使用是因为词”the”太常见。分类器继续检查词是否以”s”结尾。如果是,那么它极有可能得到动词标记VBZ
(除非它是这个词”is”,它有特殊标记BEZ
),如果不是,那么它往往是名词(除非它是标点符号“.”)。实际的分类器包含这里显示的 if-then 语句下面进一步的嵌套,参数depth=4
只显示决策树的顶端部分。