KMeans算法的基本思想是初始随机给定K个簇中心,按照最邻近原则把待分类样本点分到各个簇。然后按平均法重新计算各个簇的质心,从而确定新的簇心。一直迭代,直到簇心的移动距离小于某个给定的值。
 

K-Means聚类算法主要分为三个步骤:
(1)第一步是为待聚类的点寻找聚类中心
(2)第二步是计算每个点到聚类中心的距离,将每个点聚类到离该点最近的聚类中去
(3)第三步是计算每个聚类中所有点的坐标平均值,并将这个平均值作为新的聚类中心
反复执行(2)、(3),直到聚类中心不再进行大范围移动或者聚类次数达到要求为止

下图展示了对n个样本点进行K-means聚类的效果,这里k取2:
(a)未聚类的初始点集
(b)随机选取两个点作为聚类中心
(c)计算每个点到聚类中心的距离,并聚类到离该点最近的聚类中去
(d)计算每个聚类中所有点的坐标平均值,并将这个平均值作为新的聚类中心
(e)重复(c),计算每个点到聚类中心的距离,并聚类到离该点最近的聚类中去
(f)重复(d),计算每个聚类中所有点的坐标平均值,并将这个平均值作为新的聚类中心

%随机获取150个点
X = [randn(50,2)+ones(50,2);randn(50,2)-ones(50,2);randn(50,2)+[ones(50,1),-ones(50,1)]];opts = statset('Display','final');%调用Kmeans函数
%X N*P的数据矩阵
%Idx N*1的向量,存储的是每个点的聚类标号
%Ctrs K*P的矩阵,存储的是K个聚类质心位置
%SumD 1*K的和向量,存储的是类间所有点与该类质心点距离之和
%D N*K的矩阵,存储的是每个点与所有质心的距离;[Idx,Ctrs,SumD,D] = kmeans(X,3,'Replicates',3,'Options',opts);%画出聚类为1的点。X(Idx==1,1),为第一类的样本的第一个坐标;X(Idx==1,2)为第二类的样本的第二个坐标
plot(X(Idx==1,1),X(Idx==1,2),'r.','MarkerSize',14)
hold on
plot(X(Idx==2,1),X(Idx==2,2),'b.','MarkerSize',14)
hold on
plot(X(Idx==3,1),X(Idx==3,2),'g.','MarkerSize',14)%绘出聚类中心点,kx表示是圆形
plot(Ctrs(:,1),Ctrs(:,2),'kx','MarkerSize',14,'LineWidth',4)
plot(Ctrs(:,1),Ctrs(:,2),'kx','MarkerSize',14,'LineWidth',4)
plot(Ctrs(:,1),Ctrs(:,2),'kx','MarkerSize',14,'LineWidth',4)legend('Cluster 1','Cluster 2','Cluster 3','Centroids','Location','NW')
#include <iostream>
#include <sstream>
#include <fstream>
#include <vector>
#include <math.h>
#include <stdlib.h>
#define k 3//簇的数目
using namespace std;
//存放元组的属性信息
typedef vector<double> Tuple;//存储每条数据记录int dataNum;//数据集中数据记录数目
int dimNum;//每条记录的维数//计算两个元组间的欧几里距离
double getDistXY(const Tuple& t1, const Tuple& t2)
{double sum = 0;for(int i=1; i<=dimNum; ++i){sum += (t1[i]-t2[i]) * (t1[i]-t2[i]);}return sqrt(sum);
}//根据质心,决定当前元组属于哪个簇
int clusterOfTuple(Tuple means[],const Tuple& tuple){double dist=getDistXY(means[0],tuple);double tmp;int label=0;//标示属于哪一个簇for(int i=1;i<k;i++){tmp=getDistXY(means[i],tuple);if(tmp<dist) {dist=tmp;label=i;}}return label;
}
//获得给定簇集的平方误差
double getVar(vector<Tuple> clusters[],Tuple means[]){double var = 0;for (int i = 0; i < k; i++){vector<Tuple> t = clusters[i];for (int j = 0; j< t.size(); j++){var += getDistXY(t[j],means[i]);}}//cout<<"sum:"<<sum<<endl;return var;}
//获得当前簇的均值(质心)
Tuple getMeans(const vector<Tuple>& cluster){int num = cluster.size();Tuple t(dimNum+1, 0);for (int i = 0; i < num; i++){for(int j=1; j<=dimNum; ++j){t[j] += cluster[i][j];}}for(int j=1; j<=dimNum; ++j)t[j] /= num;return t;//cout<<"sum:"<<sum<<endl;
}void print(const vector<Tuple> clusters[])
{for(int lable=0; lable<k; lable++){cout<<"第"<<lable+1<<"个簇:"<<endl;vector<Tuple> t = clusters[lable];for(int i=0; i<t.size(); i++){cout<<i+1<<".(";for(int j=0; j<=dimNum; ++j){cout<<t[i][j]<<", ";}cout<<")\n";}}
}void KMeans(vector<Tuple>& tuples){vector<Tuple> clusters[k];//k个簇Tuple means[k];//k个中心点int i=0;//一开始随机选取k条记录的值作为k个簇的质心(均值)srand((unsigned int)time(NULL));for(i=0;i<k;){int iToSelect = rand()%tuples.size();if(means[iToSelect].size() == 0){for(int j=0; j<=dimNum; ++j){means[i].push_back(tuples[iToSelect][j]);}++i;}}int lable=0;//根据默认的质心给簇赋值for(i=0;i!=tuples.size();++i){lable=clusterOfTuple(means,tuples[i]);clusters[lable].push_back(tuples[i]);}double oldVar=-1;double newVar=getVar(clusters,means);cout<<"初始的的整体误差平方和为:"<<newVar<<endl; int t = 0;while(abs(newVar - oldVar) >= 1) //当新旧函数值相差不到1即准则函数值不发生明显变化时,算法终止{cout<<"第 "<<++t<<" 次迭代开始:"<<endl;for (i = 0; i < k; i++) //更新每个簇的中心点{means[i] = getMeans(clusters[i]);}oldVar = newVar;newVar = getVar(clusters,means); //计算新的准则函数值for (i = 0; i < k; i++) //清空每个簇{clusters[i].clear();}//根据新的质心获得新的簇for(i=0; i!=tuples.size(); ++i){lable=clusterOfTuple(means,tuples[i]);clusters[lable].push_back(tuples[i]);}cout<<"此次迭代之后的整体误差平方和为:"<<newVar<<endl; }cout<<"The result is:\n";print(clusters);
}
int main(){char fname[256];cout<<"请输入存放数据的文件名: ";cin>>fname;cout<<endl<<" 请依次输入: 维数 样本数目"<<endl;cout<<endl<<" 维数dimNum: ";cin>>dimNum;cout<<endl<<" 样本数目dataNum: ";cin>>dataNum;ifstream infile(fname);if(!infile){cout<<"不能打开输入的文件"<<fname<<endl;return 0;}vector<Tuple> tuples;//从文件流中读入数据for(int i=0; i<dataNum && !infile.eof(); ++i){string str;getline(infile, str);istringstream istr(str);Tuple tuple(dimNum+1, 0);//第一个位置存放记录编号,第2到dimNum+1个位置存放实际元素tuple[0] = i+1;for(int j=1; j<=dimNum; ++j){istr>>tuple[j];}tuples.push_back(tuple);}cout<<endl<<"开始聚类"<<endl;KMeans(tuples);return 0;
}

Kmeans算法介绍及其实现相关推荐

  1. K-means算法介绍

    K-means算法介绍 K-means算法是很典型的基于距离的聚类算法,采用距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度就越大.该算法认为簇是由距离靠近的对象组成的,因此把得到紧凑且独 ...

  2. 【阿旭机器学习实战】【16】KMeans算法介绍及实战:利用KMeans进行足球队分类

    [阿旭机器学习实战]系列文章主要介绍机器学习的各种算法模型及其实战案例,欢迎点赞,关注共同学习交流. 本文对机器学习中的KMeans算法原理进行了简单介绍,并且通过实战案例:足球队分类详细介绍了其使用 ...

  3. 基本Kmeans算法介绍及其实现

    1.基本Kmeans算法[1] 选择K个点作为初始质心 repeat将每个点指派到最近的质心,形成K个簇重新计算每个簇的质心 until 簇不发生变化或达到最大迭代次数 时间复杂度:O(tKmn),其 ...

  4. 【机器学习】k-means算法介绍及简单实现

    文章目录 前言 一.什么是k-means算法 二.k-means的算法过程 三.k-means算法的优缺点 3.1 优点 3.2 缺点 四.k-means算法简单案例 4.1 手写实现k-means算 ...

  5. 【OpenCV学习笔记 020】K-Means聚类算法介绍及实现

    一.K-Means算法介绍 在数据挖掘中,K-Means算法是一种cluster analysis的算法,其主要是来计算数据聚集的算法,主要通过不断地取离种子点最近均值的算法. 问题 K-Means算 ...

  6. 机器学习算法-k-means聚类算法介绍

    聚类算法介绍: 在"无监督学习"(unsupervised learning)中,训练样本的标记信息是未知的,目标是通过对无标记训练样本的学习来揭示数据的内在性质及规律,为进一步的 ...

  7. c均值聚类matlab程序_聚类算法之kmeans算法

    一.k-means算法介绍 k-means最早是由James MacQueen在1967年提出的,这一观点能够追溯到1957年Hugo Steinhaus所提出的想法.1957年,斯图亚特最先提出这一 ...

  8. K-means算法的Java实现 聚类分析681个三国武将(1)

    k-means算法接受输入量 k :然后将n个数据对象划分为 k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度较高:而不同聚类中的对象相似度较小.聚类相似度是利用各聚类中对象的均值所获得一个& ...

  9. MATLAB实现k-means算法(k-均值)对无标签数据进行聚类,并通过肘部法则确定聚类类别

    应一个小伙伴的要求介绍了一下K均值聚类算法.本人也不是很专业,这是之前自学的,如果有错,大家可以提出来,共同进步嘛. 文章目录 一.k-means算法(k-均值) 1.k-means算法介绍 2.k- ...

最新文章

  1. NPOI 菜鸟实践行之根据指定的模板生成Excel 2003格式的文件 (一)
  2. JS中函数和变量声明的提升
  3. php常见漏洞修复,phpstudy漏洞修复方法
  4. 怎么能把看不清的照片给看清_拍完照不会后期怎么办?教你一个懒人办法,能帮照片变“高级”...
  5. MySQL.. ERROR! The server quit without updating PID file问题解决
  6. Java多线程-生产者消费者问题(多个消费者多个生产者)
  7. 每周荐书:JVM、Nginx、小程序(评论送书)
  8. window下python2和python3的共存
  9. 国外大牛开发者创造出Siri第三方服务器
  10. 小贝拉机器人是朋友_被Angelababy、周震南等摸头杀?机器人贝拉凭什么受宠
  11. UVa 10499 - The Land of Justice
  12. InitializeSecurityDescriptor、InitializeAcl、AddAccessAllowedAce、SetSecurityDescriptorDacl
  13. 基于内容和用户画像的个性化推荐
  14. 【POJ2318】TOYS(点在凸多边形内判定---模版暴力/二分)
  15. LitJson使用中的一些问题
  16. 政府部门服务器拒收邮件 怎么办,hotmail 邮箱最近反映拒收邮件,请问怎么解决?...
  17. 【系统架构】原型图验收的思考
  18. 谈谈产品与运营之 - 什么是用户感知
  19. uni-app 第三方授权登录
  20. 用Python快速制作海报级地图!

热门文章

  1. SQL Server 数值四舍五入,小数点后保留2位
  2. TextView使用实例
  3. HTML基础第六讲---表格
  4. jQuery之事件绑定
  5. mybatis_基础篇
  6. SEO配置信息操作文档
  7. eclipse中的debug按钮组突然找不到了,找回方法
  8. ngx_lua_API 指令详解(三)怎样理解 cosocket指令
  9. JavaScript实现十种经典排序算法(js排序算法)
  10. jquery实现动态五角星评分