KMeans 算法深度解析:从原理到实战

一、算法概述:无监督学习的聚类利器​

在机器学习的无监督学习领域,聚类算法是探索数据内在结构的重要工具。KMeans 算法作为划分式聚类的代表,因其简单高效的特性,成为数据科学家工具箱中的必备技能。该算法通过将 n 个数据点划分为 k 个簇,使得每个数据点属于离其最近的均值(簇中心)所在的簇,最终实现 "物以类聚" 的效果。​

核心目标函数​

KMeans 的核心是最小化簇内平方和(Within-Cluster Sum of Squares, WCSS),数学表达式为:​

J(c,μ)=i=1∑k​x∈Ci​∑​∥x−μi​∥2

其中:​

  • ​k是预设的簇数量​
  • ​Ci​是第 i 个簇的样本集合​
  • ​μi​是第 i 个簇的质心(均值向量)​
  • ​c(x)表示样本 x 所属的簇索引​

这个目标函数本质上是寻找 k 个质心,使得所有样本到其所属质心的欧氏距离平方和最小。​

二、算法原理:三步迭代优化过程​

1. 初始化聚类中心(关键第一步)​

传统随机初始化​

最直接的方法是从数据集中随机选取 k 个样本作为初始质心。但这种方法存在明显缺陷:​

  • 可能陷入局部最优(如图 1 所示,不同初始化导致不同聚类结果)​
  • 极端情况下可能产生空簇(当 k > 样本量时)​

KMeans++ 优化初始化(工业级方案)​

步骤如下:​

  1. 随机选择第一个质心​μ1​对于每个样本 x,计算其到最近已选质心的距离​D(x)2​以​D(x)2作为权重,随机选择下一个质心,重复直到选满 k 个​

优点:保证初始质心尽可能分散,提升算法收敛质量,减少局部最优影响。​

2. 分配样本到最近质心(硬聚类过程)​

对于每个样本点​xj​,计算其与所有质心​μi​的欧氏距离:​​

cj​=argi=1..kmin​∥xj​−μi​∥2

将样本分配到距离最小的簇,形成当前划分​{C1​,C2​,...,Ck​}。​

3. 重新计算簇质心(更新迭代中心)​

对每个簇​Ci​,计算所有样本的均值作为新质心:​

​μi(t+1)​=∣Ci​∣1​x∈Ci​∑​x​

重复步骤 2-3,直到质心不再变化或达到最大迭代次数。​

收敛条件​算法终止的两种情况:​

  1. 质心位置稳定:​μi(t+1)​=μi(t)​对所有 i 成立
  2. ​目标函数收敛:​∣J(t+1)−J(t)∣<ϵ(预设极小值)​

三、算法特性:优势与局限性分析​

显著优势​

  1. 计算效率高:时间复杂度为​

    O(nkt),适用于中等规模数据集(n≤10^5)​

  1. 实现简单:核心步骤仅包含距离计算和均值求解,易于工程实现​
  1. 几何意义明确:基于欧氏距离的划分方式符合直观几何理解​

主要局限性​

  1. K 值需预先指定:实际应用中缺乏客观的 K 值确定方法(需结合业务经验或肘部法则)​
  1. 对初始质心敏感:不同初始化可能导致差异较大的聚类结果(需 KMeans++ 等技术优化)​
  1. 对非凸数据不友好:适用于球形簇,对环形、月牙形等非凸分布效果不佳(如图 2 所示)​
  1. 对噪声敏感:离群点会显著影响簇质心计算(可结合离群点检测预处理)​

四、工程实现:从手动编码到 Scikit-learn 实战​

手动实现简化版(Python)​

TypeScript

取消自动换行复制

import numpy as np​

class SimpleKMeans:​

def __init__(self, n_clusters=2, max_iter=100, random_state=42):​

self.k = n_clusters​

self.max_iter = max_iter​

self.centers = None​

def fit(self, X):​

# 初始化质心(随机选择k个样本)​

np.random.seed(self.random_state)​

idx = np.random.choice(len(X), self.k, replace=False)​

self.centers = X[idx]​

for _ in range(self.max_iter):​

# 分配样本​

distances = np.linalg.norm(X[:, None] - self.centers, axis=2)​

labels = np.argmin(distances, axis=1)​

# 更新质心​

new_centers = np.array([X[labels==i].mean(axis=0) for i in range(self.k)])​

# 检查收敛​

if np.allclose(self.centers, new_centers):​

break​

self.centers = new_centers​

return self​

def predict(self, X):​

