参考:

1.机器学习-KMeans聚类 K值以及初始类簇中心点的选取

2.K-Means算法的研究分析及改进

一、K-means算法原理

K-means算法是最常用的一种聚类算法。算法的输入为一个样本集(或者称为点集),通过该算法可以将样本进行聚类,具有相似特征的样本聚为一类。

针对每个点,计算这个点距离所有中心点最近的那个中心点,然后将这个点归为这个中心点代表的簇。一次迭代结束之后,针对每个簇类,重新计算中心点,然后针对每个点,重新寻找距离自己最近的中心点。如此循环,直到前后两次迭代的簇类没有变化。

下面通过一个简单的例子,说明K-means算法的过程。如下图所示,目标是将样本点聚类成3个类别。

基本的步骤为:

step1:选定要聚类的类别数目k(如上例的k=3类),选择k个中心点。

step2:针对每个样本点,找到距离其最近的中心点(寻找组织),距离同一中心点最近的点为一个类,这样完成了一次聚类。

step3:判断聚类前后的样本点的类别情况是否相同,如果相同,则算法终止,否则进入step4。

step4:针对每个类别中的样本点,计算这些样本点的中心点,当做该类的新的中心点,继续step2。


上述步骤的关键两点是:

1. 找到距离自己最近的中心点。

2. 更新中心点。

二、Python实现

下面给出它的Python实现,其中中心点的选取是手动选择的。在代码中随机产生了一个样本,用于测试K-means算法:

# K-means Algorithm is a clustering algorithm
import numpy as np
import matplotlib.pyplot as plt
import randomdef get_distance(p1, p2):diff = [x-y for x, y in zip(p1, p2)]distance = np.sqrt(sum(map(lambda x: x**2, diff)))return distance# 计算多个点的中心
# cluster = [[1,2,3], [-2,1,2], [9, 0 ,4], [2,10,4]]
def calc_center_point(cluster):N = len(cluster)m = np.matrix(cluster).transpose().tolist()center_point = [sum(x)/N for x in m]return center_point# 检查两个点是否有差别
def check_center_diff(center, new_center):n = len(center)for c, nc in zip(center, new_center):if c != nc:return Falsereturn True# K-means算法的实现
def K_means(points, center_points):N = len(points)         # 样本个数n = len(points[0])      # 单个样本的维度k = len(center_points)  # k值大小tot = 0while True:             # 迭代temp_center_points = [] # 记录中心点clusters = []       # 记录聚类的结果for c in range(0, k):clusters.append([]) # 初始化# 针对每个点,寻找距离其最近的中心点(寻找组织)for i, data in enumerate(points):distances = []for center_point in center_points:distances.append(get_distance(data, center_point))index = distances.index(min(distances)) # 找到最小的距离的那个中心点的索引,clusters[index].append(data)    # 那么这个中心点代表的簇,里面增加一个样本tot += 1print(tot, '次迭代   ', clusters)k = len(clusters)colors = ['r.', 'g.', 'b.', 'k.', 'y.']  # 颜色和点的样式for i, cluster in enumerate(clusters):data = np.array(cluster)data_x = [x[0] for x in data]data_y = [x[1] for x in data]plt.subplot(2, 3, tot)plt.plot(data_x, data_y, colors[i])plt.axis([0, 1000, 0, 1000])# 重新计算中心点(该步骤可以与下面判断中心点是否发生变化这个步骤,调换顺序)for cluster in clusters:temp_center_points.append(calc_center_point(cluster))# 在计算中心点的时候,需要将原来的中心点算进去for j in range(0, k):if len(clusters[j]) == 0:temp_center_points[j] = center_points[j]# 判断中心点是否发生变化:即,判断聚类前后样本的类别是否发生变化for c, nc in zip(center_points, temp_center_points):if not check_center_diff(c, nc):center_points = temp_center_points[:]   # 复制一份breakelse:   # 如果没有变化,那么退出迭代,聚类结束breakplt.show()return clusters # 返回聚类的结果# 随机获取一个样本集,用于测试K-means算法
def get_test_data():N = 1000# 产生点的区域area_1 = [0, N / 4, N / 4, N / 2]area_2 = [N / 2, 3 * N / 4, 0, N / 4]area_3 = [N / 4, N / 2, N / 2, 3 * N / 4]area_4 = [3 * N / 4, N, 3 * N / 4, N]area_5 = [3 * N / 4, N, N / 4, N / 2]areas = [area_1, area_2, area_3, area_4, area_5]k = len(areas)# 在各个区域内,随机产生一些点points = []for area in areas:rnd_num_of_points = random.randint(50, 200)for r in range(0, rnd_num_of_points):rnd_add = random.randint(0, 100)rnd_x = random.randint(area[0] + rnd_add, area[1] - rnd_add)rnd_y = random.randint(area[2], area[3] - rnd_add)points.append([rnd_x, rnd_y])# 自定义中心点,目标聚类个数为5,因此选定5个中心点center_points = [[0, 250], [500, 500], [500, 250], [500, 250], [500, 750]]return points, center_pointsif __name__ == '__main__':points, center_points = get_test_data()clusters = K_means(points, center_points)print('#######最终结果##########')for i, cluster in enumerate(clusters):print('cluster ', i, ' ', cluster)

由于样本点是随机产生的,所以每次运行的结果不相同。6次迭代得到的聚类结果分别如下图。

控制台输出结果为:

