K-Means聚类算法java实现

对于K-Means算法想必做机器学习和数据挖掘的广大同胞们已经不再陌生,做为数据挖据的十大经典算法之一,k-Means做聚类分析上有得天独厚的优势。对于其原理进行简单的描述:

k-Means算法是典型的基于距离的聚类算法,采用的是距离作为相似性指标。经过n次迭代后,当中心的位置不在发生变换的时候即是收敛完成。

算法:

           1. 从n个文档中随机的选择出k个文档作为质心

           2.从剩余的文档中测量出每个文档到质心的距离,并归类到最小质心的一类中

          3. 重新计算质心的位置

          4.重复2-3步,直到迭代完成。

由以上步骤,可以有java实现K-Means算法。随机产生100个点,设置k=5后进行聚类操作:

         1.主函数:

          

[html]  view plain  copy
  1. package KMeans;  
  2. import java.util.ArrayList;  
  3.   
  4. /**  
  5.  * K-Means算法  
  6.  * @author Administrator  
  7.  *  
  8.  */  
  9. public class k_means {  
  10.   
  11.     /**  
  12.      * @param args  
  13.      */  
  14.     public static void main(String[] args) {  
  15.     //1.创建二维数组 10x10的数组  
  16.         int num_1[]=new int[100];  
  17.         int num_2[]=new int[100];  
  18.         //随机赋值  
  19.   
  20.             for(int i=0;i<100;i++){  
  21.                 num_1[i]=(int)( Math.random()*100);  
  22.             }  
  23.           
  24.             for(int i=0;i<100;i++){  
  25.                 num_2[i]=(int)( Math.random()*100);  
  26.             }  
  27.         // 2.创建点坐标  
  28.             ArrayList<pointBean> list=new ArrayList<pointBean>();  
  29.             pointBean bean;  
  30.             for(int i=0;i<100;i++){  
  31.                 bean=new pointBean();  
  32.                 bean.point_x=num_1[i];  
  33.                 bean.point_y=num_2[i];  
  34.                 list.add(bean);  
  35.             }  
  36.      // 执行k-means算法  
  37.          getDataKMeans gg=new getDataKMeans();  
  38.          gg.setData(list);  
  39.   
  40.     }  
  41. }  
2.设置点的x,y坐标的Bean

[html]  view plain  copy
  1. package KMeans;  
  2.   
  3. public class pointBean {  
  4. int point_x;  
  5. int point_y;  
  6. public int getPoint_x() {  
  7.     return point_x;  
  8. }  
  9. public void setPoint_x(int point_x) {  
  10.     this.point_x = point_x;  
  11. }  
  12. public int getPoint_y() {  
  13.     return point_y;  
  14. }  
  15. public void setPoint_y(int point_y) {  
  16.     this.point_y = point_y;  
  17. }  
  18. @Override  
  19. public String toString() {  
  20.     return "pointBean [point_x=" + point_x + "point_y=" + point_y + "]";  
  21. }  
  22. public pointBean(int point_x, int point_y) {  
  23.     super();  
  24.     this.point_x = point_x;  
  25.     this.point_y = point_y;  
  26. }  
  27. public pointBean() {  
  28.     super();  
  29. }  
  30. }  
3.聚类的计算部分:

