1、首先(shuxin),随机选取k个对象作为(zuwi)初始的k个簇的质心(zh xn);然后,将其余对象根据其与各个簇质心的距离分配(fnpi)到最近的簇;再求新形成的簇的质心。这个迭代重定位过程不断重复,直到(zhdo)目标函数最小化为止。C均值聚类算法使用的聚类准则函数是误差平方和准则 :为了使聚类结果优化,应该使准则 最小化。二、C均值聚类的实现步骤C均值算法步骤: 给出n个混合样本,令 ,表示迭代运算次数,选取c个初始聚合中心 计算每个样本与聚合中心的距离:若则令 计算新的集合中心:计算误差平方和 值: 对每个聚合中的每个样本,计算:表示 减少的部分 。表示 增加的部分:若 ,则把样本
2、 移到聚合中心 中,并修改聚合中心和 值。 判断(pndun):若 则 ,返回(fnhu)。否则(fuz),算法结束。三. 编写(binxi)的程序:#include iostreamiomanipfstreamctimecmathusing namespace std;double distance(double a4, double b4) / TODO: 改马氏距离(jl) double d0 = a0-b0; double d1 = a1-b1; double d2 = a2-b2; double d3 = a3-b3; return sqrt(d0*d0+d1*d1+d2*d2+d3
3、*d3);int main() / 读取数据 double data1504; ifstream f(data.txt); for(int i=0; idatai0datai1datai2datai3; f.close(); / 归一化 double m4 = DBL_MAX, DBL_MAX, DBL_MAX, DBL_MAX; double M4 = -DBL_MAX, -DBL_MAX, -DBL_MAX, -DBL_MAX; for(i=0; for(int j=0; j4; j+) if(dataijMj) Mj=dataij; dataij = (dataij-mj) / (Mj-
4、mj); / 打乱 使用(shyng)随机排序int rightLabels150;for(i=0;50;rightLabelsi = 0;for(i=50;100;rightLabelsi = 1;for(i=100;rightLabelsi = 2; srand(time(NULL); int j = rand()%150; double tmp; tmp = datai0; datai0 = dataj0; dataj0 = tmp; tmp = datai1; datai1 = dataj1; dataj1 = tmp; tmp = datai2; datai2 = dataj2; d
5、ataj2 = tmp; tmp = datai3; datai3 = dataj3; dataj3 = tmp;int tmp2;tmp2 = rightLabelsi;rightLabelsi = rightLabelsj;rightLabelsj = tmp2; / 分类(fn li) int labels150; double Z34 = data00, data01, data02, data03, data10, data11, data12, data13, data20, data21, data22, data23; int iterations = 0; while(tru
6、e)/ coutsetw(10)Z00Z01Z02Z03endl/ Z10Z11Z12Z13Z20Z21Z22Z23endl;/ cin.get(); iterations+; / 最小距离(j)分类 到label for(int i=0; double d0 = distance(Z0, datai); double d1 = distance(Z1, datai); double d2 = distance(Z2, datai); if(d0d1)&(d0d2) labelsi = 0; else if(d1d2) labelsi = 1; else labelsi = 2; / 计算均值
7、(jn zh)为新聚类中心 到Z double sum34 = 0.0; int count3 = 0; for(i=0; int label = labelsi; sumlabel0+=datai0; sumlabel1+=datai1; sumlabel2+=datai2; sumlabel3+=datai3; countlabel+; bool changed = false;3; for(int j=0; if(Zij != sumij / counti)/ 可以加入(jir)e比较 Zij = sumij / counti; changed = true; / 聚类中心(zhngxn
8、)没改变则退出 if(!changed) break; / 输出(shch) int count3 = 0; coutdatai0tdatai1datai2datai3labelsi(char)(rightLabelsi+A) countlabelsi+; cout iterations: iterationslabel0 count:count0label1 count:count1label2 count:count2 cin.get(); return 0;四.运行(ynxng)结果:0.1666670.3898310.375B0.1388890.4166670.0677971A0.4722220.0833330.6779660.583333C0.3333330.7796610.87520.250.0847460.1944440.4237290.0416670.50.6271190.5416670.2916670.5254240.750.4583330.1016950.4915250.333
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1