hadoop下kmeans算法实现四

KMapper.java

[java]  view plain copy
  1. import java.io.ByteArrayOutputStream;  
  2. import java.io.IOException;  
  3. import java.net.URI;  
  4. import java.util.StringTokenizer;  
  5.   
  6. import org.apache.hadoop.conf.Configuration;  
  7. import org.apache.hadoop.fs.FSDataInputStream;  
  8. import org.apache.hadoop.fs.FileSystem;  
  9. import org.apache.hadoop.fs.Path;  
  10. import org.apache.hadoop.io.IOUtils;  
  11. import org.apache.hadoop.io.LongWritable;  
  12. import org.apache.hadoop.io.Text;  
  13. import org.apache.hadoop.mapreduce.Mapper;  
  14.   
  15.   
  16. public class KMapper extends Mapper<LongWritable, Text, Text, Text> {  
  17.       
  18.     private String[] center;  
  19.     //读取3.txt中更新的中心点坐标,并将坐标存入center数组中  
  20.     protected void setup(Context context) throws IOException,InterruptedException  //read centerlist, and save to center[]  
  21.     {  
  22.         String centerlist = "hdfs://localhost:9000/home/administrator/hadoop/kmeans/input2/3.txt"; //center文件  
  23.         Configuration conf1 = new Configuration();  
  24.         conf1.set("hadoop.job.ugi""hadoop-user,hadoop-user");  
  25.        FileSystem fs = FileSystem.get(URI.create(centerlist),conf1);  
  26.        FSDataInputStream in = null;  
  27.        ByteArrayOutputStream out = new ByteArrayOutputStream();  
  28.        try{  
  29.                
  30.            in = fs.open( new Path(centerlist) );  
  31.            IOUtils.copyBytes(in,out,100,false);    
  32.            center = out.toString().split(" ");  
  33.            }finally{  
  34.                 IOUtils.closeStream(in);  
  35.             }  
  36.     }  
  37.     //从hadoop接收的数据在2.txt中保存  
  38.     public void map(LongWritable key,Text value,Context context) throws IOException,InterruptedException  
  39.     {  
  40.         StringTokenizer itr = new StringTokenizer(value.toString());  
  41.         //从2.txt读入数据,以空格为分割符,一个一个处理  
  42.         while(itr.hasMoreTokens())//用于判断所要分析的字符串中,是否还有语言符号,如果有则返回true,反之返回false  
  43.         {  
  44.               
  45.             //计算第一个坐标跟第一个中心的距离min  
  46.             String outValue = new String(itr.nextToken());//逐个获取以空格为分割符的字符串(2,3) (10,30) (34,40) (1,1)  
  47.             String[] list = outValue.replace("(""").replace(")""").split(",");  
  48.             String[] c = center[0].replace("(""").replace(")""").split(",");  
  49.             float min = 0;  
  50.             int pos = 0;  
  51.             for(int i=0;i<list.length;i++)  
  52.             {  
  53.                 System.out.println(i+"list:"+list[i]);  
  54.                 System.out.println(i+"c:"+c[i]);  
  55.                 min += (float) Math.pow((Float.parseFloat(list[i]) - Float.parseFloat(c[i])),2);//求欧式距离,为加根号  
  56.             }  
  57.               
  58.               
  59.             for(int i=0;i<center.length;i++)  
  60.             {  
  61.                 String[] centerStrings = center[i].replace("(""").replace(")""").split(",");  
  62.                 float distance = 0;  
  63.                 for(int j=0;j<list.length;j++)  
  64.                     distance += (float) Math.pow((Float.parseFloat(list[j]) - Float.parseFloat(centerStrings[j])),2);  
  65.                 if(min>distance)  
  66.                 {  
  67.                     min=distance;  
  68.                     pos=i;  
  69.                 }  
  70.             }  
  71.             context.write(new Text(center[pos]), new Text(outValue));//输出:中心点,对应的坐标  
  72.             System.out.println("中心点"+center[pos]+"对应坐标"+outValue);  
  73.             System.out.println("Mapper输出:"+center[pos]+" "+outValue);  
  74.         }  
  75.     }  
  76.   
  77. }  


KReduce.java

