Mahout架构初探及KMeans算法分布式实现的研究

转载自:http://hi.baidu.com/%B3%CF%D5%F7id/blog/item/6863de395f2f963eb8998fc3.html

1.         Mahout简介

Apache项目下的开源的基于hadoop分布式系统的数据挖掘工具,mahout源代码由maven项目管理工具管理。

2.         $MAHOUT_HOME/bin/mahout

Mahout启动的shell脚本

几个重要环境变量

JAVA_HOME    mahout运行需指定jdk的目录

MAHOUT_JAVA_HOME指定此变量可覆盖JAVA_HOME

HADOOP_HOME  如果配置,则在hadoop分布式平台上运行,否则单机运行

HADOOP_CONF_DIR指定hadoop的配置文件目录

MAHOUT_LOCAL    如果此变量值不为空,则单机运行mahout

MAHOUT_CONF_DIR  mahout配置文件的路径,默认值是$MAHOUT_HOME/src/conf

MAHOUT_HEAPSIZE   mahout运行时可用的最大heap大小

 

Mahout命令行:

$MAHOUT_HOME/bin/mahout $CLASS  [Generic Options] [Job-Specific Options]

Mahout脚本通过调用hadoop在分布式平台运行或调用jre在本地运行,然后调用mahout工程的总入口org.apache.mahout.driver.MahoutDriver类。

3.         Mahout总入口org.apache.mahout.driver.MahoutDriver

Mahout启动的总入口做了一下的任务:

1)         首先装载$MAHOUT_CONF_DIR目录下的一个名为driver.classes.props的资源文件(如果找不到,则寻找driver.classes.default.props文件)

driver.classes.props文件内罗列了mahout内集成的各种工具的资源(Properties)列表,例如列举聚类的KMeans的那一行:

org.apache.mahout.clustering.kmeans.KMeansDriver = kmeans : K-means clustering

等号前面(Properties.Key的是类名,等号后Properties.Value、分号前的是mahout命令行内的简写,分号后面是描述。

2)         装载driver.classes.props中的类。如果mahout命令行第一个参数不是简写,则装载以第一个参数为名的类。

3)         装载“mahout命令行中第一个参数名.props”的配置文件,该配置文件中可以指定输入输出目录等等参数。

4)         调用mahout命令行的第一个参数的类运行,并将命令行参数结合配置文件中的参数以字符的形式传递过去。

4.         Kmeans算法的分布式实现

KMeans为例,org.apache.mahout.driver.MahoutDriver会调用org.apache.mahout.clustering.kmeans.KMeansDriver类。

KMeansDriver类继承于AbstractJobAbstractJob继承于org.apache.hadoop.conf.Configured并同时实现了org.apache.hadoop.util.Tool接口,

KMeansDriver类提供了KMeans聚类的单机版本和分布式版本。

Main方法里调用了run(String[] args)方法,run(String[] args)方法内对命令行参数做了解析。

根据提供的参数调用单机或分布式的KMeans聚类方法,我们主要研究KMeans聚类方法的分布式算法。

KMeansDriver类的runIteration方法中,mahout提交了一个MapReduce任务。

这段代码是:

job.setMapOutputKeyClass(Text.class);

    job.setMapOutputValueClass(ClusterObservations.class);

    job.setOutputKeyClass(Text.class);

    job.setOutputValueClass(Cluster.class);

 

    job.setInputFormatClass(SequenceFileInputFormat.class);

    job.setOutputFormatClass(SequenceFileOutputFormat.class);

    job.setMapperClass(KMeansMapper.class);

    job.setCombinerClass(KMeansCombiner.class);

    job.setReducerClass(KMeansReducer.class);

 

    FileInputFormat.addInputPath(job, input);

    FileOutputFormat.setOutputPath(job, clustersOut);

 

    job.setJarByClass(KMeansDriver.class);

 

因此对KMeans算法的分布式实现的研究,我们应主要关注ClusterClusterObservationsKMeansMapperKMeansCombinerKMeansReducer这几个类。

5.         Cluster告诉我们KMeanscluster是如何表示的。

Cluster继承于org.apache.mahout.clustering.DistanceMeasureCluster类,后者继承于org.apache.mahout.clustering.AbstractCluster抽象类,再后者实现了org.apache.mahout.clustering. Cluster接口

总之,cluster内部有一个变量idint类型)用于唯一的标识该聚类,numPointslong类型)表示该聚类内部有多少个点,centerVector类型,此Vector是数学中的N维向量,也可理解为N维点,非java.util.Vector)表示聚类中心点,radiusVector类型)表示半径,还有聚合标志位convergedboolean类型)

6.         ClusterObservations

Kmeans分布式算法有关,ClusterObservationss0(double,点数目增量),s1(Vector,用于计算中心点增量),s2(Vector,用于计算半径增量)

7.         KMeansMapper

Map过程,输入keyvalue =WritableComparable<?> key, VectorWritablepoint

计算每个point表示的点与每个cluster中心center距离,并将改点加入距离最近的cluster中,并计算该cluster的三个增量。

context.write(new Text(nearestCluster.getIdentifier()), new ClusterObservations(1, point, point.times(point)));

输出的keyvalue = Text, ClusterObservationskeyclusteridvaluecluster的三个增量(点数目,中心点增量,半径增量)

8.         KMeansCombiner

Map阶段运行结束后,为了减少到Reduce阶段的网络数据输出,mahout对于同一个节点上Map阶段的输出进行合并,把多个相同的keyvalue合并成一个<Key, Value>

由于KMeans算法是线性的,因此在此阶段可将Map阶段输出相同key的多个<cluster_id,point.增量>合并成一个<cluster_id, point.总增量>

9.         KMeansReducer

Kmeans算法中,有几个cluster聚集就有几个Reducer任务。Reducer任务中,对每个clusterMap阶段所有的增量计算,重新计算每个cluster的点数,中心点和半径,以及聚合度。

posted on 2013-11-21 13:40  AI001  阅读(499)  评论(0编辑  收藏  举报

导航