由于个人理解有限,难免有错误之处,欢迎指正。

k-means 聚类算法原理:

1、从包含多个数据点的数据集 D 中随机取 k 个点,作为 k 个簇的各自的中心。

2、分别计算剩下的点到 k 个簇中心的相异度,将这些元素分别划归到相异度最低的簇。两个点之间的相异度大小采用欧氏距离公式衡量,对于两个点 T0(x1,y2)和 T1(x2,y2),T0 和 T1 之间的欧氏距离为:

欧氏距离越小,说明相异度越小

3、根据聚类结果,重新计算 k 个簇各自的中心,计算方法是取簇中所有点各自维度的算术平均数。

4、将 D 中全部点按照新的中心重新聚类。

5、重复第 4 步,直到聚类结果不再变化。

6、将结果输出。

举例说明, 假设包含 9 个点数据 D 如下(见 simple_k-means.txt), 从 D 中随机取 k 个元素,作为 k 个簇的各自的中心, 假设选 k=2, 即将如下的 9 个点聚类成两个类(cluster)

  1.假设选 C0(1 1)和 C1(2 1)前两个点作为两个类的簇心。
  2. 分别计算剩下的点到 k 个簇中心的相异度,将这些元素分别划归到相异度最低的簇。结果为:
  3.根据 2 的聚类结果,重新计算 k 个簇各自的中心,计算方法是取簇中所有元素各自维度的算术平均数。
C0 新的簇心为: 1.0,1.5
C1 新的簇心为: 5.857142857142857, 5.714285714285714
  4.将 D 中全部元素按照新的中心重新聚类。
  5.重复第 4 步,直到聚类结果不再变化。当每个簇心点前后移动的距离小于某个阈值t的时候,就认为聚类已经结束了,不需要再迭代,这里的值选t=0.001,距离计算采用欧氏距离。
C0 的簇心为: 1.6666666666666667, 1.75
C1 的簇心为: 7.971428571428572, 7.942857142857143
C0 的簇心为: 1.777777777777778, 1.7916666666666667
C1 的簇心为: 8.394285714285715, 8.388571428571428

C0 的簇心为: 1.7962962962962965, 1.7986111111111114

C1 的簇心为: 8.478857142857143, 8.477714285714285
C0 的簇心为: 1.799382716049383, 1.7997685185185184
C1 的簇心为: 8.495771428571429, 8.495542857142857

C0 的簇心为: 1.7998971193415638, 1.7999614197530864

C1 的簇心为: 8.499154285714287, 8.499108571428572
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <vector>
#include <cmath>using namespace std;class Cluster//聚类,每个聚类都包含两个属性,一个是簇心的属性(维数),另一个是距离本簇心最近的样本点
{
public:vector <double> centroid;//存放簇心的属性(维数)vector <int> samples;//存放属于相同簇心样本的下标
};double CalculateDistance(vector<double> a, vector<double> b)//计算两个向量之间的距离
{int len1 = a.size();int len2 = b.size();if(len1 != len2)cerr<<"Dimensions of two vectors must be same!!\n";double temp = 0;for(int i = 0; i  < len1; ++i)temp += pow(a[i]-b[i], 2);return sqrt(temp);
}//max_iteration表示最大的迭代次数,min_move_distance
vector<Cluster> KMeans(vector<vector<double> >data_set, int k, int max_iteration, double threshold)
{int row_number = data_set.size();//数据的个数int col_number = data_set[0].size();//每个向量(属性)的维数//初始随机选取k个质心vector<Cluster> cluster(k);//存放k个簇心。vector<T> v(n,i)形式,v包含n 个值为 i 的元素srand((int)time(0));for(int i = 0; i < k; ++i){int c = rand()%row_number;cluster[i].centroid = data_set[c];//把第c个作为簇心,并把它相应的属性赋值给centroid}//iterationint iter = 0;while(iter < max_iteration){iter++;for(int i = 0; i < k; ++i)cluster[i].samples.clear();//找出每个样本点所属的质心for(int i = 0; i < row_number; ++i){double min_distance = INT_MAX;int index = 0;//计算离样本点i最近的质心for(int j = 0; j < k; ++j){double temp_distance = CalculateDistance(data_set[i], cluster[j].centroid);if(min_distance > temp_distance){min_distance = temp_distance;index = j;}}cluster[index].samples.push_back(i);//把第i个样本点放入,距离其最近的质心的samples}double max_move_distance = INT_MIN;//更新簇心for(int i = 0; i < k; ++i){vector<double> temp_value(col_number, 0.0);for(int num = 0; num < cluster[i].samples.size(); ++num)//计算每个样本的属性之和{int temp_same = cluster[i].samples[num];for(int j = 0; j < col_number; ++j)temp_value[j] += data_set[temp_same][j];}vector<double> temp_centroid = cluster[i].centroid;for(int j = 0; j < col_number; ++j)cluster[i].centroid[j] = temp_value[j]/cluster[i].samples.size();//计算从上一个簇心移动到当前新的簇心的距离double temp_distance = CalculateDistance(temp_centroid, cluster[i].centroid);if(max_move_distance < temp_distance)max_move_distance = temp_distance;}if(max_move_distance < threshold)break;}return cluster;
}int main()
{int threshold = 0.001;//当从上一个簇心移动到当前粗心的距离几乎不变时,可以结束。这里用threshold作为阈值vector <vector<double> >data_set(9, vector<double>(2, 0.0));int point_number;cin>>point_number;for(int i = 0; i < point_number; ++i){for(int j = 0; j < 2; ++j)cin>>data_set[i][j];}int col = data_set[0].size();vector<Cluster> cluster_res = KMeans(data_set, 2, 200, threshold);for(int i = 0; i < cluster_res.size(); ++i){cout<<"Cluster "<<i<<" : "<<endl;cout<<"\t"<<"Centroid: ";//<<endl;cout<<"(";for(int j = 0; j < cluster_res[i].centroid.size()-1; ++j)cout<< cluster_res[i].centroid[j]<<",";cout<<cluster_res[i].centroid[cluster_res[i].centroid.size()-1]<<")"<<endl;cout<<"\t"<<"Samples: ";for(int j = 0; j < cluster_res[i].samples.size(); ++j){int c = cluster_res[i].samples[j];cout<<"(";for(int m = 0; m < col-1; ++m)cout<<data_set[c][m]<<",";cout<<data_set[c][col-1]<<")  ";}cout<<endl;}return 0;
}/**1 1
2 1
1 2
2 2
3 3
8 8
8 9
9 8
9 9*/

