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的点数,中心点和半径,以及聚合度。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
K-Means算法是一种常见的无监督聚类算法,适用于大规模数据集的聚类分析。在Java编程语言中,实现K-Means算法可以使用一些开源的第三方机器学习库,例如Weka、Apache Mahout等。 以Weka为例,其提供了丰富的聚类算法实现,包括K-Means。用户可以使用Weka提供的API来实现K-Means算法。首先需要将数据转化为Weka框架中的Instances格式,即一个Instances对象表示一个实例集合,其中每个实例由多个属性组成。然后,通过构建一个SimpleKMeans对象,将转化后的数据传递给SimpleKMeans对象,即可进行聚类分析。 简单示例代码如下: ```java import weka.clusterers.SimpleKMeans; import weka.core.Instances; import weka.core.converters.ConverterUtils.DataSource; public class KMeansDemo { public static void main(String[] args) { try { Instances data = DataSource.read("path/to/dataset.arff"); SimpleKMeans kmeans = new SimpleKMeans(); kmeans.setSeed(10); kmeans.setPreserveInstancesOrder(true); kmeans.setNumClusters(3); kmeans.buildClusterer(data); System.out.println(kmeans.toString()); // 输出聚类结果 } catch (Exception e) { e.printStackTrace(); } } } ``` 上述代码首先从数据源加载数据集,然后创建一个SimpleKMeans对象,设置其参数(例如种子、簇数等),最后将数据集传递给kmeans实例对象进行聚类分析。最终输出结果可以通过SimpleKMeans对象的toString方法获取。 需要注意的是,K-Means算法需要对原始数据进行预处理(例如特征缩放、归一化等),特别是当数据集的特征数很多时。此外,Weka还提供了其他调节聚类效果的参数,例如聚类中心初始化方法、聚类质量评估方法等,用户可以根据实际情况进行调节。 综上所述,使用Java实现K-Means算法可以通过第三方机器学习库,例如Weka、Mahout等来完成。在实现过程中需要注意数据预处理及算法调节参数的设置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值