您的位置:首页 > 运维架构 > 网站架构

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

2013-11-21 13:40 197 查看
转载自: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脚本

几个重要环境变量

J***A_HOME mahout运行需指定jdk的目录

MAHOUT_J***A_HOME指定此变量可覆盖J***A_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类继承于AbstractJob,AbstractJob继承于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算法的分布式实现的研究,我们应主要关注Cluster、ClusterObservations、KMeansMapper、KMeansCombiner、KMeansReducer这几个类。

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

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

总之,cluster内部有一个变量id(int类型)用于唯一的标识该聚类,numPoints(long类型)表示该聚类内部有多少个点,center(Vector类型,此Vector是数学中的N维向量,也可理解为N维点,非java.util.Vector)表示聚类中心点,radius(Vector类型)表示半径,还有聚合标志位converged(boolean类型)

6. ClusterObservations类

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

7. KMeansMapper

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

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

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

输出的key,value = Text, ClusterObservations,key是cluster的id,value是cluster的三个增量(点数目,中心点增量,半径增量)

8. KMeansCombiner

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

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

9. KMeansReducer

Kmeans算法中,有几个cluster聚集就有几个Reducer任务。Reducer任务中,对每个cluster将Map阶段所有的增量计算,重新计算每个cluster的点数,中心点和半径,以及聚合度。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