5

我正在尝试用 Java 编写一个 k-means 算法。我计算了许多数组,每个数组都包含许多系数。我需要使用 k-means 算法来对所有这些数据进行分组。你知道这个算法的任何实现吗?

谢谢

4

8 回答 8

5

我自己没有研究过代码,但是这篇 JavaWorld 文章中给出了一个多线程的 K-means 实现,看起来很有启发性。

于 2009-06-28T21:29:27.910 回答
4

OpenCV 是我用过的最糟糕的库之一。另一方面,Matlab 做得非常巧妙。

如果您必须自己编写代码,那么该算法的效率非常简单。

  1. 选择簇数 (k)
  2. 制作 k 点(它们将成为质心)
  3. 随机化所有这些点的位置
  4. 计算每个点到所有质心的欧几里得距离
  5. 将每个点的“成员资格”分配给最近的质心
  6. 通过平均属于给定集群的所有点的位置来建立新的质心
  7. Goto 4 直到达到收敛,或所做的更改无关紧要。
于 2009-06-30T19:38:44.460 回答
4

分类、聚类和分组是 IR 发展良好的领域。这里有一个非常好的(Java)库/软件(开源)叫做 WEKA。那里有几种聚类算法。虽然有一个学习曲线,但当您遇到更难的问题时它可能会很有用。

于 2009-06-28T22:04:21.363 回答
3

真的,KMeans 是一个非常简单的算法。为什么不自己手动编码有什么好的理由吗?我是在 Qt 中完成的,然后将代码移植到普通的旧 STL,没有太多问题。

我开始喜欢 Joel 的想法:没有外部依赖,所以请随时告诉我你无法控制的大型软件有什么好处,其他人在这个问题上已经提到它不是一个好软件软件/

说话便宜,真男人向世界展示他们的代码:http: //github.com/elcuco/data_mining_demo

我应该稍微清理一下代码以使其更通用,并且当前版本未移植到 STL,但这是一个开始!

于 2009-06-30T19:44:07.400 回答
3

在"Programming Collective Intelligence"中有一个非常好的 K-means 聚类 Python 实现。我强烈推荐它。

我意识到你必须翻译成 Java,但这看起来并不难。

于 2009-06-28T21:25:21.473 回答
2

非常老的问题,但我注意到没有提到Java 机器学习库,它实现了K-Means,并包含一些关于它的使用的文档。

该项目不是很活跃,但最后一个版本相对较新(2012 年 7 月)

于 2012-11-22T07:00:43.617 回答
1

似乎每个发帖的人都忘了提到事实上的图像处理库:OpenCV http://sourceforge.net/projects/opencvlibrary/。您必须围绕 C OpenCV 代码编写一个 JNI 包装器才能使 KMeans 工作,但额外的好处是

  1. 您会知道 KMeans 算法已经过高度优化
  2. OpenCV 广泛使用您的 GPU,因此运行速度极快

主要缺点是您必须编写 JNI 包装器。我曾经需要一个模板匹配例程并且面临许多替代方案,但我发现 OpenCV 是迄今为止最好的,即使我被迫为它编写一个 JNI 包装器。

