K-均值聚类算法及其初始点的选取
来源:互联网 发布:电梯破解软件 编辑:程序博客网 时间:2024/05/16 01:14
K-均值聚类(K-Means Clustering)是一种无监督的聚类方法,即最初并不知道同种类数据的特征,算法会根据数据自身特点进行分类。
算法流程如下:
1 . 选取k个初始中心点,选取方法根据具体数据特点决定,可以是随机;
2 . 遍历数据集,找到离每个数据最近的中心点,并将其归入该点;
3 . 更新中心点位置:求出归入每个中心点的数据的均值,将其更新为新的中心点;
4 . 如果中心点更新量小于某个阈值,或者算法执行到一定次数,结束程序;否则,执行步骤2。
在算法中,k是需要提前约定的,它代表期望的种类数。但有时会不确定数据的种类数目,这种情况可以多次尝试使用不同的k值进行聚类,并选取其中最符合的(参考:http://blog.csdn.net/shennongzhaizhu/article/details/51871891)
另外一个是初始点的选取。初始点的选取与数据具体特征有关,如果数据分布较密集,且相对于选定的k值比较符合,这时如果使用随机选点就可能造成空簇,而某两类本应该被分开的数据聚合到一个类中。这种情况,需要选定其初始互相较远的k个点作为初始点。
一个实例如下:
//pts_src为原数据,data为聚类得到需要输出的中心点数据 void kmean_cluster(int k = 3){ //初始化中心点(应选取相互距离较远的三个点) vector<Point3d> ks(3,Point3d()); Point3d pt_evg; ks[0] = pts_src[0]; double max_dis = 0; int max_i = 0; for (int i = 1; i < pts_src.size(); i++){ double dis = P3d_distance(ks[0], pts_src[i]); if (dis > max_dis){ max_dis = dis; max_i = i; } } ks[1] = pts_src[max_i]; max_dis = 0; for (int i = 1; i < pts_src.size(); i++){ double dis = P3d_distance(ks[0], pts_src[i]) + P3d_distance(ks[1], pts_src[i]); if (dis > max_dis){ max_dis = dis; max_i = i; } } ks[2] = pts_src[max_i]; int n = 100; bool over_flag = false; //--------- while (n--){ vector<set<int>> sets(k, set<int>());//集合初始化 for (int i = 0; i < pts_src.size(); i++){ double min = 1000; int min_j = 0; for (int j = 0; j < k; j++){ double dist = P3d_distance(ks[j], pts_src[i]); if (dist < min){ min = dist; min_j = j; } } sets[min_j].insert(i); if (over_flag){ save_card(min_j, i, pic_src[i]); //imshow(num2str(min_j), pic_src[i]); //waitKey(0); } } if (over_flag){ cout << "输入角色对应集合的顺序:0 1 2" << endl; for (int i = 0; i < k; i++){ int temp; cin >> temp; pos.push_back(temp); } data = ks; save_data(); cout << "数据已存储" << endl; break; } //重新分配中心点 int i = 0; int sim_count = 0; for (auto&s : sets){ Point3d pt_evg; for (auto&i : s){ Point3d pt = pts_src[i]; pt_evg.x += pt.x; pt_evg.y += pt.y; pt_evg.z += pt.z; } if (s.size()){ pt_evg.x /= s.size(); pt_evg.y /= s.size(); pt_evg.z /= s.size(); } if (P3d_distance(pt_evg, ks[i]) < 0.01)sim_count++; ks[i++] = pt_evg; } if (sim_count == k)over_flag = true; // } }
这是从最近正在做的一个程序中截取的部分代码,作用是将得到的15张图片根据rgb值分类。因为其类型数目是已知的,k= 3。且其各个特征较为明显,只是存在噪声干扰。
最初使用随机选取点,聚类结果如下:
文件第一个数字为集合标识。可以看出,虽然准确将地分成了两类(分类没有出错),但是没有达到想要的目标:分成三类,因为存在一个空簇。
后来使用找出互相较远的点的方法,其流程如下:
1 . 随机选取一个数据点,作为第一个中心
2 . 找出离这个数据点最远的一个点,作为第二个中心
3 . 找出离这两个数据点之和最远的一个点,作为第三个中心
再往更高的k推广的话,这个算法的初始点选择又会影响,但是对于这里的三个数据点是比较好用的。
其聚类结果如下:
参考资料:
http://blog.csdn.net/rex_huang61/article/details/51051839
《集体智慧编程》42~44
- K-均值聚类算法及其初始点的选取
- k-means初始点的选取
- 创建正态分布的点并用k均值算法聚类
- KMeans算法的K值以及初始类簇中心点的选取
- k-均值算法及其实现
- 第十章 k-均值算法 10.4 对地图上的点进行聚类
- K-均值聚类算法
- K均值聚类算法
- K-均值聚类算法
- 聚类算法:K均值
- K-均值聚类算法
- K-均值聚类算法
- k均值聚类算法
- k均值聚类算法
- K-均值聚类算法
- k均值聚类算法
- K-均值聚类算法
- isodata算法确定k均值聚类的k值
- 三步开启win10的ubuntu子系统
- DP---最长公共子序列&最长公共字串
- View 浮在软键盘上多种实现方式及踩坑
- JAVA算法(一) -- 经典回文数(取出任意范围的回文数)
- kafka-02-集群搭建
- K-均值聚类算法及其初始点的选取
- NVIC的初识
- [BZOJ1910][CTSC2002]颁奖典礼 DP
- Miller-Rabin素数测试
- 捕捉信号的总结
- POJ2892Tunnel Warfare
- Activity之间传递数据
- web项目部署到阿里云服务器
- codeforces 797e Array Queries 部分dp+暴力