kmeans原理

  • 1.初始化k个起始中心点;
  • 2.计算所有样本点到这些中心点的距离,对于单个样本点,把它归类成和距离最近的中心点一类;
  • 3.聚类好所有样本点后,对聚到同一类的点,计算坐标均值,更新中心点;
  • 4.循环2、3两步,直到达到指定的循环次数或者满足退出循环条件时(如每次循环中心点移动距离小于某个值),退出循环.

讲一下题目

输入序列坐标和聚类数k:
[(x1,y1),(x2,y2,...)],k[(x_1,y_1),(x_2,y_2,...)],k [(x1​,y1​),(x2​,y2​,...)],k
使用前几个坐标作为初始化的中心点

迭代100次

输出分类结果label:
[1,1,1,0,1,2,...][1,1,1,0,1,2,...] [1,1,1,0,1,2,...]

代码部分

定义全局变量

//点集数目
int POINTNUM=1000;
// 聚类数
int k=3;
//迭代次数
int ITER=100;

随机生成二维测试点集

 //随机生成二维测试点集vector<Point2f> points;for (int i = 0; i < POINTNUM; i++){Point2f point;point.x = rand() % 500;point.y = rand() % 500;points.push_back(point);}

计算两点间距离的函数

float getDistance(Point2f point, Point2f center)
{return sqrt(pow(point.x - center.x, 2) + pow(point.y - center.y, 2));
}

Kmeans部分

 //使用前几个坐标初始化中心点vector<Point2f> center;for (int i = 0; i < k; ++i){center.push_back(points[i]);}//初始化labelvector<int> label(POINTNUM,-1);//迭代for (int iter = 0; iter < ITER; ++iter){//根据与中心点的距离,对每一个样本点进行聚类for (int pointNum = 0; pointNum < POINTNUM; ++pointNum){float distance = FLT_MAX;for (int cluster = 0; cluster < k; ++cluster){float temp_distance = getDistance(points[pointNum], center[cluster]);if (temp_distance < distance){distance = temp_distance;label[pointNum] = cluster;}}}//根据聚类结果,计算坐标均值,更新中心点坐标for (int cluster = 0; cluster < k; cluster++){int count = 0;int sum_x = 0;int sum_y = 0;for (int pointNum = 0; pointNum < POINTNUM; pointNum++){if (label[pointNum] == cluster){count++;sum_x += points[pointNum].x;sum_y += points[pointNum].y;}}center[cluster].x = sum_x / count;center[cluster].y = sum_y / count;}}

将结果画出来的部分代码(仅k=3)

主要是利用opencv的两个函数:
imshow(用图片的方式显示矩阵Mat)
circle(在矩阵Mat上画圆)

Mat img = Mat::zeros(500, 500, CV_8UC3);for (int i = 0; i < POINTNUM; i++)
{if (label[i] == 0){circle(img, points[i], 2, Scalar(255, 0, 0), FILLED, LINE_AA);}if (label[i] == 1){circle(img, points[i], 2, Scalar(0,255,0), FILLED, LINE_AA);}if (label[i] == 2){circle(img, points[i], 2, Scalar(0, 0, 255), FILLED, LINE_AA);}
}namedWindow("img", WINDOW_AUTOSIZE);
imshow("img", img);
waitKey(0);

结果

初始随机点集:

kmeans,k=3聚类后结果

完整代码

#include <iostream>
#include <stack>
#include <opencv2/opencv.hpp>
#include <math.h>using namespace std;
using namespace cv;//点集数目
int POINTNUM = 1000;
// 聚类数
int k = 3;
//迭代次数
int ITER = 100;float getDistance(Point2f point, Point2f center)
{return sqrt(pow(point.x - center.x, 2) + pow(point.y - center.y, 2));
}void main()
{Mat img = Mat::zeros(500, 500, CV_8UC3);//随机生成二维测试点集vector<Point2f> points;for (int i = 0; i < POINTNUM; i++){Point2f point;point.x = rand() % 500;point.y = rand() % 500;points.push_back(point);}//kmeans//使用前几个坐标初始化中心点vector<Point2f> center;for (int i = 0; i < k; ++i){center.push_back(points[i]);}//初始化labelvector<int> label(POINTNUM,-1);//迭代for (int iter = 0; iter < ITER; ++iter){//根据与中心点的距离,对每一个样本点进行聚类for (int pointNum = 0; pointNum < POINTNUM; ++pointNum){float distance = FLT_MAX;for (int cluster = 0; cluster < k; ++cluster){float temp_distance = getDistance(points[pointNum], center[cluster]);if (temp_distance < distance){distance = temp_distance;label[pointNum] = cluster;}}}//根据聚类结果,计算坐标均值,更新中心点坐标for (int cluster = 0; cluster < k; cluster++){int count = 0;int sum_x = 0;int sum_y = 0;for (int pointNum = 0; pointNum < POINTNUM; pointNum++){if (label[pointNum] == cluster){count++;sum_x += points[pointNum].x;sum_y += points[pointNum].y;}}center[cluster].x = sum_x / count;center[cluster].y = sum_y / count;}}for (int i = 0; i < POINTNUM; i++){if (label[i] == 0){circle(img, points[i], 2, Scalar(255, 0, 0), FILLED, LINE_AA);}if (label[i] == 1){circle(img, points[i], 2, Scalar(0,255,0), FILLED, LINE_AA);}if (label[i] == 2){circle(img, points[i], 2, Scalar(0, 0, 255), FILLED, LINE_AA);}}namedWindow("img", WINDOW_AUTOSIZE);imshow("img", img);waitKey(0);return;
}

