不足 20 行 Python 代码,高效实现 k-means 均值聚类算法
off999 2024-11-05 10:53 37 浏览 0 评论
作者 | 许文武
责编 | 郭芮
出品 | CSDN 博客
scikti-learn 将机器学习分为4个领域,分别是分类(classification)、聚类(clustering)、回归(regression)和降维(dimensionality reduction)。k-means均值算法虽然是聚类算法中比较简单的一种,却包含了丰富的思想内容,非常适合作为初学者的入门习题。
关于 k-means 均值聚类算法的原理介绍、实现代码,网上有很多,但运行效率似乎都有点问题。今天稍微有点空闲,写了一个不足20行的 k-means 均值聚类算法,1万个样本平均耗时20毫秒(10次均值)。同样的数据样本,网上流行的算法平均耗时3000毫秒(10次均值)。差距竟然达百倍以上,令我深感意外,不由得再次向 numpy 献上膝盖!
以下是我的代码,包含注释、空行总共26行,有效代码16行。
1import numpy as np
2
3def kmeans_xufive(ds, k):
4 """k-means聚类算法
5
6 k - 指定分簇数量
7 ds - ndarray(m, n),m个样本的数据集,每个样本n个属性值
8 """
9
10 m, n = ds.shape # m:样本数量,n:每个样本的属性值个数
11 result = np.empty(m, dtype=np.int) # m个样本的聚类结果
12 cores = np.empty((k, n)) # k个质心
13 cores = ds[np.random.choice(np.arange(m), k, replace=False)] # 从m个数据样本中不重复地随机选择k个样本作为质心
14
15 while True: # 迭代计算
16 d = np.square(np.repeat(ds, k, axis=0).reshape(m, k, n) - cores)
17 distance = np.sqrt(np.sum(d, axis=2)) # ndarray(m, k),每个样本距离k个质心的距离,共有m行
18 index_min = np.argmin(distance, axis=1) # 每个样本距离最近的质心索引序号
19
20 if (index_min == result).all: # 如果样本聚类没有改变
21 return result, cores # 则返回聚类结果和质心数据
22
23 result[:] = index_min # 重新分类
24 for i in range(k): # 遍历质心集
25 items = ds[result==i] # 找出对应当前质心的子样本集
26 cores[i] = np.mean(items, axis=0) # 以子样本集的均值作为当前质心的位置这是网上比较流行的 k-means 均值聚类算法代码,包含注释、空行总共57行,有效代码37行。
1import numpy as np
2
3# 加载数据
4def loadDataSet(fileName):
5 data = np.loadtxt(fileName,delimiter='\t')
6 return data
7
8# 欧氏距离计算
9 def distEclud(x,y):
10 return np.sqrt(np.sum((x-y)**2)) # 计算欧氏距离
11
12# 为给定数据集构建一个包含K个随机质心的集合
13 def randCent(dataSet,k):
14 m,n = dataSet.shape
15 centroids = np.zeros((k,n))
16 for i in range(k):
17 index = int(np.random.uniform(0,m)) #
18 centroids[i,:] = dataSet[index,:]
19 return centroids
20
21# k均值聚类
22def kmeans_open(dataSet,k):
23
24 m = np.shape(dataSet)[0] #行的数目
25 # 第一列存样本属于哪一簇
26 # 第二列存样本的到簇的中心点的误差
27 clusterAssment = np.mat(np.zeros((m,2)))
28 clusterChange = True
29
30 # 第1步 初始化centroids
31 centroids = randCent(dataSet,k)
32 while clusterChange:
33 clusterChange = False
34
35 # 遍历所有的样本(行数)
36 for i in range(m):
37 minDist = 100000.0
38 minIndex = -1
39
40 # 遍历所有的质心
41 #第2步 找出最近的质心
42 for j in range(k):
43 # 计算该样本到质心的欧式距离
44 distance = distEclud(centroids[j,:],dataSet[i,:])
45 if distance < minDist:
46 minDist = distance
47 minIndex = j
48 # 第 3 步:更新每一行样本所属的簇
49 if clusterAssment[i,0] != minIndex:
50 clusterChange = True
51 clusterAssment[i,:] = minIndex,minDist**2
52 #第 4 步:更新质心
53 for j in range(k):
54 pointsInCluster = dataSet[np.nonzero(clusterAssment[:,0].A == j)[0]] # 获取簇类所有的点
55 centroids[j,:] = np.mean(pointsInCluster,axis=0) # 对矩阵的行求均值
56
57 return clusterAssment.A[:,0], centroids函数create_data_set,用于生成测试数据。可变参数 cores 是多个三元组,每一个三元组分别是质心的x坐标、y坐标和对应该质心的数据点的数量。
1def create_data_set(*cores):
2 """生成k-means聚类测试用数据集"""
3
4 ds = list
5 for x0, y0, z0 in cores:
6 x = np.random.normal(x0, 0.1+np.random.random/3, z0)
7 y = np.random.normal(y0, 0.1+np.random.random/3, z0)
8 ds.append(np.stack((x,y), axis=1))
9
10 return np.vstack(ds)测试代码如下:
1import time
2import matplotlib.pyplot as plt
3
4k = 4
5ds = create_data_set((0,0,2500), (0,2,2500), (2,0,2500), (2,2,2500))
6
7t0 = time.time
8result, cores = kmeans_xufive(ds, k)
9t = time.time - t0
10
11plt.scatter(ds[:,0], ds[:,1], s=1, c=result.astype(np.int))
12plt.scatter(cores[:,0], cores[:,1], marker='x', c=np.arange(k))
13plt.show
14
15print(u'使用kmeans_xufive算法,1万个样本点,耗时%f0.3秒'%t)
16
17t0 = time.time
18result, cores = kmeans_open(ds, k)
19t = time.time - t0
20
21plt.scatter(ds[:,0], ds[:,1], s=1, c=result.astype(np.int))
22plt.scatter(cores[:,0], cores[:,1], marker='x', c=np.arange(k))
23plt.show
24
25print(u'使用kmeans_open算法,1万个样本点,耗时%f0.3秒'%t)
测试结果如下:
1PS D:\XufiveGit\CSDN\code> py -3 .\k-means.py
2使用kmeans_xufive算法,1万个样本点,耗时0.0156550.3秒
3使用kmeans_open算法,1万个样本点,耗时3.9990890.3秒效果如下:
作者:许文武,博客昵称「天元浪子」,本文首发于作者CSDN博客https://blog.csdn.net/xufive/article/details/101448969。
【END】
相关推荐
- win10专业版不激活有什么影响
-
如果Windows10专业版未激活,您将面临以下问题:1.桌面背景将变为黑色,无法更改。2.您将无法自定义主题和颜色。3.您将无法使用个性化设置,如锁屏图片和屏幕保护程序。4.您将无法接收W...
- 企业qq最新版官方下载(企业qqapp下载)
-
你好,企业微信需要下载的,手机端需要下载企业微信APP。企业微信,是腾讯微信团队为企业打造的专业办公管理工具。与微信一致的沟通体验,丰富免费的OA应用,并与微信消息、小程序、微信支付等互通,助力企业高...
-
- huifuqqcom 官方网站(huifu.qq.com)
-
qq恢复官方网站,http://huifu.qq.com/1、什么是QQ恢复系统?QQ恢复系统是腾讯公司提供的一项找回QQ联系人、QQ群的服务,向所有QQ用户免费开放。2、QQ恢复系统能恢复多长时间内删除的好友?普通用户可以申请恢复3个月内...
-
2025-12-19 16:51 off999
- 优启通u盘装win7(优启通重装win7)
-
如果安装windows7视窗操作系统,推荐使用ACHI硬盘模式,可以提高SATA硬盘的读写速度,比传统IDE模式大约提高了10%-30%。硬盘的读写速度提高,相对的噪音也会大一些,如果不需要进行大量数...
- pp助手苹果版下载安装(pp助手软件下载安装苹果)
-
Ipad上不能直接下载PP助手进行安装,会提示失败。方法如下:1.将Ipad用数据线与电脑连接,然后按照电脑端的pp助手。2.然后进入电脑端的pp助手,可以看到选项,安装pp助手到Ipad上。...
- 如何关闭uac(如何关闭uac权限)
-
1.使用电脑快捷键WIN+R打开运行窗口,窗口内输入"msconfig"。2.在打开的窗口选项卡中点击“工具”按钮,在下拉栏里找到“更改UAC通知”选项,点击下方的“启动”按钮。3...
- 轻启动激活码永久(轻启动解锁版)
-
如果您的WindowsXP轻启动一直无法激活,可能是由于多种原因导致的。首先,请确保您的网络连接正常,并且您的计算机的日期和时间设置正确。其次,确保您输入的产品密钥是正确的,并且与您的操作系统版本相...
- msdn下载系统靠谱吗(msdn下载安装)
-
秋叶系统好用,自动激活的,而且非常流畅。。。MSDN下载的系统驱动具有普遍兼容性,一般硬件商提供的更好MSDN下载的系统需要激活。原版系统意味着没有任何激活和授权,需要自己有激活密钥序列号,否则30...
- 赛格电脑城买电脑靠谱吗(赛格电脑城的电脑为什么便宜)
-
西安赛格电脑城的东西质量好,可信。1、赛格是整个西安,至整个陕西,乃至整个西北地区,最大的电子产品集散地,便宜实惠很靠谱。只要去到赛格正规的柜台去买东西产品,都没有问题。2、西安赛格电脑商城总建筑面积...
- ins加速器永久免费版(加速器免费加速steam)
-
①通常来说这种软件是为了让用户使用某些软件平台可以获得更好的使用体验而推出来的。②其次部分软件因某些原因。而不得不做出这种选择。③同时这种软件也会对用户在设备中使用的网络线路进行改善。让用户可以更好的...
-
- 系统集成项目管理工程师是干什么的
-
首先,有这个证书对于你从事IT行业有很大的好处。如果同样学历、同样经验的人员应聘同一家IT企业,如果你有这个证书,那么你的录取率将会大大地增加,同时你还可以为自己争取一个比较理想的薪水(前提是你确实是有一定的项目管理实践的基础上)。其次,可...
-
2025-12-19 12:03 off999
- 设置自动关机不显示提示窗口
-
一.首先我们要处理掉一个可能性到"我的电脑按"右键-->属性-->高级-->按下"启动及修复"-->把下面"系统失败"那框框的三个选项取消勾选.当把这三个选择取消后.能解决大部...
欢迎 你 发表评论:
- 一周热门
-
-
抖音上好看的小姐姐,Python给你都下载了
-
全网最简单易懂!495页Python漫画教程,高清PDF版免费下载
-
Python 3.14 的 UUIDv6/v7/v8 上新,别再用 uuid4 () 啦!
-
飞牛NAS部署TVGate Docker项目,实现内网一键转发、代理、jx
-
python入门到脱坑 输入与输出—str()函数
-
宝塔面板如何添加免费waf防火墙?(宝塔面板开启https)
-
Python三目运算基础与进阶_python三目运算符判断三个变量
-
(新版)Python 分布式爬虫与 JS 逆向进阶实战吾爱分享
-
失业程序员复习python笔记——条件与循环
-
系统u盘安装(win11系统u盘安装)
-
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python进度条 (67)
- python吧 (67)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python列表切片 (59)
- python面向对象编程 (60)
- python 代码加密 (65)
- python串口编程 (77)
- python封装 (57)
- python写入txt (66)
- python读取文件夹下所有文件 (59)
- python操作mysql数据库 (66)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)
