参考了http://www.cnblogs.com/chaoku/p/3748456.html?utm_source=tuicool的代码。不过他的代码细节上有点问题。主要在于对于质心的处理上,他的代码中将前面的序号也作为数据进行求距离,但是这里是不用的。
 

kmeans基本思想就是在一个点集中随机选取k个点作为初始的质心,然后在以这K个点求点集中其他点和这质心的距离,并且按照最近的原则,将这个点集分成k个类,接着在这k个类中求其质心,接着便是迭代,一直到质心不变或者SSE小于某个阈值或者达到指定的迭代次数。不过这样的Kmeans有几个缺点1 我们如何确定K值,2初始的质心选取很重要。基于此,可以用二分kmeans(似乎是叫这个),如果有时间可以写一下。

Kmeans之所以能用MapReduce是因为Kmeans中有个计算质心的过程,而这个过程可以并行计算。不过用MapReduce似乎有一个不好的地方,就是他的这个迭代过程比较蛋疼,每次需要把数据放到HDFS,然后再删除,再读取,感觉反而会消耗很多资源,不过没有验证过,仅仅是自己的瞎想。
接下来说下思路。
1map用于求点集中各个点和k个质心的距离,选择最近的质心,key是那个质心对应的序号,value是那个点
2 reduce此时接受到的数据是相同质心的点集,接着要做的是便是求质心,对于相同质心的那个点集,求各列的平均值,以此作为新的质心。
3 以上这样就是一次跌代过程。显然一次迭代是不够的。那么如何用MapReduce进行迭代呢。
我们可以写一个判断条件,就是用于比较新的质心和旧的质心距离是否为0(也可以加上是否达到迭代次数,或者小于某个阈值等)。附上代码
  1. while(true ){
  2. run(centerPath,dataPath,newCenterPath,true);
  3. System. out.println(" " );
  4. System. out.println("The " + ++count+"th time's compution is completed");
  5. System. out.println(" " );
  6. if(Utils.CompareCenters(centerPath,newCenterPath)){
  7. Utils. deleteDir(newCenterPath);
  8. break;
  9.  
  10. }
  11.  
  12. }