[html]  view plain  copy
  1. package KMeans;  
  2.   
  3. import java.util.ArrayList;  
  4.   
  5. public class getDataKMeans {  
  6.   
  7.     int k=5;//k值  
  8.       //第一个中心点x,y  
  9.     static double con1_x;  
  10.     static double con1_y;  
  11.     //第一个中心点x,y  
  12.     static double con2_x;  
  13.     static double con2_y;  
  14.     //第一个中心点x,y  
  15.     static double con3_x;  
  16.     static double con3_y;  
  17.     //第一个中心点x,y  
  18.     static double con4_x;  
  19.     static double con4_y;  
  20.     //第一个中心点x,y  
  21.     static double con5_x;  
  22.     static double con5_y;         
  23.     //创建5个list装各个点  
  24.     ArrayList<pointBean> list1=new ArrayList<pointBean>();  
  25.     ArrayList<pointBean> list2=new ArrayList<pointBean>();  
  26.     ArrayList<pointBean> list3=new ArrayList<pointBean>();  
  27.     ArrayList<pointBean> list4=new ArrayList<pointBean>();  
  28.     ArrayList<pointBean> list5=new ArrayList<pointBean>();  
  29.       
  30.     public  void setData(ArrayList<pointBean> list){  
  31.         con1_x=list.get(0).point_x;  
  32.         con1_y=list.get(0).point_y;  
  33.         con2_x=list.get(1).point_x;  
  34.         con2_y=list.get(1).point_y;  
  35.         con3_x=list.get(2).point_x;  
  36.         con3_y=list.get(2).point_y;  
  37.         con4_x=list.get(3).point_x;  
  38.         con4_y=list.get(3).point_y;  
  39.         con5_x=list.get(4).point_x;  
  40.         con5_y=list.get(4).point_y;  
  41.         //分别加入list中  
  42.         list1.add(list.get(0));  
  43.         list2.add(list.get(1));  
  44.         list3.add(list.get(2));  
  45.         list4.add(list.get(3));  
  46.         list5.add(list.get(4));  
  47.         //循环操作  
  48.         for(int i=5;i<list.size();i++){  
  49.             getLength(list.get(i));  
  50.         }         
  51.         // 打印出对应的中心点 、聚类的值  
  52.         System.out.println("-------1-------");  
  53.         System.out.println("1的中心点:"+con1_x+" "+con1_y);  
  54.         for(int i=0;i<list1.size();i++){  
  55.             System.out.println(list1.get(i).point_x+" "+list1.get(i).point_y);  
  56.         }  
  57.         System.out.println("-------2-------");  
  58.         System.out.println("2的中心点:"+con2_x+" "+con2_y);  
  59.         for(int i=0;i<list2.size();i++){  
  60.             System.out.println(list2.get(i).point_x+" "+list2.get(i).point_y);  
  61.         }  
  62.         System.out.println("-------3-------");  
  63.         System.out.println("3的中心点:"+con3_x+" "+con3_y);  
  64.         for(int i=0;i<list3.size();i++){  
  65.             System.out.println(list3.get(i).point_x+" "+list3.get(i).point_y);  
  66.         }  
  67.         System.out.println("-------4-------");  
  68.         System.out.println("4的中心点:"+con4_x+" "+con4_y);  
  69.         for(int i=0;i<list4.size();i++){  
  70.             System.out.println(list4.get(i).point_x+" "+list4.get(i).point_y);  
  71.         }  
  72.         System.out.println("-------5-------");  
  73.         System.out.println("5的中心点:"+con5_x+" "+con5_y);  
  74.         for(int i=0;i<list5.size();i++){  
  75.             System.out.println(list5.get(i).point_x+" "+list5.get(i).point_y);  
  76.         }     
  77.     }  
  78.     /**  
  79.      * 求出每个点到中心点距离  
  80.      * @param point  
  81.      */  
  82.     public  void getLength(pointBean point) {  
  83.         int x=point.point_x;  
  84.         int y=point.point_y;  
  85.           
  86.           
  87.         double s1=(x-con1_x)*(x-con1_x)+(y-con1_y)*(y-con1_y);  
  88.         double s2=(x-con2_x)*(x-con2_x)+(y-con2_y)*(y-con2_y);  
  89.         double s3=(x-con3_x)*(x-con3_x)+(y-con3_y)*(y-con3_y);  
  90.         double s4=(x-con4_x)*(x-con4_x)+(y-con4_y)*(y-con4_y);  
  91.         double s5=(x-con5_x)*(x-con5_x)+(y-con5_y)*(y-con5_y);  
  92.           
  93.         double nn[]={s1,s2,s3,s4,s5};  
  94.         // 找出最小的一个  
  95.         double temp=nn[0];  
  96.         for(int i=1;i<nn.length;i++){  
  97.             if(nn[i]<=temp)  
  98.                 temp=nn[i];  
  99.         }  
  100.         // 添加点  
  101.         if(temp==s1){  
  102.             list1.add(point);  
  103.             upDataPoint(list1,con1_x,con1_y);  
  104.         }  
  105.         if(temp==s2){  
  106.             list2.add(point);  
  107.             upDataPoint(list2,con2_x,con2_x);  
  108.         }  
  109.         if(temp==s3){  
  110.             list3.add(point);  
  111.             upDataPoint(list3,con3_x,con3_x);  
  112.         }  
  113.         if(temp==s4){  
  114.             list4.add(point);  
  115.             upDataPoint(list4,con4_x,con4_x);  
  116.         }  
  117.         if(temp==s5){  
  118.             list5.add(point);  
  119.             upDataPoint(list5,con5_x,con5_x);  
  120.         }  
  121.           
  122.           
  123.           
  124.           
  125.           
  126.           
  127.           
  128.     }  
  129.     /**  
  130.      * 更新中心点坐标  
  131.      * @param list  
  132.      */  
  133.     private void upDataPoint(ArrayList<pointBean> list,double x,double y) {  
  134.         double up_x=0;  
  135.         double up_y=0;  
  136.         for(int i=0;i<list.size();i++){  
  137.             up_x+=list.get(i).point_x;  
  138.             up_y+=list.get(i).point_y;  
  139.         }  
  140.         x=up_x/(list.size());  
  141.         y=up_y/(list.size());  
  142.     }  
  143.   
  144. }  