K-Means聚类算法原理及实现相关推荐

  1. k means聚类算法_一文读懂K-means聚类算法

    1.引言 什么是聚类?我们通常说,机器学习任务可以分为两类,一类是监督学习,一类是无监督学习.监督学习:训练集有明确标签,监督学习就是寻找问题(又称输入.特征.自变量)与标签(又称输出.目标.因变量) ...

  2. k means聚类算法_K-Means 聚类算法 20210108

    说到聚类,应先理解聚类和分类的区别 聚类和分类最大的不同在于:分类的目标是事先已知的,而聚类则不一样,聚类事先不知道目标变量是什么,类别没有像分类那样被预先定义出来. K-Means 聚类算法有很多种 ...

  3. OpenCV官方文档 理解k - means聚类

    理解k - means聚类 目标 在这一章中,我们将了解k - means聚类的概念,它是如何工作等. 理论 我们将这个处理是常用的一个例子. t恤尺寸问题 考虑一个公司要发布一个新模型的t恤. 显然 ...

  4. python(scikit-learn)实现k均值聚类算法

    k均值聚类算法原理详解 示例为链接中的例题 直接调用python机器学习的库scikit-learn中k均值算法的相关方法 from sklearn.cluster import KMeans imp ...

  5. k均值聚类算法(K Means)及其实战案例

    算法说明 K均值聚类算法其实就是根据距离来看属性,近朱者赤近墨者黑.其中K表示要聚类的数量,就是说样本要被划分成几个类别.而均值则是因为需要求得每个类别的中心点,比如一维样本的中心点一般就是求这些样本 ...

  6. k均值聚类算法案例 r语言iris_K-means算法原理

    聚类的基本思想 俗话说"物以类聚,人以群分" 聚类(Clustering)是一种无监督学习(unsupervised learning),简单地说就是把相似的对象归到同一簇中.簇内 ...

  7. 干货 | 非常全面的谱聚类算法原理总结

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 谱聚类算法是目前最流行的聚类算法之一,其性能及适用场景优于传统的聚 ...

  8. 层次聚类算法原理总结

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 层次聚类(hierarchical clustering)基于簇间 ...

  9. OpenCV的k - means聚类 -对图片进行颜色量化

    OpenCV的k - means聚类 目标 学习使用cv2.kmeans()数据聚类函数OpenCV 理解参数 输入参数 样品:它应该的np.float32数据类型,每个特性应该被放在一个单独的列. ...

  10. 【模式识别】K均值聚类算法应用实验报告及MATLAB仿真

    一. 实验目的 1.掌握K均值聚类算法的原理和实现过程: 2.掌握K均值聚类算法的应用方法. 二. 实验内容 1.彩色图像分割 选择一幅图像,分别按三种颜色数进行彩色图像分割的结果(原图和分割图).步 ...

最新文章

  1. DeepI2P:基于深度分类的图像对点云配准
  2. linux新增ssh端口80,Linux(CentOS 7) 新增或修改 SSH默认端口
  3. Jquery_改变背景颜色
  4. jq实现文字个数限制_分布式系统高可用实战之限流器(Go 版本实现)
  5. ORACLE关于段的HEADER_BLOCK的一点浅析
  6. 数字非压缩光端机的选购原则
  7. 【渝粤教育】电大中专电商运营实操 答案作业 题库
  8. mysql经典主从复制
  9. win10锁定计算机会断网吗,Win10专业版如何设置锁屏后不断网?超详细的图文教程...
  10. java里的foreach迭代器_java 中 for 、foreach 和 迭代器 的学习笔记
  11. RDS数据库全量恢复方案
  12. matlab在数学教学,Matlab在数学函数教学中的应用
  13. 编写测试用例方法之等价类划分法
  14. 什么是僵尸进程(Zombie)?
  15. 从百草园到三味书屋 鲁迅
  16. EXCEL中输入的数字无法正常显示变成科学计数法
  17. 编程一开始就应该养成的好习惯
  18. git拉取报错:You have not concluded your merge. (MERGE_HEAD exists)
  19. swr_get_out_samples和swr_convert,比特率重采样
  20. jQuery中添加元素删除元素的方法

热门文章

  1. uni-app 使用外部.js文件定义全局变量和全局方法
  2. Julia学习笔记(一)——入门
  3. 回首2013,寄语步入社会的我——自强不息,厚德载物
  4. swper 实现滑动切换功能的两种方式
  5. 平面设计教程:PS新手如何制作好透视立体字海报
  6. MOOC中国大学自动评分js脚本
  7. MacOS中的剪切快捷键
  8. Android 9 Audio系统笔记:AudioFlinger音频流处理流程
  9. 【工作规划】未来自我学习计划及发展注意事项
  10. ACTF2022 rsa leak