distances = np.linalg.norm(X[:, None] - self.centers, axis=2)​

return np.argmin(distances, axis=1)​

Scikit-learn 专业实现​

TypeScript

取消自动换行复制

from sklearn.datasets import make_blobs​

from sklearn.cluster import KMeans​

import matplotlib.pyplot as plt​

# 生成模拟数据​

X, y_true = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)​

# 模型训练​

kmeans = KMeans(n_clusters=4, init='k-means++', n_init=10, max_iter=300, random_state=0)​

y_pred = kmeans.fit_predict(X)​

# 结果可视化​

plt.scatter(X[:, 0], X[:, 1], c=y_pred, cmap='viridis', edgecolors='k')​

plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], s=300, c='red', marker='x', label='Centers')​

plt.legend()​

plt.title("KMeans Clustering Result")​

plt.show()​

关键参数解析​

参数名​

含义​

推荐值​

init​

初始化方法​

'k-means++'(默认)​

n_init​

重复初始化次数​

10(默认,自动选择最优结果)​

max_iter​

单次运行最大迭代数​

300(默认)​

tol​

收敛阈值​

1e-4(默认)​

n_clusters​

簇数量​

需业务 / 技术手段确定​

五、进阶技巧:提升聚类效果的关键方法​

1. 确定最佳 K 值​

肘部法则(Elbow Method)​

绘制 WCSS 随 K 值变化曲线,选择曲线拐点(如图 3 所示)。缺点:拐点不明显时难以判断。​

TypeScript

取消自动换行复制

from sklearn.metrics import pairwise_distances_argmin​

wcss = []​

for k in range(1, 11):​

kmeans = KMeans(n_clusters=k, init='k-means++', random_state=42)​

kmeans.fit(X)​

wcss.append(kmeans.inertia_) # inertia_即WCSS​

plt.plot(range(1, 11), wcss, marker='o')​

plt.title('Elbow Method')​

plt.xlabel('Number of clusters')​

plt.ylabel('WCSS')​

plt.show()​

轮廓系数(Silhouette Score)​

计算样本 i 的轮廓系数:​​

s(i)=max(a(i),b(i))b(i)−a(i)​

其中:​

  • a(i):样本 i 到同簇其他样本的平均距离​

  • b(i):样本 i 到最近异簇样本的平均距离​

取值范围 [-1,1],越接近 1 表示聚类效果越好。​

TypeScript

取消自动换行复制

from sklearn.metrics import silhouette_score​

silhouette_scores = []​

for k in range(2, 11):​

kmeans = KMeans(n_clusters=k, init='k-means++', random_state=42)​

labels = kmeans.fit_predict(X)​

silhouette_scores.append(silhouette_score(X, labels))​

plt.plot(range(2, 11), silhouette_scores, marker='o')​

plt.title('Silhouette Score Analysis')​

plt.xlabel('Number of clusters')​

plt.ylabel('Silhouette Score')​

plt.show()​

2. 处理非球形数据​

当数据分布为非凸形状时,可采用:​

  • 核 KMeans(引入核函数将数据映射到高维空间)​
  • DBSCAN 等密度聚类算法(适用于任意形状簇)​

3. 大规模数据优化​

MiniBatchKMeans​

通过随机选取样本子集(mini-batch)计算质心,降低每次迭代计算量,适用于 n>10^5 的场景:​

TypeScript

取消自动换行复制

from sklearn.cluster import MiniBatchKMeans​

mbk = MiniBatchKMeans(n_clusters=4, batch_size=100, random_state=0)​

mbk.fit(X)​

分布式实现​

利用 MapReduce 框架并行计算距离矩阵,常见于 Spark MLlib 的 KMeans 实现。​

六、应用场景:数据驱动的业务实践​

1. 客户分群分析​

通过用户行为数据(消费频率、客单价、互动时长等)划分客户群体,实现精准营销:​

  • 高价值客户(重点维护)​
  • 潜力客户(定向激励)​
  • 沉睡客户(唤醒活动)​

2. 图像分割处理​

将像素点的 RGB 值作为特征进行聚类,实现图像压缩与目标分割(如图 4 所示,左图为原始图像,右图为 4 簇聚类结果)。​

3. 异常检测​

将正常样本聚类后,远离所有簇中心的样本视为异常点(需结合业务阈值调整)。​

4. 文本聚类​

对文档词向量进行聚类,实现新闻分类、主题发现等(需配合 TF-IDF 或 Word2Vec 等特征工程)。​

七、总结与拓展​

