python-Kmeans\Kmeans++算法理解及代码实现
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了python-Kmeans\Kmeans++算法理解及代码实现,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3463字,纯文字阅读大概需要5分钟。
内容图文
一、 环境:
- Python 3.7.4
- Pycharm Community 2019.3
二、 问题:
对六个样本点[1, 5], [2, 4], [4, 1], [5, 0], [7, 6], [6, 7]进行K-means聚类。
三、 理论推导
此处依照我个人理解所写,错误之处欢迎指出
K-means核心操作为:聚类中心选取—分类—调整聚类中心—再次分类并调整聚类中心直到调整幅度小于阈值或程序运行轮数大于阈值
- 选取聚类中心:
聚类中心的选取可以选择随机选取、人工选取。K-means++相对K-means来说在第一次选取聚类中心方面有所改进,K-means++在初次选择聚类中心时会使各个聚类中心之间的距离都尽可能的远,以得到更合理的分类。如果条件允许的话,我认为人工选取聚类中心的结果会更符合我们的需求。 - 分类
遍历所有待分类的点,根据我们选择的度量方法来判断点的类型。(我的代码直接以欧式距离作为度量来判断类型)
度量方法的选择要根据实际情况以及需求具体分析选择。同一数据使用不同的度量方法最后的分类结果可能会不同。 - 调整聚类中心
计算已经分好类的样本点的均值,以均值作为新的聚类中心。
若首次聚类中心选择很不合理的话,聚类中心的调整也会受到影响,导致最后分类结果不理想。 - 再次分类并调整聚类中心直到调整幅度小于阈值或运行轮数大于阈值
在调整了聚类中心之后再次进行步骤2,3直到聚类中心调整的幅度小于我们设定的一个阈值,或者循环运行的轮数大于我们的阈值,就认为分类结束。
四、 代码实现
代码主要用于理解算法,有些地方可能不够严谨,还请轻喷??????
因为样本点较少,所以俩个算法运行结果相同,读者可自行增加样本检测
K-means:
1 # kmeans input_data为待分类数据,k为分类类别数 2 def myKmeans(input_data, k): 3 # region 选择类中心 4 index_cls = [] 5while index_cls.__len__() < k: 6 n = np.random.randint(0, input_data.shape[0], 1) 7if n notin index_cls: 8 index_cls.append(n[0]) 9 point_cls = input_data[np.array(index_cls)] # piont_cls为选好的三个聚类中心10# endregion11# region 更新样本点类型12# tag_sample = [-1 for i in range(input_data.shape[0])] # 六个样本点的标签13while True: 14# 计算样本点到聚类中心的欧式距离平方(无需开根号) (x1-x2) ** 2 + (y1 - y2) ** 215# axis = 0 为按行取值,axis = 1 为按列取值16 dis_cls = np.array([np.sum((input_data - i) ** 2, axis=1) for i in point_cls]) # 计算六个点距离三个聚类中心的值,三行六列17# 0: 1 2 3 4 5 618# 1: 6 5 4 2 3 419# 2: 4 4 5 3 4 520# 选取每一列最小值索引作为这个样本点的距离21 min_tag = np.argmin(dis_cls, axis=0) # 选取每一列的最小值(即最小距离),为本次计算样本点的tag22# endregion2324# region 计算新类中心25 new_piont_cls = np.array(list([np.average(input_data[min_tag == i], axis=0) for i in range(k)])) 26# endregion2728# region 计算新类中心的样本类别,做判断,若类别有变化,则更新类别,若不变化,结束算法29# 比较俩个类的中心是否满足一定条件(一般算和小于一定的值)30 gap = np.sum((new_piont_cls - point_cls) ** 2) # 若样本点改变值和小于1,则表示分类结束31if gap < 1: 32break33else: 34 point_cls = new_piont_cls 35# 可以比较样本的类别变化,若样本类别无变化,则停止36# endregion37return min_tag # 返回input_data分类(0,1,2) 三类
K-means++:
1 # kmeans++ input_data为待分类数据,k为分类类别数 2 def myKmeanspp(input_data, k): 3 # region 选择类中心 4 # 选取相距距离最远的点作为聚类中心 5 point_cls = [list([np.random.randint(0, input_data.shape[0]), 1])] 6# 计算第二个点,即获取离选好的类中心点最远的点 7while point_cls.__len__() < k: 8 dis = np.array([sum((input_data[j] - point_cls[i]) ** 2 for i in range(point_cls.__len__())) for j in 9 range(input_data.__len__())]) 10 sample_dis_cls_min = np.min(dis, axis=0) 11 index_max_dis_sample = np.argmax(sample_dis_cls_min) 12 point_cls.append(list(input_data[index_max_dis_sample])) 13 point_cls = np.array(point_cls) 14# endregion15# region 更新样本点类型16# tag_sample = [-1 for i in range(input_data.shape[0])] # 六个样本点的标签17while True: 18# 计算样本点到聚类中心的欧式距离平方(无需开根号) (x1-x2) ** 2 + (y1 - y2) ** 219# axis = 0 为按行取值,axis = 1 为按列取值20 dis_cls = np.array([np.sum((input_data - i) ** 2, axis=1) for i in point_cls]) # 计算六个点距离三个聚类中心的值,三行六列21# 0: 1 2 3 4 5 622# 1: 6 5 4 2 3 423# 2: 4 4 5 3 4 524# 选取每一列最小值索引作为这个样本点的距离25 min_tag = np.argmin(dis_cls, axis=0) # 选取每一列的最小值(即最小距离),为本次计算样本点的tag26# endregion2728# region 计算新类中心29 new_piont_cls = np.array(list([np.average(input_data[min_tag == i], axis=0) for i in range(3)])) 30# endregion3132# region 计算新类中心的样本类别,做判断,若类别有变化,则更新类别,若不变化,结束算法33# 比较俩个类的中心是否满足一定条件(一般算和小于一定的值)34 gap = np.sum((new_piont_cls - point_cls) ** 2) # 若样本点改变值和小于1,则表示分类结束35if gap < 1: 36break37else: 38 point_cls = new_piont_cls 39# 可以比较样本的类别变化,若样本类别无变化,则停止40# endregion41return min_tag
原文:https://www.cnblogs.com/FSeng/p/12199333.html
内容总结
以上是互联网集市为您收集整理的python-Kmeans\Kmeans++算法理解及代码实现全部内容,希望文章能够帮你解决python-Kmeans\Kmeans++算法理解及代码实现所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。