1.3 文档分类

1中,我们看到了语料库的几个例子,那里文档已经按类别标记。使用这些语料库,我们可以建立分类器,自动给新文档添加适当的类别标签。首先,我们构造一个标记了相应类别的文档清单。对于这个例子,我们选择电影评论语料库,将每个评论归类为正面或负面。

  1. >>> from nltk.corpus import movie_reviews
  2. >>> documents = [(list(movie_reviews.words(fileid)), category)
  3. ... for category in movie_reviews.categories()
  4. ... for fileid in movie_reviews.fileids(category)]
  5. >>> random.shuffle(documents)

接下来,我们为文档定义一个特征提取器,这样分类器就会知道哪些方面的数据应注意(1.4)。对于文档主题识别,我们可以为每个词定义一个特性表示该文档是否包含这个词。为了限制分类器需要处理的特征的数目,我们一开始构建一个整个语料库中前 2000 个最频繁词的列表[1]。然后,定义一个特征提取器[2],简单地检查这些词是否在一个给定的文档中。

  1. all_words = nltk.FreqDist(w.lower() for w in movie_reviews.words())
  2. word_features = list(all_words)[:2000] ![[1]](/projects/nlp-py-2e-zh/Images/78bc6ca8410394dcf6910484bc97e2b6.jpg)
  3. def document_features(document): ![[2]](/projects/nlp-py-2e-zh/Images/854532b0c5c8869f9012833955e75b20.jpg)
  4. document_words = set(document) ![[3]](/projects/nlp-py-2e-zh/Images/f202bb6a4c773430e3d1340de573d0e5.jpg)
  5. features = {}
  6. for word in word_features:
  7. features['contains({})'.format(word)] = (word in document_words)
  8. return features

注意

[3]中我们计算文档的所有词的集合,而不仅仅检查是否word in document,因为检查一个词是否在一个集合中出现比检查它是否在一个列表中出现要快的多(4.7)。

现在,我们已经定义了我们的特征提取器,可以用它来训练一个分类器,为新的电影评论加标签(1.5)。为了检查产生的分类器可靠性如何,我们在测试集上计算其准确性[1]。再一次的,我们可以使用show_most_informative_features()来找出哪些特征是分类器发现最有信息量的[2]

  1. featuresets = [(document_features(d), c) for (d,c) in documents]
  2. train_set, test_set = featuresets[100:], featuresets[:100]
  3. classifier = nltk.NaiveBayesClassifier.train(train_set)

显然在这个语料库中,提到 Seagal 的评论中负面的是正面的大约 8 倍,而提到 Damon 的评论中正面的是负面的大约 6 倍。