机器学习-Kmeans

news2025/1/16 7:49:27

K-means是一种经典的无监督学习算法,用于对数据进行聚类。K-means算法将数据集视为具有n个特征的n维空间,并尝试通过最小化簇内平方误差的总和来将数据点划分为簇。本文将介绍K-means算法的原理、实现和应用。

定义

  • K-means是一种无监督学习算法,
  • 用于对数据进行聚类。该算法将数据集分为K个簇,每个簇包含最接近其质心的数据点。K-means算法将数据集视为具有n个特征的n维空间,并尝试通过最小化簇内平方误差的总和来将数据点划分为簇。
  • 它是一种迭代算法,通过将每个数据点分配到最近的质心并计算新的质心来迭代地改进簇的质量,直到质心不再变化或达到最大迭代次数为止。

实现流程(k-means算法原理)

K-means算法是一种迭代算法,其基本思想是通过将每个数据点分配到最近的质心,并计算新的质心来迭代地改进簇的质量,直到质心不再变化或达到最大迭代次数为止。具体步骤如下:

  1. 随机选择K个点作为初始质心;
  2. 计算每个数据点与K个质心的距离;
  3. 将数据点划分到距离最近的质心所在的簇;
  4. 对于每个簇,重新计算该簇内所有数据点的均值,将该均值作为新的质心;
  5. 如果质心没有变化,则停止迭代。

K-means算法的核心是将数据点分配到最近的质心所在的簇,这是通过计算每个数据点与K个质心的距离来实现的。一般而言,距离可以使用欧氏距离、曼哈顿距离等来计算。而每个簇的质心则是该簇内所有数据点的均值,用于表示该簇的中心位置。

K值的选择

在K-means算法中,簇的数量k是需要事先指定的。选择合适的簇的数量非常重要。

  1. 手肘法:在不同的k值下运行K-means算法,计算每个簇的误差平方和(SSE),并将其绘制成折线图。通常会发现,随着k值的增加,SSE会逐渐减小。但是,当k值增加到某个值时,SSE的下降速度会变得更加缓慢,形成一个类似手肘的拐点。该拐点所对应的k值就是比较合适的簇的数量。
  2. 轮廓系数法:轮廓系数是一种用于评估聚类结果质量的指标,其取值范围在[-1, 1]之间。对于每个数据点,轮廓系数是其与同簇其他数据点距离的平均值和与最近的不同簇的所有数据点的距离的平均值之差除以两者中的较大值。聚类结果的整体轮廓系数是所有数据点的轮廓系数的平均值。较高的轮廓系数表示聚类效果较好。可以在不同的k值下运行K-means算法,计算聚类结果的整体轮廓系数,选择轮廓系数最大的k值。
  3. 经验法则:在实际应用中,可以根据数据的特点、应用场景等因素,采用经验法则来选择k值。例如,对于图像分割等应用,通常选择k值为2,对于客户分类等应用,通常选择k值为3或4。

需要注意的是,K-means算法可能陷入局部最优解,因此,选择k值需要多次运行算法,比较不同的聚类结果。

创建数据

  • 该代码生成了一个包含1000个数据点的随机数据集,其中有4个簇,每个簇的中心点分别位于(0,0)、(3,3)、(0,3)和(3,0)。每个簇的数据点服从正态分布。最后,用散点图可视化了数据集。可以根据需要调整数据集的大小、簇的数量、中心点的位置等参数。
 