[java]  view plain copy
  1. import java.io.IOException;  
  2.   
  3. import org.apache.hadoop.io.Text;  
  4. import org.apache.hadoop.mapreduce.Reducer;  
  5.   
  6.   
  7. public class KReducer extends Reducer<Text, Text, Text, Text> {  
  8.     //<中心点类别,中心点对应的坐标集合>,每个中心点类别的坐标集合求新的中心点  
  9.       
  10.     public void reduce(Text key,Iterable<Text> value,Context context) throws IOException,InterruptedException  
  11.     {  
  12.         String outVal = "";  
  13.         int count=0;  
  14.         String center="";  
  15.         System.out.println("Reduce过程第一次");  
  16.         System.out.println(key.toString()+"Reduce");  
  17.         int length = key.toString().replace("(""").replace(")""").replace(":""").split(",").length;  
  18.         float[] ave = new float[Float.SIZE*length];  
  19.         for(int i=0;i<length;i++)  
  20.             ave[i]=0;   
  21.         for(Text val:value)  
  22.         {  
  23.             System.out.println("val:"+val.toString());  
  24.             System.out.println("values:"+value.toString());  
  25.             outVal += val.toString()+" ";  
  26.             String[] tmp = val.toString().replace("(""").replace(")""").split(",");  
  27.             System.out.println("temlength:"+tmp.length);  
  28.             for(int i=0;i<tmp.length;i++)  
  29.                 ave[i] += Float.parseFloat(tmp[i]);  
  30.             count ++;  
  31.         }  
  32.         System.out.println("count:"+count);  
  33.         System.out.println("outVal:"+outVal+"/outVal");  
  34.         for (int i=0;i<2;i++)  
  35.         {  
  36.             System.out.println("ave"+i+"i"+ave[i]);  
  37.         }  
  38.         //ave[0]存储X坐标之和,ave[1]存储Y坐标之和  
  39.         for(int i=0;i<length;i++)  
  40.         {  
  41.             ave[i]=ave[i]/count;  
  42.             if(i==0)  
  43.                 center += "("+ave[i]+",";  
  44.             else {  
  45.                 if(i==length-1)  
  46.                     center += ave[i]+")";  
  47.                 else {  
  48.                     center += ave[i]+",";  
  49.                 }  
  50.             }  
  51.         }  
  52.         System.out.println("写入part:"+key+" "+outVal+" "+center);  
  53.         context.write(key, new Text(outVal+center));  
  54.     }  
  55.   
  56. }  

NewCenter.java

[java]  view plain copy
  1. import java.io.ByteArrayInputStream;  
  2. import java.io.ByteArrayOutputStream;  
  3. import java.io.IOException;  
  4. import java.io.OutputStream;  
  5. import java.net.URI;  
  6.   
  7. import org.apache.hadoop.conf.Configuration;  
  8. import org.apache.hadoop.fs.FSDataInputStream;  
  9. import org.apache.hadoop.fs.FileSystem;  
  10. import org.apache.hadoop.fs.Path;  
  11. import org.apache.hadoop.io.IOUtils;  
  12.   
  13.   
  14. public class NewCenter {  
  15.       
  16.     int k = 2;  
  17.     float shold=Integer.MIN_VALUE;  
  18.     String[] line;  
  19.     String newcenter = new String("");  
  20.       
  21.     public float run(String[] args) throws IOException,InterruptedException  
  22.     {  
  23.         Configuration conf = new Configuration();  
  24.         conf.set("hadoop.job.ugi""hadoop,hadoop");   
  25.         FileSystem fs = FileSystem.get(URI.create(args[2]+"/part-r-00000"),conf);  
  26.         FSDataInputStream in = null;  
  27.         ByteArrayOutputStream out = new ByteArrayOutputStream();  
  28.         try{   
  29.             in = fs.open( new Path(args[2]+"/part-r-00000"));   
  30.             IOUtils.copyBytes(in,out,50,false);  
  31.             line = out.toString().split("\n");  
  32.             } finally {   
  33.                 IOUtils.closeStream(in);  
  34.             }  
  35.       
  36.         //System.out.println("上一次的MapReduce结果:"+out.toString());  
  37.         System.out.println("上一次MapReduce结果:第一行:"+line[0]);  
  38.         System.out.println("第二行:"+line[1]);  
  39.         System.out.println("。");  
  40.         for(int i=0;i<k;i++)  
  41.         {  
  42.             String[] l = line[i].replace("\t"" ").split(" ");//如果这行有tab的空格,可以替代为空格  
  43.             //(key,values)key和values同时输出是,中间保留一个Tab的距离,即'\t'  
  44.             String[] startCenter = l[0].replace("(""").replace(")""").split(",");  
  45.             //上上次的中心点startCenter[0]=(10,30);startCenter[1]=(2,3);  
  46.             String[] finalCenter = l[l.length-1].replace("(""").replace(")""").split(",");  
  47.             //上一次的中心点finalCenter[0]=(22,35);finalCenter[1]=(1.5,2.0);  
  48.             float tmp = 0;  
  49.             for(int j=0;j<startCenter.length;j++)  
  50.                 tmp += Math.pow(Float.parseFloat(startCenter[j])-Float.parseFloat(finalCenter[j]), 2);  
  51.             //两个中心点间的欧式距离的平方  
  52.             newcenter = newcenter + l[l.length - 1].replace("\t""") + " ";  
  53.             if(shold <= tmp)  
  54.                 shold = tmp;  
  55.             System.out.println(i+"坐标距离:"+tmp);  
  56.         }  
  57.         System.out.println("新中心点:"+newcenter);  
  58.         OutputStream out2 = fs.create(new Path(args[1]+"/center/3.txt") );   
  59.         IOUtils.copyBytes(new ByteArrayInputStream(newcenter.getBytes()), out2, 4096,true);  
  60.         //System.out.println(newcenter);  
  61.         return shold;  
  62.         //return 0;  
  63.     }  
  64.   
  65. }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值