它们分别式j为类中样本的均值:mj误差平方可以用来代表C个类。C均值聚类实验报告、c均值聚类的算法原理聚类分析是指事先不知样本的类别,而利用样本的先验知识来构造分类器无监督学习)聚类准则函数在样本相似性度量的基础上,聚类分析还需要一定的准则函数,才能把真正属于同一类的样本聚合成一个类的子集,而把不同类的样本分离开来。如果聚类准则函数选得好,聚类质量就会高。同时,聚类准则函数还可以用来评价一种聚类结果的质量,如果聚类质量不满足要求,就要重复执行聚类过程,以优化结果。在重复优化中,可以改变相似性度量,也可以选用新的聚类准则。误差平方和准则(最常用的)假定有混合样本集X={X1,X2‘…'xn},采用某种相似性度量X被聚合成C个分离开的子集X1,X2,…,Xc,每个子集是一个类,含n1,n2,,nc个样本。为了衡量聚类的质量,采用误差平方和聚类准则函数Jc艺》"IIx-mII2kjm=丄为xj=1,2,•…,cjnjjj是c个子集合的中心,J聚类准则函数是样本与集合中心的函数。在样本集X给定的c情况下,其取值取决于c个集合“中心”。它描述n个试验样本聚合成c个类时,所产生的总误差平方和J越小越好。c误差平方和准则适用于各类样本比较密集且样本数目悬殊不大的样本分布。C-均值聚类算法的核心思想是通过迭代把数据对象划分到不同的簇中,以求目标数最小化,从而使生成的簇尽可能地紧凑和独立。首先,随机选取k个对象作为初始的k个簇的质心;然后,将其余对象根据其与各个簇质心的距离分配到最近的簇;再求新形成的簇的质心。J(2)-工ILIIx(i)-Z(2)112cki这个迭代重定位过程不断重复,直到目标函数最小化为止。c—均值聚类算法使用的聚类准则函数是误差平方和准则J:c为了使聚类结果优化,应该使准则Jc最小化。c二、C均值聚类的实现步骤C—均值算法步骤:①给出n个混合样本,令1=1,表示迭代运算次数,选取c个初始聚合中Z(1),j二1,2,...,c;j②计算每个样本与聚合中心的距离:D(x,Z(I)),k=1,2,...,n;j=1,2,...,c.kj若D(x,Z(I))二min{D(x,Z(I)),k=1,2,...,n},kij-12ckjJ—丄,2,...,c则xkwy;③令I—1+1=2计算新的集合中心:Z⑵—一艺x(j),j—匕2'…,c;II12,jnk计算误差平方和丿值:jk=1c④对每个聚合中的每个样本,计算:nP—iIIx(i)—Z(I)I|2,i—1,2,...ciin—1kiiP..表示J减少的部分。iicnP—j—IIx(i)—Z(I)II2,j—1,2,...c,j丰iijn+1kjp..表示J增加的部分:P7—mintp,.}ijc”闻j若p7Vp..,则把样本x(i)移到聚合中心3/中,并修改聚合中心和J值。iliiklc1Z(I+1)—Z(I)+[Z(I)—x(i)]iin—1iki1Z(I+1)—Z(I)+[Z(I)—x(i)]J(I+1)—J(I)-碍p)kcciiil⑤判断:若Jc(I+1)#include#include#include#include#includeusingnamespacestd;doubledistance(doublea[4],doubleb[4]){//TODO:改马氏距离doubled0=a[0]-b[0];doubled1=a[1]-b[1];doubled2=a[2]-b[2];doubled3=a[3]-b[3];returnsqrt(d0*d0+d1*d1+d2*d2+d3*d3);}intmain(){//读取数据doubledata[150][4];ifstreamf("data.txt");for(inti=0;i<150;i++)f>>data[i][0]>>data[i][1]>>data[i][2]>>data[i][3];f.close();//归一化doublem[4]={DBL_MAX,DBL_MAX,DBL_MAX,DBL_MAX};doubleM[4]={-DBL_MAX,-DBL_MAX,-DBL_MAX,-DBL_MAX};for(i=0;i<150;i++)for(intj=0;j<4;j++){if(data[i][j]M[j])M[j]=data[i][j];}for(i=0;i<150;i++)for(intj=0;j<4;j++)data[i][j]=(data[i][j]-m[j])/(M[j]-m[j]);//打乱//TODO:使用随机排序intrightLabels[150];for(i=0;i<50;i++)rightLabels[i]=0;for(i=50;i<100;i++)rightLabels[i]=1;for(i=100;i<150;i++)rightLabels[i]=2;srand(time(NULL));for(i=0;i<150;i++){intj=rand()%150;doubletmp;tmp=data[i][0];data[i][0]=data[j][0];data[j][0]=tmp;tmp=data[i][1];data[i][1]=data[j][1];data[j][1]=tmp;tmp=data[i][2];data[i][2]=data[j][2];data[j][2]=tmp;tmp=data[i][3];data[i][3]=data[j][3];data[j][3]=tmp;inttmp2;tmp2=rightLabels[i];right...