import numpy as np
import matplotlib.pyplot as plt
# 创建数据集
np.random.seed(0)
n_samples = 1000
centers = np.array([[0, 0], [3, 3], [0, 3], [3, 0]])
X = np.zeros((n_samples, 2))
for i in range(len(centers)):
X[i * (n_samples // len(centers)): (i + 1) * (n_samples // len(centers)), :] = \
centers[i] + np.random.randn(n_samples // len(centers), 2)
# 可视化数据集
plt.scatter(X[:, 0], X[:, 1], s=10)
plt.show()

实现k-means

  • 该代码接受一个数据矩阵X、簇的数量k和最大迭代次数max_iter作为输入,返回每个数据点的簇标签和最终的质心坐标。在每次迭代中,先计算每个数据点与k个质心的距离,然后将数据点划分到距离最近的质心所在的簇。接着,对于每个簇,重新计算该簇内所有数据点的均值,将该均值作为新的质心。最后,如果质心没有变化,则停止迭代。
 
import numpy as np
def k_means(X, k, max_iter=100):
# 随机选择k个点作为初始质心
centroids = X[np.random.choice(len(X), k, replace=False)]
for i in range(max_iter):
# 计算每个数据点与k个质心的距离
distances = np.linalg.norm(X[:, np.newaxis, :] - centroids, axis=-1)
# 将数据点划分到距离最近的质心所在的簇
labels = np.argmin(distances, axis=1)
# 对于每个簇,重新计算该簇内所有数据点的均值,将该均值作为新的质心
new_centroids = np.array([X[labels == j].mean(axis=0) for j in range(k)])
# 如果质心没有变化,则停止迭代
if np.allclose(new_centroids, centroids):
break
centroids = new_centroids
return labels, centroids
if __name__ == '__main__':
labels, centroids = k_means(X=X, k=4)
plt.scatter(X[labels==0, 0], X[labels==0, 1], color='r')
plt.scatter(X[labels==1, 0], X[labels==1, 1], color='g')
plt.scatter(X[labels==2, 0], X[labels==2, 1], color='b')
plt.scatter(X[labels==3, 0], X[labels==3, 1])
plt.show()

优化后代码

  • 在此优化后的代码中,我们使用了两个新函数
  • plot_data函数用于绘制划分后的数据集
  • plot_centers函数用于绘制中心点
  • 在主函数中,我们先调用k_means函数得到簇标签和中心点,然后调用plot_data函数绘制划分后的数据集,最后调用plot_centers函数绘制中心点。这样的代码结构使得代码更易读,更易于调试和维护。
 
import numpy as np
import matplotlib.pyplot as plt
# 创建数据集
np.random.seed(0)
n_samples = 1000
centers = np.array([[0, 0], [3, 3], [0, 3], [3, 0]])
X = np.zeros((n_samples, 2))
for i in range(len(centers)):
X[i * (n_samples // len(centers)): (i + 1) * (n_samples // len(centers)), :] = \
centers[i] + np.random.randn(n_samples // len(centers), 2)
# 可视化数据集
def plot_data(X, labels):
plt.scatter(X[labels==0, 0], X[labels==0, 1], color='r')
plt.scatter(X[labels==1, 0], X[labels==1, 1], color='g')
plt.scatter(X[labels==2, 0], X[labels==2, 1], color='b')
plt.scatter(X[labels==3, 0], X[labels==3, 1], color='m')
plt.show()
def plot_centers(centroids):
plt.scatter(centroids[:, 0], centroids[:, 1], s=200, marker='*', color='k')
plt.show()
def k_means(X, k, max_iter=100):
# 随机选择k个点作为初始质心
centroids = X[np.random.choice(len(X), k, replace=False)]
for i in range(max_iter):
# 计算每个数据点与k个质心的距离
distances = np.linalg.norm(X[:, np.newaxis, :] - centroids, axis=-1)
# 将数据点划分到距离最近的质心所在的簇
labels = np.argmin(distances, axis=1)
# 对于每个簇,重新计算该簇内所有数据点的均值,将该均值作为新的质心
new_centroids = np.array([X[labels == j].mean(axis=0) for j in range(k)])
# 如果质心没有变化,则停止迭代
if np.allclose(new_centroids, centroids):
break
centroids = new_centroids
return labels, centroids
if __name__ == '__main__':
labels, centroids = k_means(X=X, k=4)
plot_data(X, labels)
plot_centers(centroids)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/575434.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MongoDB基础到入门(一篇就够了)

文章目录 文章有误请指正,如果觉得对你有用,请点三连一波,蟹蟹支持✨前言MongoDBMongoDB体系结构MongoDB数据模型MongoDB部署安装服务器启动服务器 Shell连接(mongo命令)MongoDB可视化工具MongoDB命令基本常用⭐权限数据库⭐辅助命令⭐集合⭐…

vite的使用

私人博客 许小墨のBlog —— 菜鸡博客直通车 系列文章完整版,配图更多,CSDN博文图片需要手动上传,因此文章配图较少,看不懂的可以去菜鸡博客参考一下配图! 系列文章目录 前端系列文章——传送门 后端系列文章——传送…

抖音seo源代码分享(前端+后端)

后端代码展示: $where [ [name > dvtv_s_id, oper > , value > $this->sid], [name > dvtv_dv_id, oper > , value > $dv_id], ]; $cache_model new App_Model_Douyin_MysqlVideoTempVideoStora…

挂耳式耳机推荐,这几个蓝牙耳机品牌不容错过!

办公的同时享受音乐是释放工作压力的不错途径,对于成为打工人日常配饰的耳机随着无线技术的不断进步也在不断开发新产品。开放式耳机不入耳佩戴有效的降低对耳朵的负担,在不打扰旁人的同时,长时间的佩戴也是对耳朵的考验,不知该如…

29 Vue 中 v-if/show/for 的实现

前言 这是最近的碰到的那个 和响应式相关的问题 特定的操作之后响应式对象不“响应“了 引起的一系列的文章 主要记录的是 vue 的相关实现机制 呵呵 理解本文需要 vue 的使用基础, js 的使用基础 v-if 测试用例 测试用例如下, 主要是一个 if 的使用 这里我们仅仅跟进到…

chatgpt赋能python:Python桌面应用程序:在SEO中的重要性和应用

Python桌面应用程序:在SEO中的重要性和应用 在当今数字时代,拥有一个桌面应用程序成为了非常重要的一件事情,特别是对于那些需要使用软件来完成日常任务的工作人员。而Python作为一种跨平台编程语言,可以帮助开发者编写适用于Win…

chatgpt赋能python:Python换行连接介绍

Python 换行连接介绍 如果你是一个Python初学者,你可能会想知道如何在程序中使用换行连接来使代码更加易读和易于理解。 换行连接是Python编程中一个很重要的概念,也是一个很简单的概念,但是许多初学者经常会犯错误。 在本文中,我…

( 链表) 142. 环形链表 II——【Leetcode每日一题】

❓142. 环形链表 II 难度:中等 给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定…

【测试】软件测试基本概念、软件测试分类、测试工具

文章目录 软件测试的定义概念、目的什么是软件?软件与程序的区别软件测试的定义软件测试的目的软件测试的流程软件测试执行 软件测试分类按照测试阶段分类单元测试集成测试确认测试系统测试验收测试 按照测试方法分类静态测试动态测试黑盒测试白盒测试灰盒测试冒烟测…

算法第四版 Algorithms Part 1动态联通性

联通性检测用途 照片中的像素网络中的计算机社交网络中的朋友计算机芯片中的电路元器件数学集合中的元素Fortan程序中的变量复合体系中的金属位 假定已连接等价于 反身的: p与p本身是连接的.对称的: 如果p连接到q,那么q也链接到p传递的: 如果p连接到q并且q连接到r,那么p连接…

港科夜闻|香港科大近百名创新企业家回归母校庆祝大学首个「独角兽日」

关注并星标 每周阅读港科夜闻 建立新视野 开启新思维 1、香港科大近百名创新企业家回归母校庆祝大学首个「独角兽日」。这些香港科大毕业的创业者,参与创立了五间独角兽企业或上市公司,以及近90间初创企业,包括现正快速崛起、有潜力成为下一间…

【Linux】守护进程(附终端、进程组、会话的介绍)

目录 1、终端2、进程组3、会话4、守护进程 橙色 1、终端 echo $$ 可以查看当前终端进程的id 默认情况下(没有重定向),每个进程的标准输入、标准输出和标准错误输出都指向控制终端、进程从标准输入读也就是读用户的键盘输入,进程往标准输出或标准错误…

PGXC GaussDB

PGXCA PGXC(PostgreSQL eXtended Coordinator)是一个基于 PostgreSQL 架构的分布式数据库解决方案。它扩展了 PostgreSQL,为用户提供了在多个节点上分布式存储和处理数据的能力。 PGXC 的设计目标是将 PostgreSQL 扩展为能够处理大规模数据…

2023 年互联网上 10个最佳联盟营销论坛(付费和免费)

2023 年互联网上 10个最佳联盟营销论坛(付费和免费) 在文章中,我将分享 2023 年的 10 个最佳联盟营销论坛。 您是联盟营销的新手并正在寻找向专业人士学习的地方吗? 您来对地方了,我们赞赏您加入联盟营销论坛的决定…

【C++初阶】9. string类的模拟实现

string类的完整实现放这里啦!快来看看吧 1. string类的成员 string类的作用就是将字符串类型实现更多功能,运算符重载,增删改查等等操作,所以其成员就包含char*的字符串 private:char* _str;size_t _capacity;size_t _size;2. …

三对角矩阵原理及C++实现

一、三对角矩阵 1.三对角矩阵概念 2.三对角矩阵元素数量 对于给定n阶方阵M,若其为三对角矩阵,则元素个数N为: 若n1,此时方阵只有一个元素M[0][0],由定义知该元素也在三对角线上。故N1。若n>1,由三对角…

chatgpt赋能python:Python文件夹的使用和优化

Python 文件夹的使用和优化 文件夹是计算机操作系统中最基本的存储单位之一。在计算机领域,文件夹也被称为目录。文件夹中可以存储多个文件或其他文件夹,使得文件在计算机中可以更好的组织和管理。基于Python语言,我们可以很容易地创建、读取…

javaEE基于springboot的小区社区文化活动报名系统jsp生活服务网站

社区文化宣传网站采用的开发框架为springboot框架,开发工具采用Eclipse,idea 服务器用的是Tomcat。编码语言是Java,数据库采用Mysql数据库。 本社区文化宣传网站,主要服务的用户是社区附近的居民,为居民展示最新的新闻…

带电更换10kV架空线路直线杆绝缘子(绝缘手套作业法)

一、现场复勘 1.核对线路及杆塔号 线路双重名称及杆号无误。 2.检查杆身质量 3.检查电杆埋深 4.检查拉线受力情况 5.检查相邻杆情况 作业点及相邻侧电杆之间导线应无断股等现象。 6.检查气象条件 作业前需进行湿度和风速的测量,风力大于5级,或湿度大…

5分钟搞定验证码

验证码生成 本效果是利用easy-captcha工具包实现&#xff0c;首先需要添加相关依赖到pom.xml中&#xff0c;代码如下&#xff1a; <dependency><groupId>com.github.whvcse</groupId><artifactId>easy-captcha</artifactId><version>1.6…