这里的CompareCenters就是一个用于判断的条件,如果是的话就break。否则就继续run。
具体说明下过程:
 
 
PS这里主要涉及了3个技术点
1 理解kmeans
2 会使用MapReduce迭代。一开始自己写的MapReduce都是直接在main下写了,没有run方法,后来才知道可以用run来启动,job.waitForCompletion(true)这句话比较重要,当时忘记在run里面写了,结果一直出错。
3 会hadoop的文件操作,比如删除文件,写数据等。
具体附上代码
  1. package hadoop.MachineLearning.kmeans;
  2.  
  3. import java.io.IOException;
  4.  
  5. import org.apache.hadoop.conf.Configuration;
  6. import org.apache.hadoop.fs.Path;
  7. import org.apache.hadoop.io.IntWritable;
  8. import org.apache.hadoop.io.Text;
  9. import org.apache.hadoop.mapreduce.Job;
  10. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
  11. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
  12.  
  13. public class Kmeans {
  14.  
  15. public static void run(String centerPath,String dataPath,String newCenterPath,boolean runReduce) throws IOException, ClassNotFoundException, InterruptedException{
  16. Configuration conf =new Configuration();
  17.  
  18. conf.set("centerPath",centerPath);
  19. Job job=Job.getInstance(conf,"Kmeans");
  20. job.setJarByClass(hadoop.MachineLearning.kmeans.Kmeans.class);
  21. job.setMapperClass(MyMapper.class);
  22. job.setMapOutputKeyClass(IntWritable.class);
  23. job.setMapOutputValueClass(Text.class);
  24. if(runReduce){
  25. job.setReducerClass(MyReducer.class);
  26. job.setOutputKeyClass(Text.class);
  27. job.setOutputValueClass(Text.class);
  28. }
  29.  
  30. FileInputFormat.addInputPath(job,new Path(dataPath));
  31. FileOutputFormat.setOutputPath(job,new Path(newCenterPath));
  32. System.out.println(job.waitForCompletion(true));
  33.  
  34. }
  35.  
  36. public static void main(String[] args) throws Exception {
  37. String centerPath="hdfs://10.107.8.110:9000/Kmeans_input/center_input/centers.txt";
  38. String dataPath="hdfs://10.107.8.110:9000/Kmeans_input/data_input/data.txt";
  39. String newCenterPath="hdfs://10.107.8.110:9000/Kmeans_output/newCenter";
  40. int count=0;
  41.  
  42. while(true){
  43. run(centerPath,dataPath,newCenterPath,true);
  44. System.out.println(" ");
  45. System.out.println("The "+ ++count+"th time's compution is completed");
  46. System.out.println(" ");
  47. if(Utils.CompareCenters(centerPath,newCenterPath)){
  48. Utils.deleteDir(newCenterPath);
  49. break;
  50.  
  51. }
  52.  
  53. }
  54.  
  55. }
  56.  
  57. }
  1. package hadoop.MachineLearning.kmeans;
  2.  
  3. import java.io.IOException;
  4. import java.util.ArrayList;
  5.  
  6. import org.apache.hadoop.conf.Configuration;
  7. import org.apache.hadoop.io.IntWritable;
  8. import org.apache.hadoop.io.LongWritable;
  9. import org.apache.hadoop.io.Text;
  10. import org.apache.hadoop.mapreduce.Mapper;
  11.  
  12. public class MyMapper extends Mapper<LongWritable, Text, IntWritable, Text> {
  13. ArrayList<ArrayList<Double>> centerList=new ArrayList<ArrayList<Double>>();
  14.  
  15. public void setup(Context context) throws IOException{
  16. Configuration conf=context.getConfiguration();
  17. String centerPath=conf.get("centerPath");
  18. centerList=Utils.GetCenterFromHDFS(centerPath,false);
  19.  
  20. }
  21.  
  22. public void map(LongWritable ikey, Text ivalue, Context context)
  23. throws IOException, InterruptedException {
  24. ArrayList<Double> point=Utils.TextToArray(ivalue);
  25. // int size=point.size();
  26. double distance=0.0;
  27. double mindis=9999.0;
  28. int index=-1;
  29.  
  30. for(int i=0;i<centerList.size();i++){
  31. double currentDistance=0;
  32. for(int j=1;j<point.size();j++){//原文是j=0
  33. double centerPoint = Math.abs(centerList.get(i).get(j));
  34. double filed = Math.abs(point.get(j));
  35. currentDistance += Math.pow((centerPoint - filed) / (centerPoint + filed), 2);
  36.  
  37. }
  38. if(currentDistance<mindis){
  39. mindis=currentDistance;
  40. index=i;
  41. }
  42. }
  43.  
  44. /*
  45. for(int i=0;i<centerList.size();i++){
  46. distance=Utils.getDistance(centerList.get(i),point);
  47. if(distance<mindis){
  48. mindis=distance;
  49. index=i+1;
  50. }
  51. }
  52. */
  53. // String value="";
  54.  
  55. context.write(new IntWritable(index+1),ivalue);
  56.  
  57. }
  58.  
  59. }
  1. package hadoop.MachineLearning.kmeans;
  2.  
  3. import java.io.IOException;
  4. import java.util.ArrayList;
  5. import java.util.Arrays;
  6.  
  7. import org.apache.hadoop.io.IntWritable;
  8. import org.apache.hadoop.io.Text;
  9. import org.apache.hadoop.mapreduce.Reducer;
  10.  
  11. public class MyReducer extends Reducer<IntWritable, Text, Text, Text> {
  12.  
  13. public void reduce(IntWritable _key, Iterable<Text> values, Context context)
  14. throws IOException, InterruptedException {
  15. // process values
  16. ArrayList<ArrayList<Double>> pointList=new ArrayList<ArrayList<Double>>();
  17. for (Text val : values) {
  18. ArrayList<Double> point=Utils.TextToArray(val);
  19. pointList.add(point);
  20. }
  21. int row=pointList.size();
  22. int col=pointList.get(0).size();
  23. double[] avg=new double[col];
  24. for(int i=1;i<col;i++){//原文是i=0
  25. double sum=0;
  26. for(int j=0;j<row;j++){
  27. sum+=pointList.get(j).get(i);
  28. }
  29. avg[i]=sum/row;
  30. }
  31. context.write(new Text("") , new Text(Arrays.toString(avg).replace("[", "").replace("]", "")));
  32. }
  33.  
  34. }
  1. package hadoop.MachineLearning.kmeans;
  2.  
  3. import java.io.IOException;
  4. import java.util.ArrayList;
  5.  
  6. import org.apache.hadoop.conf.Configuration;
  7. import org.apache.hadoop.fs.FSDataInputStream;
  8. import org.apache.hadoop.fs.FSDataOutputStream;
  9. import org.apache.hadoop.fs.FileStatus;
  10. import org.apache.hadoop.fs.FileSystem;
  11. import org.apache.hadoop.fs.Path;
  12. import org.apache.hadoop.io.IOUtils;
  13. import org.apache.hadoop.io.Text;
  14. import org.apache.hadoop.util.LineReader;
  15.  
  16. public class Utils {
  17.  
  18. /**
  19. * @param args
  20. * @throws IOException
  21. */
  22. public static ArrayList<Double> TextToArray(Text text){
  23. ArrayList<Double> centers=new ArrayList<Double>();
  24. String[] line=text.toString().split(",");
  25. for(int i=0;i<line.length;i++){
  26. double center=Double.parseDouble(line[i]);
  27. centers.add(center);
  28. }
  29. return centers;
  30. }
  31.  
  32. public static ArrayList<ArrayList<Double>> GetCenterFromHDFS(String centerPath,boolean isDirectory) throws IOException{
  33. Configuration conf=new Configuration();
  34. Path path=new Path(centerPath);
  35. FileSystem fs=path.getFileSystem(conf);
  36.  
  37. ArrayList<ArrayList<Double>> result=new ArrayList<ArrayList<Double>>();
  38.  
  39. if(isDirectory){
  40. FileStatus[] fileStatus=fs.listStatus(path);
  41. for(int i=0;i<fileStatus.length;i++){
  42. if(fileStatus[i].isFile()){
  43. result.addAll(GetCenterFromHDFS(fileStatus[i].getPath().toString(),false));
  44. }
  45. }
  46. return result;
  47. }
  48. FSDataInputStream infs=fs.open(path);
  49. LineReader reader=new LineReader(infs,conf);
  50. Text line=new Text();
  51. while(reader.readLine(line)>0){
  52. ArrayList<Double> center=TextToArray(line);
  53. result.add(center);
  54. }
  55. reader.close();
  56. return result;
  57. }
  58.  
  59. public static void deleteDir(String deletepath) throws IOException{
  60. Configuration conf=new Configuration();
  61. Path path=new Path(deletepath);
  62. FileSystem fs=path.getFileSystem(conf);
  63. fs.delete(path,true);
  64. }
  65.  
  66. public static boolean CompareCenters(String oldPath,String newPath) throws IOException{
  67. ArrayList<ArrayList<Double>> oldcenters=Utils.GetCenterFromHDFS(oldPath,false);
  68. ArrayList<ArrayList<Double>> newcenters=Utils.GetCenterFromHDFS(newPath,true);
  69. //
  70. // System.out.println(" ");
  71. //
  72. // System.out.println("oldcenters's size is "+oldcenters.size());
  73. // System.out.println("newcenters's size is "+newcenters.size());
  74. //
  75. // System.out.println(" ");
  76. int row=oldcenters.size();
  77. int col=oldcenters.get(0).size();
  78. double distance=0.0;
  79. for(int i=0;i<row;i++){
  80. for(int j=1;j<col;j++){
  81. double oldpoint=Math.abs(oldcenters.get(i).get(j));
  82. double newpoint=Math.abs(newcenters.get(i).get(j));
  83. distance+=Math.pow((oldpoint-newpoint)/(oldpoint+newpoint),2);
  84. }
  85. }
  86. if(distance==0.0){
  87. Utils.deleteDir(newPath);
  88. return true;
  89. }else{
  90. Configuration conf = new Configuration();
  91. Path outPath = new Path(oldPath);
  92. FileSystem fs=outPath.getFileSystem(conf);
  93. FSDataOutputStream overWrite=fs.create(outPath,true);
  94. overWrite.writeChars("");
  95. overWrite.close();
  96.  
  97. Path inPath=new Path(newPath);
  98. FileStatus[] listFiles=fs.listStatus(inPath);
  99. for(int i=0;i<listFiles.length;i++){
  100. FSDataOutputStream out=fs.create(outPath);
  101. FSDataInputStream in=fs.open(listFiles[i].getPath());
  102. IOUtils.copyBytes(in,out,4096,true);
  103. }
  104. Utils.deleteDir(newPath);
  105. }
  106. return false;
  107. }
  108.  
  109. public static double getDistance(ArrayList<Double> point1,ArrayList<Double> point2){
  110. double distance=0.0;
  111. if(point1.size()!=point2.size()){
  112. System.err.println("point size not match!!");
  113. System.exit(1);
  114. }else{
  115. for(int i=0;i<point1.size();i++){
  116. double t1=Math.abs(point1.get(i));
  117. double t2=Math.abs(point2.get(i));
  118. distance+=Math.pow((t1-t1)/(t1+t2),2);
  119. }
  120. }
  121. return distance;
  122. }
  123.  
  124. public static void main(String[] args) throws IOException {
  125. // TODO Auto-generated method stub
  126. String oldpath="hdfs://10.107.8.110:9000/Kmeans_input/center_input/centers.txt";
  127. String newpath="hdfs://10.107.8.110:9000/Kmeans_input/test";
  128. if(Utils.CompareCenters(oldpath,newpath)){
  129. System.out.println("equals");
  130. }else{
  131. System.out.println("not equals");
  132. }
  133. /*
  134. ArrayList<ArrayList<Double>> centers=Utils.GetCenterFromHDFS(path,true);
  135. for(ArrayList<Double> center:centers){
  136. System.out.println(" ");
  137. for(double point:center){
  138. System.out.println(point);
  139. }
  140. }
  141. */
  142. //String deletepath="hdfs://10.107.8.110:9000/output/";
  143. //Utils.deleteDir(deletepath);
  144. }
  145.  
  146. }
 

