13.5.5 算法应用实例

下面我们将对如何使用Mahout进行聚类和分类进行具体介绍,其中聚类算法以K-Means为例,分类算法以贝叶斯(Bayes)为例。

1.K-Means聚类

在Mahout中运行K-Means聚类算法非常简单。对于不同的数据主要有以下三个步骤。

使用seqdirectory命令将待处理的文件转化成序列文件。

使用seq2sparse命令将序列文件转化成向量文件。

使用kmeans命令对数据运行K-Means聚类算法。

将文本文件转化成向量需要两个重要的工具。一个是SequenceFilesFromDirectory类,它能将一个目录结构下的文本文件转化成序列文件,这种序列文件为一种中间文本表示形式。另一个是SparseVectorsFromSequenceFiles类,它使用词频(TF)或TF-IDF(TF-IDF weighting with n-gram generation)将序列文件转化成向量文件。序列文件以文件编号为键、文件内容为值。下面讨论如何将文本转换成向量。

使用路透社14578新闻集作为示例数据。这组数据被广泛应用于机器学习的研究中,它起初是由卡内基集团有限公司和路透社共同搜集整理的,目的是发展文本分类系统。路透社14578新闻集分布于22个文档中,除最后的reut2-0.14.sgm包含578份文件外,其余的每个文件包含1 000份文件。

路透社14578新闻集中的所有文件都为标准通用标记语言SGML(Standard Generalized Markup Language)格式,这种格式的文件与XML文件格式相似。可以为SGML文件创建一个分析器(parser),并将文件编号(document ID)和文件内容(document text)写到序列文件(SequenceFiles)中去。然后用前文提到的向量化工具将序列文件转化成向量。但是,更快捷的方式是使用Lucene Benchmark JAR文件提供的路透社分析器(the Reuters Parser)。Lucene Benchmark JAR是捆绑在Mahout上的,剩下的工作只是到Mahout目录下的examples文件夹运行org.apache.lucene.benchmark.utils.ExtractReuters类。在这之前,需要从http://www.daviddlewis.com/resources/testcollections/reuters14578/reuters14578.tar.gz下载路透社新闻集,并将它解压到Examples/Reuters文件夹下。相关命令如下所示:

mvn-e-q exec:java


-Dexec.mainClass="org.apache.lucene.benchmark.utils.ExtractReuters"

-Dexec.args="reuters/reuters-extracted/"


使用解压得到的文件夹运行SequenceFileFromDirectory类。使用下面的脚本命令(Launch script)可以实现该功能:


bin/mahout seqdirectory-c UTF-8

-i examples/reuters-extracted/

-o reuters-seqfiles


这条命令的作用是将路透社文章转化成序列文件格式,如表13-7所示。

13.5.5 算法应用实例 - 图1

现在剩下的工作是将序列文件转化成向量文件。运行SparseVectorsFromSequenceFiles类即可实现该功能。命令如下:


bin/mahout seq2sparse-i reuters-seqfiles/-o reuters-vectors-w


注意,在seq2sparse命令中,参数-w用来表示是否覆盖输出文件夹。Mahout用来处理海量的数据,任何一个算法的输出都会花费很多时间。有了参数-w, Mahout就可以防止新产生的数据对未完全输出的数据进行破坏。除此之外,seq2sparse命令还有以下参数,如表13-8所示。

13.5.5 算法应用实例 - 图2

Mahout的seq2sparse命令的功能是从序列文件中读取数据,使用上面提到的默认参数,按照基于向量化(vectorizer)的字典生成向量文件。大家可以使用以下命令检查生成文件夹:


ls reuters-vectors/


执行上述命令后,结果如下所示:


dictionary.file-0

tfidf/

tokenized-documents/

vectors/

wordcount/


输出文件夹包含一个目录文件和四个文件夹。目录文件保存着术语(term)和整数编号之间的映射。当读取算法的输出时,这个文件是非常有用的,因此,需要保留它。其他四个文件夹是向量化过程中生成的文件夹。向量化过程主要有以下几步:

第一步,标记文本文档。具体过程是使用Lucene StandardAnalyzer将文本文档分成个体化的单词,将结果存储在tokenized-documents文件夹下。

第二步,对tonkenized文档进行迭代生成一个重要单词的集合。这个过程可能会使用单词统计、n-gram生成,这里使用的是unigrams生成。