KMeans 算法作为聚类分析的入门级算法,虽有一定局限性,但通过合理的初始化方法(KMeans++)、科学的 K 值选择(肘部法则 + 轮廓系数)和针对性优化(MiniBatch),能够在多数实际场景中发挥重要作用。对于复杂数据分布,建议结合层次聚类、密度聚类等算法进行对比分析。​

拓展学习资源​

  1. 算法原理论文:《A comparison of the K-means algorithm and the fuzzy ISODATA algorithm》​
  1. Scikit-learn 官方文档:KMeans​
  1. 可视化工具:D3.js KMeans 演示​

掌握 KMeans 算法不仅是理解无监督学习的重要起点,更能为深入学习 DBSCAN、层次聚类、高斯混合模型等高级聚类算法打下坚实基础。在实际应用中,结合领域知识进行特征工程和结果解读,才能让算法真正发挥数据洞察的价值。

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

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

相关文章

Chrome 浏览器前端与客户端双向通信实战

Chrome 前端&#xff08;即页面 JS / Web UI&#xff09;与客户端&#xff08;C 后端&#xff09;的交互机制&#xff0c;是 Chromium 架构中非常核心的一环。下面我将按常见场景&#xff0c;从通道、流程、技术栈几个角度做一套完整的分析&#xff0c;特别适合你这种在分析和改…

Server2003 B-1 Windows操作系统渗透

任务环境说明&#xff1a; 服务器场景&#xff1a;Server2003&#xff08;开放链接&#xff09; 服务器场景操作系统&#xff1a;Windows7 1.通过本地PC中渗透测试平台Kali对服务器场景Windows进行系统服务及版本扫描渗透测试&#xff0c;并将该操作显示结果中Telnet服务对应的…

渗透实战PortSwigger靶场:lab13存储型DOM XSS详解

进来是需要留言的&#xff0c;先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码&#xff0c;输入的<>当成字符串处理回显到页面中&#xff0c;看来只是把用户输…

使用React+ant Table 实现 表格无限循环滚动播放

数据大屏表格数据&#xff0c;当表格内容超出&#xff08;出现滚动条&#xff09;时&#xff0c;无限循环滚动播放&#xff0c;鼠标移入暂停滚动&#xff0c;鼠标移除继续滚动&#xff1b;数据量小没有超出时不需要滚动。 *使用时应注意&#xff0c;滚动区域高度父元素高度 - 表…

机器人现可完全破解验证码:未来安全技术何去何从?

引言 随着计算机视觉技术的飞速发展&#xff0c;机器学习模型现已能够100%可靠地解决Google的视觉reCAPTCHAv2验证码。这标志着一个时代的结束——自2000年代初以来&#xff0c;CAPTCHA&#xff08;"全自动区分计算机与人类的图灵测试"的缩写&#xff09;一直是区分…

大模型安全测试报告:千问、GPT 全系列、豆包、Claude 表现优异,DeepSeek、Grok-3 与 Kimi 存在安全隐患

大模型安全测试报告&#xff1a;千问、GPT 全系列、豆包、Claude 表现优异&#xff0c;DeepSeek、Grok-3 与 Kimi 存在安全隐患 引言 随着生成式人工智能技术的快速演进&#xff0c;大语言模型&#xff08;LLM&#xff09;正在广泛应用于企业服务、政务系统、教育平台、金融风…

docker 部署redis集群 配置

docker的网络模式 网桥模式每次重启容器都有可能导致容器ip地址变化&#xff0c;需要固定ip的自己自定义网络&#xff0c;这里介绍的是默认网络模式 docker创建容器 docker run --name redis6379 -p 6379:6379 -p 16379:16379 -v /etc/redis/redis6379:/etc/redis -d --r…

LabVIEW的AMC架构解析

此LabVIEW 程序基于消息队列&#xff08;Message Queue&#xff09;机制构建 AMC 架构&#xff0c;核心包含消息生成&#xff08;MessageGenerator &#xff09;与消息处理&#xff08;Message Processor &#xff09;两大循环&#xff0c;通过队列传递事件与指令&#xff0c;实…

数据库管理与高可用-MySQL主从复制与读写分离

目录 #1.1MySQL主从复制原理 1.1.1MySQL支持的复制类型 1.1.2复制的工作过程 #2.1MySQL读写分离原理 2.1.1常见的MySQL读写分离为为两种 #3.1主从复制读写分离的实验案例 1.1MySQL主从复制的原理 MySQL 主从复制是一种常用的数据同步机制&#xff0c;用于将主数据库&#xf…

