经典无监督机器学习c++复现–kmeans聚类
对于机器学习,估计大家现在都耳熟能详了吧,近几年的发展,从传统的机器学习算法,到通过人工神经网络发展而来的深度学习神经网络,ML到DL估计对于各类大佬来说可能已经快要厌倦了,圈子泡久了,总会有点枯燥,对于机器学习盛行的时代,python自然而然也得到了广泛的应用,主要是python对于第三方库来说是太友好了,一个pip命令叫你安装就安装,卸载就卸载,哪像其他的语言一说到第三方库,不是源码编译就是环境配置,搞得头大,哈哈!
那是题外话了,其实很早就对kmeans有过了解,但是总没有去从底层原理了解其工作机制,最近有幸又碰到Kmeans这个大佬了,不得不深入了解一下。
先放一个demo程序跑的演示看下效果吧!
以前总觉得这种机器学习算法让自己深不可测,遇到总是逃之夭夭,可这次被我抓住了,就留在这吧,别跑了,邪笑…
不管怎样,给自己涨了点知识,废话不多说,留下自己的理解吧!
自己理解的Kmeans无监督聚类:
1、初始K个质心点或类别
通过初始聚类的类别个数,对每个类随机选择质心点作为初始质心点坐标值。
2、计算所有样本点到每个质心点的距离,选取距离最小的质心点距离作为此质心类的类别
计算样本点中对每个质心点的距离,这个距离使用的是欧式距离公式计算,对每个样本点选择距离最小的那个质心点作为他的类。
3、更新质心点坐标
所有样本都有所属类别后,更新质心点坐标,这个质心点坐标是个虚拟的坐标,计算方式通过每个类的所有样本点求取均值来更新得到新的虚拟质心点坐标。
4、判断现在质心点坐标是否和更新前质心点坐标相等
不相等,重复1、2、3步骤迭代,相等则结束
不过这里还可以自动设置迭代次数来提前结束
其实到目前来说,对于kmeans算法的优化有很多种了,kmeans一个最主要的缺点就是K值的初始选择问题,是否可以动态的自己更新k值,在迭代的过程中自己判定k值的合适选取,确实是有这种算法的(这里知识有限就不过多介绍,否则会暴露自己的能力的)
其中一种优化方法就是基于kmeans的基础在质心点的选取做了点小改动-----
kmeans++做的优化是尽可能的将选取的这k个质心点距离离得远,这就可以在算法过程中减少迭代的次数,提前找到收敛点,对于上面的那个视频,初始的质心选择表示就还不错呀!
这里主要算法源码吧,对于大佬们来说就有点浪费时间了,不过可以给我指点一二,小弟感激不尽
// 1、欧式距离计算分类
for (int j = 0; j < sum_points.size(); j++)
{
float min_distance = float(INT_MAX);
for (int i = 0; i < points.size(); i++)
{
//此处为了减少时间开销,没有开根号
float distance = pow((sum_points[j].x - points[i].x), 2) + pow((sum_points[j].y - points[i].y), 2);
if (distance < min_distance)
{
min_distance = distance;
label[j] = i;
}
}
}
// 2、更新质心的坐标点(通过label值)
// k值为4,则进行四次的更新,定义4类分别的点值变量
vector<int> k(points.size(), 0);
vector<float> x(points.size(), 0.0);
vector<float> y(points.size(), 0.0);
for (int i = 0; i < label.size(); i++)
{
for (int j = 0; j < points.size(); j++)
{
// 找到对应的类别进行后续的质心坐标运算
if (j == label[i])
{
k[j]++;
x[j] += sum_points[i].x;
y[j] += sum_points[i].y;
break;
}
}
}
// 更新坐标
for (int i = 0; i < points.size(); i++)
{
x[i] /= k[i];
y[i] /= k[i];
}
// 质心坐标值填补
for (int i = 0; i < points.size(); i++)
{
new_points[i] = Point2f(x[i], y[i]);
}
上面是主要的算法代码,c++实现,主要的效果是可以实现,不过还是有可以调优的地方
如果有需要源码的童鞋,可以关注微信公众号<木木夕算法笔记>:输入指令c++kmeans获取c++源码demo,而且这里会不定时的更新一些算法以及demo程序。