三、初始中心点的选取

初始中心点的选取,对聚类的结果影响较大。可以验证,不同初始中心点,会导致聚类的效果不同。如何选择初始中心点呢?一个原则是:

初始中心点之间的间距应该较大。因此,可以采取的策略是:

step1:计算所有样本点之间的距离,选择距离最大的一个点对(两个样本C1, C2)作为2个初始中心点,从样本点集中去掉这两个点。

step2:如果初始中心点个数达到k个,则终止。如果没有,在剩余的样本点中,选一个点C3,这个点优化的目标是:

这是一个双目标优化问题,可以约束其中一个,极值化另外一个,这样可以选择一个合适的C3点,作为第3个初始中心点。

如果要寻找第4个初始中心点,思路和寻找第3个初始中心点是相同的。

四、误差平方和(Sum of Squared Error)

误差平法和,SSE,用于评价聚类的结果的好坏,SSE的定义如下。

一般情况下,k越大,SSE越小。假设k=N=样本个数,那么每个点自成一类,那么每个类的中心点为这个类中的唯一一个点本身,那么SSE=0。

五、k值得确定

一般k不会很大,大概在2~10之间,因此可以作出这个范围内的SSE-k的曲线,再选择一个拐点,作为合适的k值。

可以看到,k=5之后,SSE下降的变得很缓慢了,因此最佳的k值为5。

数据挖掘十大算法(二):K-means聚类算法原理与实现相关推荐

  1. 基于改进人工蜂群算法的K均值聚类算法(附MATLAB版源代码)

    其实一直以来也没有准备在园子里发这样的文章,相对来说,算法改进放在园子里还是会稍稍显得格格不入.但是最近邮箱收到的几封邮件让我觉得有必要通过我的博客把过去做过的东西分享出去更给更多需要的人.从论文刊登 ...

  2. pythonk均值实现_python实现k均值算法示例(k均值聚类算法)

    简易完成平面图的点K平均值剖析,应用欧几里得间距,并且用pylab展现. 编码以下: import pylab as pl #calc Euclid squire def calc_e_squire( ...

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

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

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

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

  5. 基于改进人工蜂群算法的K均值聚类算法(Matlab代码实现)

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

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

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

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

  8. k均值聚类算法优缺点_Grasshopper实现K均值聚类算法

    本文很长很长,有很多很多图,包含以下部分: 1.算法简介 2.如何分类平面点 3.如何分类空间点 4.如何分类多维数据 5.后记 提醒:以下内容包括:智障操作,无中生友,重复造轮子 等 1.算法简介 ...

  9. 聚类算法之K均值聚类

    K-Means聚类方法 1. 介绍 k均值聚类是基于样本集合划分的聚类算法.由于每个样本在划分的过程中只能属于一个类别,所以k-Means算法属于硬聚类. 2. 算法过程 k均值聚类算法是一个迭代的过 ...

  10. 非监督学习: K 均值聚类(原理、步骤、优缺点、调优)

    支持向量机.逻辑回归.决策树等经典的机器学习算法主要用于分类问题,即根据一些己给定类别的样本, 训练某种分类器,使得它能够对类别未知的样本进行分类.与分类问题不同,聚类是在事先并不知道任何样本类别标签 ...

最新文章

  1. 前端分离的前端开发工具_使我成为前端开发人员工作的工具和资源
  2. 真正拖垮年轻人的,是沉没成本
  3. python2.6更改为Python2.7
  4. 【Linux 内核】进程管理 - 进程优先级 ② ( prio 调度优先级 | static_prio 静态优先级 | normal_prio 正常优先级 | rt_priority 实时优先级 )
  5. Ado.net连接池 sp_reset_connection 概念
  6. ftok file php,Linux和PHP中的ftok函数返回值不一致问题跟踪
  7. pandas读取html并排序,使用pandas怎么实现按照列的值进行排序
  8. 高性能WEB开发之Web性能测试工具推荐
  9. java八种排序算法---直接插入排序
  10. 卷积和池化matlab 实现,UFLDL新版教程与编程练习(七):Convolution and Pooling(卷积和池化)...
  11. 学习关于时间在sql里面的对比,用if语句(这个有点特别)
  12. 为什么防火墙透传不过去VLAN11?
  13. PERL 使用IO::Socket::INET模块实现socket编程
  14. centos7 ACL
  15. java 错误 找不到符号_java错误:找不到符号
  16. thinkphp6自定义日志驱动,增加显示全部请求信息
  17. 谈下论坛和商城的开发项目
  18. 孩子们的世界很大,很大...(评刘海强日记)
  19. 双卡4G路由器_4G双卡双模路由器_4G双网双待路由器
  20. 怎样让PHP提示错误信息

热门文章

  1. 众筹模式融资报告发布
  2. Kubernetes CNI Calico:BGP 模式 / Route Reflector 模式(RR)
  3. vue 项目中H5页面,实现大转盘活动
  4. 数据结构与算法——算法
  5. iOS CPU架构(ARM指令集)
  6. [Android手机]教程:修改安卓手机…
  7. arcgis怎么关联excel表_在arcgis中添加excel表格数据-ArcGIS如何将Excel里的数据关联至地图上...
  8. 页面生成器实现及源码下载
  9. 微信小程序 + Java + Mysql(登录 Demo)
  10. ”系统管理员设置了系统策略,禁止进行此项安装“解决办法