Python60日基础学习打卡Day45

之前的神经网络训练中&#xff0c;为了帮助理解借用了很多的组件&#xff0c;比如训练进度条、可视化的loss下降曲线、权重分布图&#xff0c;运行结束后还可以查看单张图的推理效果。 如果现在有一个交互工具可以很简单的通过按钮完成这些辅助功能那就好了&#xff0c;他就是…

React项目的状态管理:Redux Toolkit

目录 1、搭建环境 2、Redux Toolkit 包含了什么 3、使用示例 &#xff08;1&#xff09;创建user切片 &#xff08;2&#xff09;合并切片得到store &#xff08;3&#xff09;配置store和使用store 使用js来编写代码&#xff0c;方便理解一些 1、搭建环境 首先&#xf…

父组件prop传向子组件的值,被子组件直接v-model绑定 功能不生效

隐式修改组件属性会导致功能异常 实际操作中发现&#xff0c;即便是父组件把简单数据通过prop传给了子组件&#xff0c;子组件再使用v-model绑定&#xff0c;也不行&#xff0c;响应式还是对异常 原vue2业务中存在组件定义某个类型为Object的属性&#xff0c;然后将该属性对象…

c#bitconverter操作,不同变量类型转byte数组

缘起:串口数据传输的基础是byte数组&#xff0c;write(buff,0,num)或者writeline(string)&#xff0c;如果是字符串传输就是string变量就可以了&#xff0c;但是在modbus这类hex传递时&#xff0c;就要遇到转换了&#xff0c;拼凑byte数组时需要各种变量的值传递&#xff0c;解…

【Redis】set 类型

set 一. set 类型介绍二. set 命令sadd、smembers、sismemberscard、spop、srandmembersmove、srem集合间操作交集&#xff1a;sinter、sinterstore并集&#xff1a;sunion、sunionstore差集&#xff1a;sdiff、sdiffstore 三. set 命令小结四. set 内部编码方式五. set 使用场…

02-Redis常见命令

02-Redis常见命令 Redis数据结构介绍 Redis是一个key-value的数据库&#xff0c;key一般是String类型&#xff0c;不过value的类型多种多样&#xff1a; 贴心小建议&#xff1a;命令不要死记&#xff0c;学会查询就好啦 Redis为了方便学习&#xff0c;将操作不同数据类型的命…

Rk3568驱动开发_GPIO点亮LED_12

需求&#xff1a; 用配置寄存器方式控制点灯非常原始&#xff0c;现在采用更方便的Linux提供的pctrl和gpio子系统编写字符驱动 1.设备树配置&#xff1a; 现将开发板中呼吸灯关闭掉防止占用到我需要使用的引脚 /* Narnat 2025-5-29 RK3568 GPIO 无需设置pinctrl*/gpioled{co…

阿里云ACP云计算备考笔记 (3)——云存储RDS

目录 第一章 云存储概览 1、云存储通用知识 ① 发展历史 ② 云存储的优势 2、云存储分类 3、文件存储业务场景 第二章 块存储 1、块存储分类 2、云盘的优势 3、创建云盘 4、管理数据盘 ① 格式化数据盘 ② 挂载数据盘 ③ 通过 API 挂载云盘 5、管理系统盘 ① 更…

亚矩阵云手机实测体验:稳定流畅背后的技术逻辑​

最近在测试一款云手机服务时&#xff0c;发现亚矩阵的表现出乎意料地稳定。作为一个经常需要多设备协作的开发者&#xff0c;我对云手机的性能、延迟和稳定性要求比较高。经过一段时间的体验&#xff0c;分享一下真实感受&#xff0c;避免大家踩坑。 ​​1. 云手机能解决什么问…

STM32H562----------ADC外设详解

1、ADC 简介 STM32H5xx 系列有 2 个 ADC,都可以独立工作,其中 ADC1 和 ADC2 还可以组成双模式(提高采样率)。每个 ADC 最多可以有 20 个复用通道。这些 ADC 外设与 AHB 总线相连。 STM32H5xx 的 ADC 模块主要有如下几个特性: 1、可配置 12 位、10 位、8 位、6 位分辨率,…

【Android】双指旋转手势

一&#xff0c;概述 本文参考android.view.ScaleGestureDetector&#xff0c;对双指旋转手势做了一层封装&#xff0c;采用了向量计算法简单实现&#xff0c;笔者在此分享下。 二&#xff0c;实例 如下&#xff0c;使用RotateGestureDetector即可委托&#xff0c;实现旋转手…