KMeans算法和简单命令使用

KMeans算法和简单命令使用 
算法简介
 同一聚类中的对象相似度较高;而不同聚类中的对象相似度较小
 以空间中k个点为中心进行聚类,对最靠近他们的对象归类。通过迭代的方法,逐次更新各聚类中心的值,直至得到最好的聚类结果。
 首先从n个数据对象任意选择 k个对象作为初始聚类中心;而对于所剩下其它对象,则根据它们与这些聚类中心的相似度(距离),分别将它们分配给与其最相似的(聚类中心所代表的)聚类;然后再计算每个所获新聚类的聚类中心(该聚类中所有对象的均值);不断重复这一过程直到标准测度函数开始收敛为止。一般都采用均方差作为标准测度函数. k个聚类具有以下特点:各聚类本身尽可能的紧凑,而各聚类之间尽可能的分开。
 对于每一个 cluster,我们可以选出一个中心点 (center),使得该 cluster中的所有的点到该中心点的距离小于到其他 cluster的中心的距离
 
建立文件 
https://cwiki.apache.org/confluence/display/MAHOUT/Clustering+of+synthetic+control+data
下载数据集synthetic_control.data,在以上官网上的Input data set. Download it here点击可下载
把里面的内容复制到了testdata文件上并放在了/root/input目录下
转换成seq文件 
 
首先简单说明下,mahout下处理的文件必须是SequenceFile格式的,所以需要把txtfile转换成sequenceFile。SequenceFile是hadoop中的一个类,允许我们向文件中写入二进制的键值对,具体介绍请看eyjian写的http://www.hadoopor.com/viewthread.php?tid=144&highlight=sequencefile
输入命令: mahout seqdirectory --input /root/input/ --output /root/input/ --charset UTF-8

可以看到在input目录下多了2个文件, 这就是我们要的SequenceFile格式文件
把文件导入到分布式文件系统上
hadoop fs -mkdir testdata  在hadoop下建立testdata文件
 hadoop fs -put /root/input/kmeans.data/  testdata testdata 把kmean.data放到HDFS上
我们可以看到:
执行使用k-means算法
 
 
输入命令:mahoutorg.apache.mahout.clustering.syntheticcontrol.kmeans.Job
 
出现错误:
Exception in thread "main" org.apache.hadoop.mapreduce.lib.input.InvalidInputException:Input path does not exist: file:/root/testdata
 
解决:
考虑可能是默认目录为root/testdata
所以cd到input文件名字改成testdata后重新运行命令:mahout org.apache.mahout.clustering.syntheticcontrol.kmeans.Job
后运行成功:  

 
如果是在本地执行的话算法执行完之后在input目录下可以找到output,hadoop集群的话就从hdfs上面导出

数据输入格式
测试数据
 
 
 
 
每个数据和数据之间用空格分开,数据都是double型的
Kmean算法在每次取数据时对所有的数据只取其中的一列
 
kmeans命令使用:
mahout kmeans \
 -i <input vectors directory> \ 输入目录
 -c <input clusters directory> \输入的簇目录
 -o <output working directory> \输出目录
 -k <optional number of initial clusters to sample from input vectors> \
 -dm <DistanceMeasure> \路径方法的类名,默认是SquaredEuclidean   
-x <maximum number of iterations> \迭代的次数
-cd <optional convergence delta. Default is 0.5> \delta的值
-ow <overwrite output directory if present>如果存在覆盖输出目录
-cl <run input vector clustering after computing Canopies>在运行Canopy算法后运行输入向量簇
-xm <execution method: sequential or mapreduce>用sequential或者mapreduce运行
注意:当-k被指定的时候,-c目录下的所有聚类都将被重写,将从输入的数据向量中随机抽取-k个点作为初始聚类的中心。
 查看结果
 
mahout seqdumper:将SequenceFile文件转成可读的文本形式,对应的源文件是org.apache.mahout.utils.SequenceFileDumper.java
mahout vectordump:将向量文件转成可读的文本形式,对应的源文件是org.apache.mahout.utils.vectors.VectorDumper.java
mahout clusterdump:分析最后聚类的输出结果,对应的源文件是org.apache.mahout.utils.clustering.ClusterDumper.java
 
例如我的文件输出在/root/input/output,我可以
输入命令:mahout seqdumper -s /root/input/output/clusteredPoints/part-m-00000
来查看point
mahout clusterdump --seqFileDir /root/input/output/clusteredPoints/part-m-00000

如果直接在本地打开是会有乱码的
出现问题:但目前我还不知道如何输出到本地上,-o命令总是报错,目前只会在console上观察结果
解决:例如要输出上述的point文件,可以使用命令:mahout seqdumper -s /root/input/output/clusteredPoints/part-m-00000 -o result.txt

 
 运行结果分析
 
首先Kmeans算法默认是10次迭代,所以我们得到的clusters是10个
结果文件夹有clusteredPoints,clusters-N,data,用命令mahout seqdumper仔细看了一下结果文件
 
clusteredPoints:存放的是最后聚类的结果,将cluster-id和documents-id都展示出来了,用mahout seqdumper读clusteredPoints结果的key-value类型是(IntWritable,WeightedVectorWritable)
例如之前的/root/input/output/clusteredPoints/part-m-00000文件

 
 
clusters-N:是第N次聚类的结果,其中n为某类的样本数目,c为各类各属性的中心,r为各类属性的半径。 clusters-N结果类型是(Text,Cluster)
例如要观察clusters-10的内容,可以使用命令:
mahout seqdumper -s /root/input/output/clusters-10/part-r-00000
要输出到txt文件则要在后面加上:-o xxxx.txt(xxxx是文件名)

data:存放的是原始数据,这个文件夹下的文件可以用mahout vectordump来读取,原始数据是向量形式的,其它的都只能用mahout seqdumper来读取,向量文件也可以用mahout seqdumper来读取,只是用vectordump读取出来的是数字结果,没有对应的key,用seqdumper读出来的可以看到key,即对应的url,而value读出来的是一个类描述,而不是数组向量
例如要查看data下的文件用命令:
mahout vectordump -s /root/input/output/data/part-m-00000/    
同样的要输出的话在后面加上 –o  xxxx.txt

 适用场景展望
 
对于像kmeans这样的聚类算法都是用来求相似度的,如果想要得到某些数据的在某些条件下的相似程度就可以用kmean算法,它可以帮助总结出一些数据规律。比如:在所有女人当中打市内电话的数据,如果按通话时间分的话就可以用kmeans算法,分成时间长的会形成一个簇,时间短的也会形成一个簇。
 
但是对例外和噪声文本比较敏感。另外一个问题是,没有一个好的办法确定k的取值。

0 个评论

要回复文章请先登录注册