于 2009-06-29T20:14:24.240 回答
0
//Aim:To implement Kmeans clustering algorithm.
//Program
import java.util.*;
class k_means
{
static int count1,count2,count3;
static int d[];
static int k[][];
static int tempk[][];
static double m[];
static double diff[];
static int n,p;

static int cal_diff(int a) // This method will determine the cluster in which an element go at a particular step.
{
int temp1=0;
for(int i=0;i<p;++i)
{
if(a>m[i])
diff[i]=a-m[i];
else
diff[i]=m[i]-a;
}
int val=0;
double temp=diff[0];
for(int i=0;i<p;++i)
{
if(diff[i]<temp)
{
temp=diff[i];
val=i;
}
}//end of for loop
return val;
}

static void cal_mean() // This method will determine intermediate mean values
{
for(int i=0;i<p;++i)
m[i]=0; // initializing means to 0
int cnt=0;
for(int i=0;i<p;++i)
{
cnt=0;
for(int j=0;j<n-1;++j)
{
if(k[i][j]!=-1)
{
m[i]+=k[i][j];
++cnt;
}}
m[i]=m[i]/cnt;
}
}

static int check1() // This checks if previous k ie. tempk and current k are same.Used as terminating case.
{
for(int i=0;i<p;++i)
for(int j=0;j<n;++j)
if(tempk[i][j]!=k[i][j])
{
return 0;
}
return 1;
}

public static void main(String args[])
{
Scanner scr=new Scanner(System.in);
/* Accepting number of elements */
System.out.println("Enter the number of elements ");
n=scr.nextInt();
d=new int[n];
/* Accepting elements */
System.out.println("Enter "+n+" elements: ");
for(int i=0;i<n;++i)
d[i]=scr.nextInt();
/* Accepting num of clusters */
System.out.println("Enter the number of clusters: ");
p=scr.nextInt();
/* Initialising arrays */
k=new int[p][n];
tempk=new int[p][n];
m=new double[p];
diff=new double[p];
/* Initializing m */
for(int i=0;i<p;++i)
m[i]=d[i];

int temp=0;
int flag=0;
do
{
for(int i=0;i<p;++i)
for(int j=0;j<n;++j)
{
k[i][j]=-1;
}
for(int i=0;i<n;++i) // for loop will cal cal_diff(int) for every element.
{
temp=cal_diff(d[i]);
if(temp==0)
k[temp][count1++]=d[i];
else
if(temp==1)
k[temp][count2++]=d[i];
else
if(temp==2)
k[temp][count3++]=d[i]; 
}
cal_mean(); // call to method which will calculate mean at this step.
flag=check1(); // check if terminating condition is satisfied.
if(flag!=1)
/*Take backup of k in tempk so that you can check for equivalence in next step*/
for(int i=0;i<p;++i)
for(int j=0;j<n;++j)
tempk[i][j]=k[i][j];

System.out.println("\n\nAt this step");
System.out.println("\nValue of clusters");
for(int i=0;i<p;++i)
{
System.out.print("K"+(i+1)+"{ ");
for(int j=0;k[i][j]!=-1 && j<n-1;++j)
System.out.print(k[i][j]+" ");
System.out.println("}");
}//end of for loop
System.out.println("\nValue of m ");
for(int i=0;i<p;++i)
System.out.print("m"+(i+1)+"="+m[i]+"  ");

count1=0;count2=0;count3=0;
}
while(flag==0);

System.out.println("\n\n\nThe Final Clusters By Kmeans are as follows: ");
for(int i=0;i<p;++i)
{
System.out.print("K"+(i+1)+"{ ");
for(int j=0;k[i][j]!=-1 && j<n-1;++j)
System.out.print(k[i][j]+" ");
System.out.println("}");
}
}
}
/*
Enter the number of elements
8
Enter 8 elements:
2 3 6 8 12 15 18 22
Enter the number of clusters:
3

At this step
Value of clusters
K1{ 2 }
K2{ 3 }
K3{ 6 8 12 15 18 22 }
Value of m
m1=2.0  m2=3.0  m3=13.5

At this step
Value of clusters
K1{ 2 }
K2{ 3 6 8 }
K3{ 12 15 18 22 }
Value of m
m1=2.0  m2=5.666666666666667  m3=16.75

At this step
Value of clusters
K1{ 2 3 }
K2{ 6 8 }
K3{ 12 15 18 22 }
Value of m
m1=2.5  m2=7.0  m3=16.75

At this step
Value of clusters
K1{ 2 3 }
K2{ 6 8 }
K3{ 12 15 18 22 }
Value of m
m1=2.5  m2=7.0  m3=16.75

The Final Clusters By Kmeans are as follows:
K1{ 2 3 }
K2{ 6 8 }
K3{ 12 15 18 22 } */
于 2013-11-22T06:02:39.090 回答