首页 > Python基础教程 >
-
探索 Python、机器学习和 NLTK 库(6)
接下来,我收集了训练集的 RSS 提要项目和它们各自的特性,并将它们传递给算法。清单 9 中的代码演示了这个任务。请注意,分类器被训练成为只有一行代码。
清单 9. 训练 nltk.NaiveBayesClassifier
1
2
3
4
5
6
7
8
|
def classify_reuters( self ): ... training_set = [] for item in rss_items: features = item.features(top_words) tup = (features, item.category) # tup is a 2-element tuple featuresets.append(tup) classifier = nltk.NaiveBayesClassifier.train(training_set) |
NaiveBayesClassifier 在运行中的 Python 程序的内存中,它现在是经过训练的。现在,我只需遍历需要进行分类的 RSS 提要项目集,并要求分类器猜测每个项目的类别。这很简单。
1
2
3
|
for item in rss_items_to_classify: features = item.features(top_words) category = classifier.classify(feat) |
变得不那么朴实
如前所述,算法假设每个特性之间是没有关系的。因此,像 "machine learning" 和 "learning machine",或者 "New York Jet" 和 "jet to New York" 这样的短语是等效的(to 是一个停用词)。在自然的语言上下文中,这些单词之间有明显的关系。所以,我怎么会让算法变得 “不那么天真”,并识别这些单词的关系?
其中一个技巧是在特性集内包括常见的双字词(两个单词为一组)和三字词(三个单词为一组)。NLTK 以 nltk.bigrams(...) 和 nltk.trigrams(...) 的形式对此提供了支持,现在我们对此应该不再感到惊讶了。正如可以从训练数据组收集最常用的 n 个单词那样,也可以识别最常用的双字词和三字词,并将它们用作特性。
您的结果会有所不同
对数据和算法进行完善是一门艺术。您是否应该进一步规范化单词集,也许应该包括词根?或者包括超过 1000 个最常用单词?少一点是否合适?或者是否应该使用更大的训练数据集?是否应该添加更多信用词或 “停用词根”?这些都是您要问自己的正确问题。使用它们进行实验,通过试错法,您可以会为您的数据实现最佳算法。我发现,85% 是一个很好的分类成功率。
利用 k-Nearest Neighbors 算法提出建议
客户希望显示在选定类别或相似类别中的 RSS 提要项目。现在,这些项目已经用 Naive Bayes 算法进行分类,这一要求的第一部分已得到了满足。较难的部分是实现 “或相似类别” 的要求。这是机器学习建议器系统开始发挥作用的地方。建议器系统 根据其他项目的相似性来建议一个项目。Amazon.com 的产品建议和 Facebook 的朋友建议就是此功能的很好的示例。
k-Nearest Neighbors (kNN) 是最常用的建议算法。思路是向它提供一组标签(即类别),并且每个标签都对应一个数据集。然后,该算法对各数据集进行了比较,以识别相似的项目。数据集由多个数值数组构成,数值的范围往往被规范化为从 0 到 1。然后,它可以从数据集识别相似的标签。与只产生一个结果的 Naive Bayes 不同,kNN 可以产生一个有排名的列表,其中包含若干(即,k 的值)个建议。
我发现,建议器算法比分类算法更容易理解和实现,但对于本文来说,其代码过于冗长,并且有复杂的数学,无法在这里详述。请参阅由 Manning 出版的一本很好的新书 Machine Learning in Action,获取 kNN 编码示例(请参阅 参考资料 中的链接)。在 RSS 提要项目实现的过程中,标签值是项目类别,而数据集是最常用的 1000 个单词的值数组。同样,在构建这个数组时,一部分属于科学范畴,一部分属于数学范畴,还有一部分属于艺术范畴。在数组中,每个单词的值都可以是简单的 0 或 1 的布尔值、文章中单词出现次数的百分比、该百分比的指数值,或一些其他值。
结束语
探索 Python、NLTK 和机器学习一直是一个有趣的、令人愉快的经验。Python 语言强大而又简洁,现在已成为我的开发工具包的核心部分。它非常适合于机器学习、自然语言和数学/科学应用程序。虽然本文中并没有提到,但我还发现 Python 对于图表和绘图非常有用。