参考:
1.C++中rand()函数的用法
https://blog.csdn.net/Kallou/article/details/123554991
2.c++实现kmeans
https://blog.csdn.net/SongJ12345666/article/details/103347903
3.c++的float类型包含的最值问题…
https://blog.csdn.net/gao1440156051/article/details/50112897
4.opencv c++ circle()函数 、putText()函数小结
https://blog.csdn.net/weixin_45842951/article/details/122201959

[C++] Kmeans算法实现相关推荐

  1. 机器学习中的聚类算法(1):k-means算法

    一文详解激光点云的物体聚类:https://mp.weixin.qq.com/s/FmMJn2qjtylUMRGrD5telw 引言: Q:什么是聚类算法? 现在我们在做的深度学习当中,比如图像的识别 ...

  2. python实现K-means算法

    K-means算法流程: 随机选k个样本作为初始聚类中心 计算数据集中每个样本到k个聚类中心距离,并将其分配到距离最小的聚类中心 对于每个聚类,重新计算中心 回到2,至得到局部最优解 python代码 ...

  3. Python之机器学习K-means算法实现

    一.前言: 今天在宿舍弄了一个下午的代码,总算还好,把这个东西算是熟悉了,还不算是力竭,只算是知道了怎么回事.今天就给大家分享一下我的代码.代码可以运行,运行的Python环境是Python3.6以上 ...

  4. matlab 职坐标,机器学习入门之机器学习实战ByMatlab(四)二分K-means算法

    本文主要向大家介绍了机器学习入门之机器学习实战ByMatlab(四)二分K-means算法,通过具体的内容向大家展现,希望对大家学习机器学习入门有所帮助.前面我们在是实现K-means算法的时候,提到 ...

  5. 一文详尽系列之K-means算法

    点击上方"Datawhale",选择"星标"公众号 第一时间获取价值内容 K-means 是我们最常用的基于距离的聚类算法,其认为两个目标的距离越近,相似度越大 ...

  6. 标准K-means算法的缺陷、K-mean++初始化算法、初始化算法步骤、Kmeans++算法实现

    标准K-means算法的缺陷.K-mean++初始化算法.初始化算法步骤.Kmeans++算法实现 目录 标准K-means算法的缺陷.K-mean&

  7. Kmeans算法的过程是什么?Kmeans算法的缺陷主要有哪些?

    Kmeans算法的过程是什么?Kmeans算法的缺陷主要有哪些? 目录 Kmeans算法的过程是什么?Kmeans算法的缺陷主要有哪些?

  8. AI K-means算法对数据进行聚类分析-实验报告

    1. 问题描述及实验要求 K-means算法对data中数据进行聚类分析 (1)算法原理描述 (2)算法结构 (3)写出K-means具体功能函数(不能直接调用sklearn.cluster(Mean ...

  9. 「AI科技」机器学习算法之K-means算法原理及缺点改进思路

    https://www.toutiao.com/a6641916717624721933/ 2019-01-03 08:00:00 K-means算法是使用得最为广泛的一个算法,本文将介绍K-mean ...

  10. 机器学习里如何确定K-Means算法的K值?

    [问题] Kmeans算法中,K值所决定的是在该聚类算法中,所要分配聚类的簇的多少.Kmeans算法对初始值是比较敏感的,对于同样的k值,选取的点不同,会影响算法的聚类效果和迭代的次数. [解决方案] ...

最新文章

  1. 能够抑制网络风暴的是?
  2. 深度解析Java可变参数类型以及与数组的区别
  3. Error:The supplied javaHome seems to be invalid. I cannot find the java executable
  4. Python开发之--前端 HTML基础
  5. 【Python 标准库学习】系统相关的参数和函数库 — sys
  6. android wifi热点项目总结,高通Android wifi移植和wifi热点问题总结
  7. flask对mysql数据库增删改查_flask后台框架1.4(mysql配置+数据库增删改查)-Go语言中文社区...
  8. 64位win7搭建php mysql_Win7 64位操作系统下配置PHP+MySql+Apache环境
  9. jclasslib修改jar包中class文件 IDEA
  10. 物种内共线性分析——思路以及踩坑总结(二)
  11. python实战—考勤报表数据分析处理
  12. mysql 每5分钟统计_SQL按时间段统计(5分钟统计一次访问量为例,oracle统计)
  13. 只有10分,5分,2分,1分的硬币;顾客付款x分,商品价格y分。如何找零所使用的硬币最少(递归实现)
  14. Android子控件超出父控件的范围被覆盖问题
  15. global 与 $GLOBALS用法
  16. [转载] DeepinC . Mr_zkt 集合选数
  17. 习题 3.12 给出一个不多于5位的正整数,要求:1. 求出它是几位数;2. 分别打印出每一位数字;3. 按逆序打印出各位数字,例如原数位321,应输出123。
  18. java基础国庆作业_第四次作业 java程序设计国庆作业
  19. Alpine镜像中not found引出的gnu libc和musl libc的争论
  20. java 音频格式_java – 音频格式的转换

热门文章

  1. android 手机远程助手,安卓远程桌面软件
  2. python体脂率计算
  3. 小米air2 pro ota 升级固件
  4. 用递归法打印九九乘法表c语言,java递归打印九九乘法表
  5. 如何使诺机亚手机显示中文电话簿
  6. 关于oracle端口映射的远程连接
  7. http测试工具:httpbin
  8. Unity3d 发动机原理详细介绍
  9. 从iRedMail 创建web服务学习Nginx
  10. CSS盒模型的2个误区