k-means聚类分析范例程序
K-Means聚类算法原理参考以下链接:
https://www.cnblogs.com/pinard/p/6164214.html
2. 传统K-Means算法流程
在上一节我们对K-Means的原理做了初步的探讨,这里我们对K-Means的算法做一个总结。
首先我们看看K-Means算法的一些要点。
1)对于K-Means算法,首先要注意的是k值的选择,一般来说,我们会根据对数据的先验经验选择一个合适的k值,如果没有什么先验知识,则可以通过交叉验证选择一个合适的k值。
2)在确定了k的个数后,我们需要选择k个初始化的质心,就像上图b中的随机质心。由于我们是启发式方法,k个初始化的质心的位置选择对最后的聚类结果和运行时间都有很大的影响,因此需要选择合适的k个质心,最好这些质心不能太近。
好了,现在我们来总结下传统的K-Means算法流程。
输入是样本集D={x1,x2,...xm},聚类的簇树k,最大迭代次数N
输出是簇划分C={C1,C2,...Ck}
1) 从数据集D中随机选择k个样本作为初始的k个质心向量: {μ1,μ2,...,μk}
2)对于n=1,2,...,N
a) 将簇划分C初始化为Ct=∅ t=1,2...k
b) 对于i=1,2...m,计算样本xixi和各个质心向量μj(j=1,2,...k)的距离:dij=||xi−μj||2,将xixi标记最小的为dij所对应的类别λi。此时更新Cλi=Cλi∪{xi}Cλi=Cλi∪{xi}
c) 对于j=1,2,...,k,对CjCj中所有的样本点重新计算新的质心μj=1|Cj|∑x∈Cjxμj=1|Cj|∑x∈Cjx
e) 如果所有的k个质心向量都没有发生变化,则转到步骤3)
3) 输出簇划分C={C1,C2,...Ck}
程序代码如下:
//在矩阵img中随机分布白点
void myRandFill(Mat&img,int numPoint)
{
Vec3b white(,,);
for(int i=;i<numPoint;i++)
{
int x=rand()%+;
int y=rand()%+;
img.at<Vec3b>(y,x)=white; } }
Point getCentroid(std::vector<Point> C)
{
Point newPc(,);
for(int i=;i<(int)C.size();i++)
{
newPc.x += C[i].x;
newPc.y +=C[i].y;
}
newPc.x /=C.size();
newPc.y /=C.size();
return newPc;
}
void getCluster(const Mat&img,Mat&imgCopy,
vector<Point>C[],Point Pc[],
Vec3b color[],int numOfCluster)
{
for(int i=;i<img.rows;i++)
{
for(int j=;j<img.cols;j++)
{
Vec3b X=img.at<Vec3b>(i,j);
vector<float> d;//当前像素与所有质心距离组成的数组
if(X[]||X[]||X[])
{
for(int k=;k<numOfCluster;k++)
{
float dist=(Pc[k].x-j)*(Pc[k].x-j)+(Pc[k].y-i)*(Pc[k].y-i);
d.push_back(dist);
}
//获取数组d[]中最小值的位置
int minPos=(int)(min_element(d.begin(),d.end())-d.begin());
//将距离最小质心 对应颜色赋值给当前像素
imgCopy.at<Vec3b>(i,j)=color[minPos];
//将当前像素并入对应类的集合
C[minPos].push_back(Point(j,i)); } }
}
} void myKmeans(const Mat&img,//输入原图像
Mat&imgCopy,//分类后的图像输出
std::vector<Point>*C,//类别标记数组,
//数组中每个元素C[i]表示一类像素
//从图像中找到符合该类准则的像素
//保存在C[i]中,i=1,2,3...k。
Point*Pc,//初始质心坐标
Vec3b*color,//不同类别的像素,赋予不同的颜色
int numOfclusters)//预设的类别数
{
//将距离Pc1近的点染成红色,距离Pc2点距离近的染成蓝色
//
int stop=;
int countIte=;
while(!stop)
{ getCluster(img,imgCopy,C,Pc,color,numOfclusters);
//计算新的C1、C2质心,并在imgCopy上绘制黄色和青色新质心点
Point* newPc=new Point[numOfclusters];
for(int nc=;nc<numOfclusters;nc++)
{
newPc[nc]=getCentroid(C[nc]);
circle(imgCopy,newPc[nc],,Scalar(,,),);
}
vector<float>dc;
float sumDistance;
for(int k=;k<;k++)
{
float dp=(newPc[k].x-Pc[k].x)*(newPc[k].x-Pc[k].x)
+(newPc[k].y-Pc[k].y)*(newPc[k].y-Pc[k].y);
dc.push_back(dp);
}
sumDistance=accumulate(dc.begin(),dc.end(),); cout<<"sum distance="<<sumDistance<<endl;
countIte++;
for(int nc=;nc<numOfclusters;nc++)
{
Pc[nc]=newPc[nc];
}
if(sumDistance==)
{
stop=;
} }
cout<<"count of iteration="<<countIte<<endl;
} int main()
{
Mat img(,,CV_8UC3,Scalar::all());
Mat imgCopy=img.clone();
//创建两组随机分布的聚类点,一共200个白点
Mat rm1=img(Rect(,,,));
Mat rm2=img(Rect(,,,));
myRandFill(rm1,);
myRandFill(rm2,); //设有两个聚类颜色标记,分别用红、蓝两色表示
Vec3b color[]={ Vec3b(,,),Vec3b(,,)};
//与red和blue两种颜色对应的族类集合为C[0]和C[1]
std::vector<cv::Point> C[];
//随便定义两个坐标点,作为两个聚类质心的起始位置
Point *Pc=new Point[];
Pc[]=Point(,);//C1类像素的初始质心坐标
Pc[]=Point(,);//C2类像素的初始质心坐标
cv::circle(imgCopy,Pc[],,Scalar(,,),-);
cv::circle(imgCopy,Pc[],,Scalar(,,),-);
imshow("original img",img); myKmeans(img,imgCopy,C,Pc,color,);
imshow("new centroid position",imgCopy);
waitKey();
return ;
}
k-means聚类分析范例程序的更多相关文章
- RAD Studio XE8 技术研讨会讲义与范例程序下载
感谢各位程序猿亲临现场參加我们的公布会,现奉上会议当天的讲义与范例程序供大家參考: 2015/5/25~27北京.深圳 『RAD Studio XE8技术研讨会』 下载讲义:http://pan ...
- SPSS聚类分析:K均值聚类分析
SPSS聚类分析:K均值聚类分析 一.概念:(分析-分类-K均值聚类) 1.此过程使用可以处理大量个案的算法,根据选定的特征尝试对相对均一的个案组进行标识.不过,该算法要求您指定聚类的个数.如果知道, ...
- SAP ALV标准范例程序介绍
下面介绍几个学习ALV的SAP自带标准程序实例 1. BALVSD06 : Output flights (simple version + save)这是该系列范例最简单的一个,建议以此入门.使用的 ...
- KNN 与 K - Means 算法比较
KNN K-Means 1.分类算法 聚类算法 2.监督学习 非监督学习 3.数据类型:喂给它的数据集是带label的数据,已经是完全正确的数据 喂给它的数据集是无label的数据,是杂乱无章的,经过 ...
- eval(function(p,a,c,k,e,r)解密程序
以eval(function(p,a,c,k,e,r){e=function(c)开头的js文件是经过加密的 使用下面方法可以对js文件进行加密.解密 步骤:1.新建html页面,内容如下列代码 2. ...
- 软件——机器学习与Python,聚类,K——means
K-means是一种聚类算法: 这里运用k-means进行31个城市的分类 城市的数据保存在city.txt文件中,内容如下: BJ,2959.19,730.79,749.41,513.34,467. ...
- R 语言实战-Part 5-1笔记
R 语言实战(第二版) part 5-1 技能拓展 ----------第19章 使用ggplot2进行高级绘图------------------------- #R的四种图形系统: #①base: ...
- 程序员编程艺术:第三章续、Top K算法问题的实现
程序员编程艺术:第三章续.Top K算法问题的实现 作者:July,zhouzhenren,yansha. 致谢:微软100题实现组,狂想曲创作组. 时间:2011年05月08日 ...
- 网络费用流-最小k路径覆盖
多校联赛第一场(hdu4862) Jump Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
随机推荐
- 挺棒的七个Python图形应用GUI开发框架
作为Pyhon开发者,你迟早都会碰到图形用户界面(GUI)应用开发任务,目前市场上有大量Python GUI开发框架可供选择,Python wiki GUI programming给出了超过30个跨平 ...
- 理解Event冒泡模型
本文探索一下Event的冒泡过程和初学遇到的几个小bug DOM Event概述 Event接口是检测在DOM中的发生的所有事件,我们一直在用,而且从DOM的很早的版本就一直在用着.早期的网景(后来的 ...
- Java笔记(第五篇)
抛出异常 使用throws声明抛出异常 Throws 通常用于方法声明,当方法中可能存在异常,却不想在方法中对异常进行处理时,就可以在声明方法时使用throws声明抛出的异常,然后再调用该方法的其他方 ...
- eclipse调试断点
1.条件断点 如果你不知道如何添加断点,只需点击左边面板(行号前面)断点即被创建.在调试界面中,“断点”视图会把所有被创建的断点列出来.我们可以给它加一个布尔条件,也就是说,该断点会被激活并且如果布尔 ...
- parent([expr]) 取得一个包含着所有匹配元素的唯一父元素的元素集合。
parent([expr]) 概述 取得一个包含着所有匹配元素的唯一父元素的元素集合.大理石构件 你可以使用可选的表达式来筛选. 参数 exprStringV1.0 用来筛选的表达式 示例 描述: 查 ...
- 2018CCPC桂林站JStone Game
题目描述 Alice and Bob are always playing game! The game today is about taking out stone from the stone ...
- Mysql 修改最大链接数
链接数过小经常出现ERROR 1040: Too many connections错误 show variables like '%max_connections%'; 查看当前的mysql链接值 ...
- element-ui做表单验证 v-for遍历表单 自动生成校验规则 pc移动双适配
整体思路: 1:利用element-ui的栅格实现小分辨率和大分辨率的适配 2:模拟一组数据,从中筛选出 绑定各个表单值的对象 以及生成验证规则对象 3:在script标签内 .data()外,自 ...
- 集合家族——LinkedList
一.概述: LinkedList 与 ArrayList 一样实现 List 接口,只是 ArrayList 是 List 接口的大小可变数组的实现,LinkedList 是 List 接口链表的实现 ...
- typedef void (*funcptr)(void)的含义
fun a;//等价于void (*a)(); 这样声明起来就方便多了 void (*a)();表示a是个指针,指向一个不带参数.返回值为空的函数 定义一个函数指针类型. 比如你有三个函数: void ...