《K均值聚类算法加源码(共8页).doc》由会员分享,可在线阅读,更多相关《K均值聚类算法加源码(共8页).doc(8页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、精选优质文档-倾情为你奉上模式识别导论K均值聚类算法实验报告一 实验功能本实验功能与目的是实现K均值聚类算法,将“Iris.txt”文件中的数据用K均值聚类的方法分为三类。分类结果用该数据的数据编号表示。二 子函数列表参数说明程序中使用到了三个子函数1. void fileop(category *p)/文件打开读入结构体函数函数功能:将Iris.txt文件打开,把数据从文件中读出存入定义的结构体,每个向量的分量存入结构体的对应元素中,取值结束后将文件关闭函数参数:已定义的结构体category,结构体定义如下 struct category/待聚类数据结构体int label;/标号floa
2、t x1;/四个分量float x2;float x3;float x4;2. float min(float x,float y,float z)/最小值函数函数功能:求三个数的最小值并返回最小值数据函数参数:三个单精度浮点型数据3. void K_averange(category *p,category a,category b,category c)/k均值聚类函数函数功能:实现K均值聚类算法函数参数:已定义的待聚类结构体,定义同上。聚类中心结构体a,b,c。存放每次迭代的聚类中心,初始聚类中心为文件中的前三个数据三 程序流程图输出结果结束聚类中心是否改变Y Y开始打开文件是否成功聚类
3、选择初始聚类中心修改聚类中心N Y N四 程序源代码#include#includeusing namespace std;#define MAX 151/定义数据个数int COUNT=1;/记录迭代次数int a1MAX;/存放第i类的标号(i=1,2,3)int a2MAX;int a3MAX;int b1;/记录第i类元素的个数(i=1,2,3)int b2;int b3;struct category/待聚类数据结构体int label;/标号float x1;/四个分量float x2;float x3;float x4;void fileop(category *p)/文件打开读
4、入结构体函数int i;fstream dataFile;dataFile.open(Iris.txt,ios:in);if(dataFile.fail()cout打开文件失败endl;exit(0);while(!dataFile.eof()for(i=1;ipi.x1;dataFilepi.x2;dataFilepi.x3;dataFilepi.x4;dataFile.close();float min(float x,float y,float z)/最小值函数if(xy&xz)return x;else if(yx&yz)return y;else if(zx&zy)return z;
5、void K_averange(category *p,category a,category b,category c)/k均值聚类函数struct category com1,com2,com3;/用来比较聚类中心是否改变struct category sum1,sum2,sum3;/求各类各分量的和进而计算新的聚类中心com1=a;com2=b;com3=c;sum1.x1=sum1.x2=sum1.x3=sum1.x4=0;sum2.x1=sum2.x2=sum2.x3=sum2.x4=0;sum3.x1=sum3.x2=sum3.x3=sum3.x4=0;int i;for(i=1;
6、iMAX;i+)a1i=0;a2i=0;a3i=0;float f3;float flag;b1=0;b2=0;b3=0;for(i=1;iMAX;i+)f0=(pi.x1-a.x1)*(pi.x1-a.x1)+(pi.x2-a.x2)*(pi.x2-a.x2)+(pi.x3-a.x3)*(pi.x3-a.x3)+(pi.x4-a.x4)*(pi.x4-a.x4);f1=(pi.x1-b.x1)*(pi.x1-b.x1)+(pi.x2-b.x2)*(pi.x2-b.x2)+(pi.x3-b.x3)*(pi.x3-b.x3)+(pi.x4-b.x4)*(pi.x4-b.x4);f2=(pi.x1
7、-c.x1)*(pi.x1-c.x1)+(pi.x2-c.x2)*(pi.x2-c.x2)+(pi.x3-c.x3)*(pi.x3-c.x3)+(pi.x4-c.x4)*(pi.x4-c.x4);/计算到三个聚类中心的距离值flag=min(f0,f1,f2);/取最小值if(f0=flag)a1b1+=pi.label;sum1.x1+=pi.x1;sum1.x2+=pi.x2;sum1.x3+=pi.x3;sum1.x4+=pi.x4;else if(f1=flag)a2b2+=pi.label;sum2.x1+=pi.x1;sum2.x2+=pi.x2;sum2.x3+=pi.x3;su
8、m2.x4+=pi.x4;else if(f2=flag)a3b3+=pi.label;sum3.x1+=pi.x1;sum3.x2+=pi.x2;sum3.x3+=pi.x3;sum3.x4+=pi.x4;/将每个元素加到距离最小值的类,并求和sum1.x1=sum1.x1/b1;sum1.x2=sum1.x2/b1;sum1.x3=sum1.x3/b1;sum1.x4=sum1.x4/b1;sum2.x1=sum2.x1/b2;sum2.x2=sum2.x2/b2;sum2.x3=sum2.x3/b2;sum2.x4=sum2.x4/b2;sum3.x1=sum3.x1/b3;sum3.x
9、2=sum3.x2/b3;sum3.x3=sum3.x3/b3;sum3.x4=sum3.x4/b3;/求平均值/测试代码/*for(j=0;jb1;j+)couta1jendl;cout*endl;for(j=0;jb2;j+)couta2jendl;cout*endl;for(j=0;jb3;j+)couta3jendl;cout*endl;coutb1endl;coutb2endl;coutb3endl;coutsum1.x1 sum1.x2 sum1.x3 sum1.x4endl;coutsum2.x1 sum2.x2 sum2.x3 sum2.x4endl;coutsum3.x1 s
10、um3.x2 sum3.x3 sum3.x4endl;*/a=sum1;b=sum2;c=sum3;/新的聚类中心if(a.x1!=com1.x1|a.x2!=com1.x2|a.x3!=com1.x3|a.x4!=com1.x4|b.x1!=com2.x1|b.x2!=com2.x2|b.x3!=com2.x3|b.x4!=com2.x4|c.x1!=com3.x1|c.x2!=com3.x2|c.x3!=com3.x3|c.x4!=com3.x4)K_averange(p,a,b,c);COUNT+;/如果聚类中心改变,递归调用k均值聚类函数,并增加迭代次数int main()int j;
11、cout已将文件的数据按行号编号endl;struct category *p=new categoryMAX;struct category a,b,c;fileop(p);/文件操作a=p1;b=p2;c=p3;/聚类中心初始值定义为前三个数据K_averange(p,a,b,c);/K均值聚类函数cout第一类分类结果为:endl;for(j=0;jb1;j+)couta1jendl;cout*endl;cout第二类分类结果为:endl;for(j=0;jb2;j+)couta2jendl;cout*endl;cout第三类分类结果为:endl;for(j=0;jb3;j+)couta
12、3jendl;cout共迭代COUNT次endl;/ 测试代码/coutb1 b2 b3endl;/for(i=1;iMAX;i+)/coutpi.label pi.x2endl;/coutendl;/couta.x1 a.x2 a.x3 a.x4endl;/coutb.x1 b.x2 b.x3 b.x4endl;/coutc.x1 c.x2 c.x3 c.x4endl;delete p;return 0;五 输出结果已将文件的数据按行号编号第一类分类结果为:51 53 78 101 103 104 105 106 108 109 110 111 112 113 116 117 118 119
13、 121 123 125 126 129 130 131 132 133 135 136 137 138 140 141 142 144 145 146 148 149*第二类分类结果为:52 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 102 107 114 115 120 122 124 127 128 134 139 143 147 150*第三类分类结果为
14、:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50共迭代11次Press any key to continue(注:程序输出时为一行一个数据,报告中为了节省页面,更加直观,故一行多个数据。报告中的数据结果和程序输出时的分类结果一致)六 算法分析通过实验程序输出可以看出,选取文件中起始的三个数据作为聚类中心将150个数据分类共需要迭代11次。此外,我采用随机产生起始
15、的聚类中心的方法下,迭代的次数出现了5次左右和12次左右的明显差异。从而我发现K-均值聚类算法的收敛性是和初值的选取有关。在实验中,程序中初始的聚类中心是1,2,3前三个数,而通过结果发现前三个数属于同一类,迭代的次数为11次。而将1,51,52分别属于三个类别的数据作为初始聚类中心,迭代次数为4次。由此可见,初始值选择同一类时K-均值算法的收敛速度较慢,初始值选择不同类别时K-均值算法的收敛速度较快。在起始不知道数据分类结果的情况下,初始聚类中心的选择是随机的。因此对于K-均值算法的收敛速度也是不确定的。但从随机选择数据做聚类中心的迭代次数可以看出,K-均值算法的收敛速度还是较慢的。时间复杂度也较高其次,在实验中我发现第51个数据在起始聚类中心不同的情况下,会被分为不同的类。从而起始聚类中心的选择与部分数据的分类也有很大关系。最后,在此次实验中,对于结构体的定义有一些不足,应将结构体中的分量定义成数组的形式。这样在比较聚类中心是否相同的条件判断中不用写那样长的判断条件了,直接用一个循环比较。这也是我的程序应该优化和提高的地方。专心-专注-专业