K-均值算法
动态聚类方法是模式识别中一种普遍采用的方法,它具有以下3个要点: 1:选定某种距离度量作为样本间的相似性度量 2:确定某个评价聚类结果质量的准则函数 3:给定某个初始分类,然后用迭代算法找出使准则函数取极值的最好的聚类结果K-MEANS算法:输入:聚类个数k,以及包含 n个数据对象的数据库。输出:满足方差最小标准的k个聚类。处理流程:(1) 从
动态聚类方法是模式识别中一种普遍采用的方法,它具有以下3个要点:
1:选定某种距离度量作为样本间的相似性度量
2:确定某个评价聚类结果质量的准则函数
3:给定某个初始分类,然后用迭代算法找出使准则函数取极值的最好的聚类结果
K-MEANS算法:
输入:聚类个数k,以及包含 n个数据对象的数据库。
输出:满足方差最小标准的k个聚类。
处理流程:
(1) 从 n个数据对象任意选择 k 个对象作为初始聚类中心;
(2) 循环(3)到(4)直到每个聚类不再发生变化为止;
(3) 根据每个聚类对象的均值(中心对象),计算每个对象与这些中心对象的距离;并根据最小距离重新对相应对象进行划分;
(4) 重新计算每个(有变化)聚类的均值(中心对象)
k-means 算法接受输入量 k ;然后将n个数据对象划分为 k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度较高;而不同聚类中的对象相似度较小。聚类相似度是利用各聚类中对象的均值所获得一个“中心对象”(引力中心)来进行计算的。
k-means 算法的工作过程说明如下:首先从n个数据对象任意选择 k 个对象作为初始聚类中心;而对于所剩下其它对象,则根据它们与这些聚类中心的相似度(距离),分别将它们分配给与其最相似的(聚类中心所代表的)聚类;然后再计算每个所获新聚类的聚类中心(该聚类中所有对象的均值);不断重复这一过程直到标准测度函数开始收敛为止。一般都采用均方差作为标准测度函数. k个聚类具有以下特点:各聚类本身尽可能的紧凑,而各聚类之间尽可能的分开。 */
/* K-均值算法*/
/*VC++6.0下编译通过*/
#include<stdio.h>
#include<math.h>
void main()
{
char test='q';
int i,j,sn1=0,sn2=0,n=0;
float z1x,z1y,z2x,z2y,z1x_l,z1y_l,z2x_l,z2y_l;
float X[100][2],S1[100][2],S2[100][2];
/****************************数据输入******************************************/
while(test!=27)
{
printf("Please input the numble of the data:");
scanf("%d",&n);
printf("Please input data/n");
for(i=0;i<n;i++)
{
for(j=0;j<2;j++)
{
if(j==0)
{
printf("X[%d]x=",i+1);
scanf("%f",&X[i][j]);
}
else
{
printf("X[%d]y=",i+1);
scanf("%f",&X[i][j]);
}
}
}
/*
printf("Please input K/n");
scanf("%d",&K);
*/
/*******************************算法过程***************************************/
z1x=z1x_l=X[0][0];//初始化聚类中心
z1y=z1y_l=X[0][1];
z2x=z2x_l=X[1][0];
z2y=z2y_l=X[1][1];
/********************迭代开始*********************/
again:
/*************计算数据点分类**************/
sn1=0;
sn2=0;
for(i=0;i<n;i++)
{
if(((X[i][0]-z1x)*(X[i][0]-z1x)+(X[i][1]-z1y)*(X[i][1]-z1y))<((X[i][0]-z2x)*(X[i][0]-z2x)+(X[i][1]-z2y)*(X[i][1]-z2y)))//判断数据所属
{
S1[sn1][0]=X[i][0];
S1[sn1][1]=X[i][1];
sn1++;
}
else
{
S2[sn2][0]=X[i][0];
S2[sn2][1]=X[i][1];
sn2++;
}
}
/*************计算聚类中心**************/
z1x=0;
z1y=0;
for(i=0;i<sn1;i++)
{
z1x=(S1[i][0]+z1x);
z1y=(S1[i][1]+z1y);
}
z1x=z1x/(sn1);
z1y=z1y/(sn1);
z2x=0;
z2y=0;
for(i=0;i<sn2;i++)
{
z2x=(S2[i][0]+z2x);
z2y=(S2[i][1]+z2y);
}
z2x=z2x/(sn2);
z2y=z2y/(sn2);
/*************判断聚类中心**************/
if((z1x!=z1x_l)||(z1y!=z1y_l)||(z2x!=z2x_l)||(z2y!=z2y_l))
{
z1x_l=z1x;
z1y_l=z1y;
z2x_l=z2x;
z2y_l=z2y;
goto again;//有时候goto还是很好用的,这里判断迭代得出的聚类中心的值是否与上次相同,不同继续迭代
}
/*******************************打印结果***************************************/
printf("%f,%f,%f,%f/nRress Esc to close/nRress any key to continue/n ",z1x,z1y,z2x,z2y);
test=getch(); //按ESC退出
}//回while
}
更多推荐
所有评论(0)