k-means聚类算法的实现

在我的程序中,我将k = 2用于k均值算法,即我只想要2个聚类。 我以一种非常简单直接的方式实现,仍然无法理解为什么我的程序进入无限循环。 任何人都可以指导我在哪里犯错误..?

为简单起见,我已经在程序代码本身中获取了输入。 这是我的代码:

import java.io.*; import java.lang.*; class Kmean { public static void main(String args[]) { int N=9; int arr[]={2,4,10,12,3,20,30,11,25}; // initial data int i,m1,m2,a,b,n=0; boolean flag=true; float sum1=0,sum2=0; a=arr[0];b=arr[1]; m1=a; m2=b; int cluster1[]=new int[9],cluster2[]=new int[9]; for(i=0;i<9;i++) System.out.print(arr[i]+ "\t"); System.out.println(); do { n++; int k=0,j=0; for(i=0;i<9;i++) { if(Math.abs(arr[i]-m1)<=Math.abs(arr[i]-m2)) { cluster1[k]=arr[i]; k++; } else { cluster2[j]=arr[i]; j++; } } System.out.println(); for(i=0;i<9;i++) sum1=sum1+cluster1[i]; for(i=0;i<9;i++) sum2=sum1+cluster2[i]; a=m1; b=m2; m1=Math.round(sum1/k); m2=Math.round(sum2/j); if(m1==a && m2==b) flag=false; else flag=true; System.out.println("After iteration "+ n +" , cluster 1 :\n"); //printing the clusters of each iteration for(i=0;i<9;i++) System.out.print(cluster1[i]+ "\t"); System.out.println("\n"); System.out.println("After iteration "+ n +" , cluster 2 :\n"); for(i=0;i<9;i++) System.out.print(cluster2[i]+ "\t"); }while(flag); System.out.println("Final cluster 1 :\n"); // final clusters for(i=0;i<9;i++) System.out.print(cluster1[i]+ "\t"); System.out.println(); System.out.println("Final cluster 2 :\n"); for(i=0;i<9;i++) System.out.print(cluster2[i]+ "\t"); } } 

你有一堆错误:

  1. do循环开始时,你应该将sum1sum2重置为0。

  2. 在计算sum1sum2 (或者在do循环开始时清除cluster1cluster2 ,应分别循环到kj

  3. sum2的计算中,你不小心使用了sum1

当我进行这些修复时,代码运行正常,产生输出:

 Final cluster 1 : 2 4 10 12 3 11 0 0 0 Final cluster 2 : 20 30 25 0 0 0 0 0 0 

我的一般建议:学习如何使用调试器。 Stackoverflow不适用于这样的问题:预计您可以找到自己的错误,只有在其他一切都失败时才会来到这里…

唯一可能的无限循环是do-while。

 if(m1==a && m2==b) flag=false; else flag=true; 

如果flag为true,则只退出循环。 在这里断开if语句并查看为什么它永远不会被设置为false。 也许添加一些调试打印语句。

 public class KMeansClustering { public static void main(String args[]) { int arr[] = {2, 4, 10, 12, 3, 20, 30, 11, 25}; // initial data int i, m1, m2, a, b, n = 0; boolean flag; float sum1, sum2; a = arr[0]; b = arr[1]; m1 = a; m2 = b; int cluster1[] = new int[arr.length], cluster2[] = new int[arr.length]; do { sum1 = 0; sum2 = 0; cluster1 = new int[arr.length]; cluster2 = new int[arr.length]; n++; int k = 0, j = 0; for (i = 0; i < arr.length; i++) { if (Math.abs(arr[i] - m1) <= Math.abs(arr[i] - m2)) { cluster1[k] = arr[i]; k++; } else { cluster2[j] = arr[i]; j++; } } System.out.println(); for (i = 0; i < k; i++) { sum1 = sum1 + cluster1[i]; } for (i = 0; i < j; i++) { sum2 = sum2 + cluster2[i]; } //printing Centroids/Means\ System.out.println("m1=" + m1 + " m2=" + m2); a = m1; b = m2; m1 = Math.round(sum1 / k); m2 = Math.round(sum2 / j); flag = !(m1 == a && m2 == b); System.out.println("After iteration " + n + " , cluster 1 :\n"); //printing the clusters of each iteration for (i = 0; i < cluster1.length; i++) { System.out.print(cluster1[i] + "\t"); } System.out.println("\n"); System.out.println("After iteration " + n + " , cluster 2 :\n"); for (i = 0; i < cluster2.length; i++) { System.out.print(cluster2[i] + "\t"); } } while (flag); System.out.println("Final cluster 1 :\n"); // final clusters for (i = 0; i < cluster1.length; i++) { System.out.print(cluster1[i] + "\t"); } System.out.println(); System.out.println("Final cluster 2 :\n"); for (i = 0; i < cluster2.length; i++) { System.out.print(cluster2[i] + "\t"); } } 

}

这是工作代码。

 package k; /** * * @author Anooj.k.varghese */ import java.io.FileNotFoundException; import java.io.File; import java.util.Scanner; public class K { /** * @param args the command line arguments */ //GLOBAL VARIABLES //data_set[][] -------------datast is stored in the data_set[][] array //initial_centroid[][]------according to k'th value we select initaly k centroid.stored in the initial_centroid[][] // value is assigned in the 'first_itration()' function private static double[][] arr; static int num = 0; static Double data_set[][]=new Double[20000][100]; static Double diff[][]=new Double[20000][100]; static Double intial_centroid[][]=new Double[300][400]; static Double center_mean[][]=new Double[20000][100]; static Double total_mean[]=new Double[200000]; static int cnum; static int it=1; static int checker=1; static int row=4;//rows in Your DataSet here i use iris dataset /////////////////////////////////reading the file///////////////////////////////////// // discriptin readFile readthe txt file private static void readFile() throws FileNotFoundException { Scanner scanner = new Scanner(new File("E:/aa.txt"));//Dataset path scanner.useDelimiter(System.getProperty("line.separator")); int lineNo = 0; while (scanner.hasNext()) { parseLine(scanner.next(),lineNo); lineNo++; System.out.println(); } // System.out.println("total"+num); PRINT THE TOTAL scanner.close(); } //read file is copey to the data_set public static void parseLine(String line,int lineNo) { Scanner lineScanner = new Scanner(line); lineScanner.useDelimiter(","); for(int col=0;col=diff[i][j]) //change { aaa=diff[i][j]; counter=j; // System.out.println(counter); } } if(it%2==0) { // abbb=4; data_set[i][row+1]=counter; } else if(it%2==1) { data_set[i][row]=counter; // abbb=4; } //System.out.println("--"); } System.out.println(it+" ITRATION**"); for(int i=0;i