第三步,使用TF将标记的文档转化成向量,从而创建TF向量。在默认情况下,向量化是使用TF-IDF,因此需要分两步来进行,一是文档频率(document-frequency)的统计工作;二是创建TF-IDF向量。TF-IDF向量在tfidf/vectors文件夹下。对于大多数的应用来说,需要的仅仅是目录文件和tfidf/vectors文件夹。

使用kmeans命令可以对数据运行K-Means聚类算法。命令如下:


bin/mahout kmeans

-i./examples/bin/work/reuters-out-seqdir-sparse/tfidf/vectors/

-c./examples/bin/work/clusters

-o./examples/bin/work/reuters-kmeans

-k 20-w


表13-9列出了K-Means命令参数的具体意义。

13.5.5 算法应用实例 - 图3

2.贝叶斯分类

在已经安装好Hadoop和Mahout的前提下,运行Bayes分类算法也比较简单。这里简要介绍Mahout的示例程序20NewsGroup的分类。实际上,除了20NewsGroup示例之外,还有Wikimapia数据,但由于其数据量达到了将近7GB,对大多数初学者而言并不合适。这里我们选择数据量较小且非常经典的20NewsGroup示例的分类。

什么是20NewsGroup?20新闻组包含20 000个新闻组文档,这些文档可以被分类成20个新闻组。20新闻组最初来源于Ken Lang的论文《Newsweeder:learning to filter netnews》。从那以后,20新闻组数据集合在机器学习领域越来越多地被用作实验数据。在文本聚类和分类方面的研究中使用尤为突出。20新闻组按照20个不同的类型进行组织,不同的类对应不同的主题。本书用到的20新闻组数据可以从http://people.csail.mit.edu/jrennie/20Newsgroups/下载。在下载页面中,一共有三种版本的20新闻组数据,分别是20news-19997.tar.gz、20news-bydate.tar.gz和20news-18828.tar.gz。

20news-19997. tar.gz是最原始的版本数据;20news-bydate.tar.gz是按照日期进行排序的,其中的60%用来进行训练Bayes分类算法,40%用来测试Bayes分类算法,不包含重复新闻和标识新闻组的标题;20news-18828.tar.gz不包含重复的新闻,但是包含带有新闻来源和新闻主题的标题。这三种20新闻组数据都是以tar.gz形式存在的。读者使用tar命令对它们进行解压即可得到相应的数据。具体选择哪种数据对结果影响不大,这里我们选择20news-bydate.tar.gz。

介绍完20NewsGroup后,下面开始介绍如何运行Mahout自带的Naïve Bayes Classifier算法示例。

数据下载完成后并不可以直接使用,可以看到,数据在目录中均是以文件夹进行区分,即数据已经被分好类别。因此我们首先需要获取所需格式的数据。该操作可以通过如下两个命令完成:

获取训练集:


mahout org.apache.mahout.classifier.bayes.PrepareTwentyNewsgroups\

-p$DATA_HOME/20news-bydate-train\

-o$DATA_HOME/bayes-train-input\

-a org.apache.mahout.vectorizer.DefaultAnalyzer\

-c UTF-8


获取测试集:


mahout org.apache.mahout.classifier.bayes.PrepareTwentyNewsgroups\

-p$DATA_HOME/20news-bydate-test\

-o$DATA_HOME/bayes-test-input\

-a org.apache.mahout.vectorizer.DefaultAnalyzer\

-c UTF-8


在数据获取完成之后,通过“hadoop fs-put”命令将数据上传到HDFS,然后使用下列命令训练Bayes分类器:


mahout trainclassifier\

-i/user/hadoop/20news/bayes-train-input\

-o/user/hadoop/20news/newsmodel\

-type cbayes\

-ng 2\

-source hdfs


该命令将会在Hadoop上运行四个MapReduce作业。在命令执行的过程中,可以打开浏览器,在http://localhost:50030/jobtracker.jsp上监视这些作业的运行状态。

运行下面的命令测试Bayes分类器:


mahout testclassifier\

-m/user/hadoop/20news/newsmodel\

-d/user/hadoop/20news/bayes-test-input\

-type cbayes\

-ng 2\

-source hdfs\

-method mapreduce


关于trainclassifier和testclassifier命令参数,这里不再详细介绍,大家可以通过“mahout[command]-h”命令来查看。

这就是Mahout自带的Bayes分类算法的示例程序。如果大家想要深入了解Mahout的分类算法,可以自行阅读Mahout Core API 0.7来了解已经实现的功能。