Kmeans在MapReduce中的实现的更多相关文章

  1. Hadoop学习笔记—11.MapReduce中的排序和分组

    一.写在之前的 1.1 回顾Map阶段四大步骤 首先,我们回顾一下在MapReduce中,排序和分组在哪里被执行: 从上图中可以清楚地看出,在Step1.4也就是第四步中,需要对不同分区中的数据进行排 ...

  2. Hadoop学习笔记—12.MapReduce中的常见算法

    一.MapReduce中有哪些常见算法 (1)经典之王:单词计数 这个是MapReduce的经典案例,经典的不能再经典了! (2)数据去重 "数据去重"主要是为了掌握和利用并行化思 ...

  3. MapReduce中作业调度机制

    MapReduce中作业调度机制主要有3种: 1.先入先出FIFO      Hadoop 中默认的调度器,它先按照作业的优先级高低,再按照到达时间的先后选择被执行的作业. 2.公平调度器(相当于时间 ...

  4. Mapreduce中的字符串编码

    Mapreduce中的字符串编码 $$$ Shuffle的执行过程,需要经过多次比较排序.如果对每一个数据的比较都需要先反序列化,对性能影响极大. RawComparator的作用就不言而喻,能够直接 ...

  5. MapReduce中一次reduce方法的调用中key的值不断变化分析及源码解析

    摘要:mapreduce中执行reduce(KEYIN key, Iterable<VALUEIN> values, Context context),调用一次reduce方法,迭代val ...

  6. Hadoop学习之路(二十三)MapReduce中的shuffle详解

    概述 1.MapReduce 中,mapper 阶段处理的数据如何传递给 reducer 阶段,是 MapReduce 框架中 最关键的一个流程,这个流程就叫 Shuffle 2.Shuffle: 数 ...

  7. [MapReduce_5] MapReduce 中的 Combiner 组件应用

    0. 说明 Combiner 介绍 &&  在 MapReduce 中的应用 1. 介绍 Combiner: Map 端的 Reduce,有自己的使用场景 在相同 Key 过多的情况下 ...

  8. Hadoop案例(七)MapReduce中多表合并

    MapReduce中多表合并案例 一.案例需求 订单数据表t_order: id pid amount 1001 01 1 1002 02 2 1003 03 3 订单数据order.txt 商品信息 ...

  9. MapReduce中的分布式缓存使用

    MapReduce中的分布式缓存使用 @(Hadoop) 简介 DistributedCache是Hadoop为MapReduce框架提供的一种分布式缓存机制,它会将需要缓存的文件分发到各个执行任务的 ...

随机推荐

  1. 多线程进阶之并发工具类:CountDownLatch、CyclicBarrier

    并发工具类在java.util.concurrent包下.常用的有CountDownLatch.CyclicBarrier,用它们可以控制并发流程. 1.CountDownLatch探究: 主要用到其 ...

  2. .gitigore 相关

    为什么要配置.gitigore 在我们使用git的过程当中,不是任何文件都需要commit到本地或者远程仓库的,比如一些三方库文件.那么作为一个git新手,很多人不知道如何配置.gitignore文件 ...

  3. 快学Scala-第五章 类

    知识点: 1.简单类和无参方法 class Counter { private var value = 0 //必须初始化字段 def increment() { value += 1} //方法默认 ...

  4. 添加以及删除className

    <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...

  5. java 类与对象

    class XiyoujiRenwu { float height,weight; String head, ear; void speak(String s) { System.out.printl ...

  6. A*算法实现

    A* 算法非常简单.算法维护两个集合:OPEN 集和 CLOSED 集.OPEN 集包含待检测节点.初始状态,OPEN集仅包含一个元素:开始位置.CLOSED集包含已检测节点.初始状态,CLOSED集 ...

  7. 转:利用ant与jmeter实现负载测试自动化

    性能测试一直以来都是测试领域一个令人争议的话题.测试的参考标准.评判依据及测试的方法选择都很难有一个统一的说法.但无论如何,对于需要能够承受一定压力而运行的程序来说,进行其进行功能和性能测试是一个必不 ...

  8. 转:Linux基本命令大全

    Linux基本命令大全   新手刚刚接触Linux的时候可能处处感到不便,不过没有关系,接触新的事物都有这样的一个过程,在你用过Linux一段时间后,你就会逐渐了解Linux其实和Windows一样容 ...

  9. 【转载】最全的面试题目整理(HTML+CSS部分)

    转载自 知乎 @西点王子 https://www.zhihu.com/people/F211/answers 1. 常用那几种浏览器测试?有哪些内核(Layout Engine)? (Q1) 浏览器: ...

  10. 第15章 I/O(输入/输出)

    在变量.数组和对象中存储的数据是暂时存在的,程序结束后它们就会丢失.为了能够永久地保存创建的数据,需要将其保存在磁盘文件中,这样就可以在其它程序中使用它们.Java的I/O技术可以将数据保存到文本文件 ...