得到的测试结果:

[html]  view plain  copy
  1. -------1-------  
  2. 1的中心点:37.0 80.0  
  3. 37 80  
  4. 54 88  
  5. 10 50  
  6. 45 85  
  7. 40 95  
  8. 51 87  
  9. 47 90  
  10. 42 97  
  11. 30 61  
  12. 20 63  
  13. 60 80  
  14. 37 93  
  15. 47 79  
  16. 37 96  
  17. 58 86  
  18. -------2-------  
  19. 2的中心点:55.0 57.0  
  20. 55 57  
  21. 89 81  
  22. 56 58  
  23. 49 53  
  24. 58 62  
  25. 42 52  
  26. 26 49  
  27. 94 95  
  28. 21 44  
  29. 1 19  
  30. 27 53  
  31. 59 74  
  32. 61 77  
  33. 32 56  
  34. 49 54  
  35. 10 39  
  36. 53 55  
  37. 48 58  
  38. 8 36  
  39. 63 63  
  40. 4 26  
  41. 49 62  
  42. 63 80  
  43. 45 62  
  44. -------3-------  
  45. 3的中心点:79.0 22.0  
  46. 79 22  
  47. 84 41  
  48. 68 17  
  49. 79 2  
  50. 99 33  
  51. 69 11  
  52. 70 29  
  53. 52 8  
  54. 94 25  
  55. 81 8  
  56. 54 20  
  57. 81 32  
  58. 81 34  
  59. 48 2  
  60. 22 1  
  61. 89 27  
  62. 57 18  
  63. 42 11  
  64. 50 6  
  65. 74 28  
  66. 98 27  
  67. 98 36  
  68. -------4-------  
  69. 4的中心点:59.0 51.0  
  70. 59 51  
  71. 64 40  
  72. 21 8  
  73. 5 19  
  74. 29 32  
  75. 62 40  
  76. 7 5  
  77. 16 25  
  78. 53 36  
  79. 28 29  
  80. 33 19  
  81. 80 55  
  82. 50 40  
  83. 98 76  
  84. 81 53  
  85. 23 23  
  86. 92 62  
  87. 85 63  
  88. 65 36  
  89. 48 44  
  90. 25 30  
  91. 11 15  
  92. 97 79  
  93. 16 9  
  94. 60 43  
  95. 59 51  
  96. 67 43  
  97. -------5-------  
  98. 5的中心点:10.0 97.0  
  99. 10 97  
  100. 14 74  
  101. 13 89  
  102. 1 60  
  103. 4 94  
  104. 6 72  
  105. 1 73  
  106. 4 86  
  107. 18 80  
  108. 2 81  
  109. 11 70  
  110. 19 97 
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值