news 2026/9/13 12:56:40

K-means聚类算法原理与Python实现详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
K-means聚类算法原理与Python实现详解

1. K-means算法核心原理剖析

K-means作为最经典的聚类算法之一,其核心思想可以用一个生活场景来理解:假设你要把一堆杂乱的衣物按颜色分类,但事先不知道有多少种主色调。你会先随机选定几个颜色中心点(比如红、蓝、绿),然后每件衣服都归到最近的中心点,接着重新计算每个颜色组的平均色作为新中心,不断重复直到中心点不再移动——这就是K-means的具象化体现。

1.1 数学建模过程

算法通过最小化平方误差函数实现聚类目标:

J = ΣΣ ||x - μ_i||²

其中x是样本点,μ_i是第i个簇的中心。这个目标函数使得簇内距离最小化,通过以下步骤迭代优化:

  1. 随机初始化K个质心(cluster centroids)
  2. 计算每个样本到质心的欧氏距离
  3. 将样本分配到最近的质心所属簇
  4. 重新计算每个簇的质心(均值点)
  5. 重复2-4步直到质心变化小于阈值或达到最大迭代次数

关键点:欧氏距离计算采用标准的L2范数公式,这也是K-means对球形分布数据效果好的原因。

1.2 算法特性与局限

优势维度:

  • 时间复杂度O(nkt),适合大规模数据(n样本数,k簇数,t迭代次数)
  • 实现简单且容易并行化
  • 对密集的球形簇结构效果显著

典型局限:

  • 需要预先指定K值(可通过肘部法则确定)
  • 对噪声和离群点敏感
  • 初始质心选择影响结果(可通过k-means++优化)
  • 只能发现凸形簇,对带状分布效果差

2. 手撕K-means解题全流程

2.1 经典例题演示

给定数据集:

A(1,1), B(1,2), C(2,2), D(5,4), E(6,5), F(6,6), G(7,5)

要求分为2类(K=2),初始质心选A(1,1)和D(5,4)。

第一轮迭代:

  1. 计算所有点到质心的距离:
    • 到A的距离:A(0), B(1), C(1.41), D(5), E(6.4), F(6.7), G(7.2)
    • 到D的距离:A(5), B(4.24), C(3.6), D(0), E(1.41), F(2.23), G(2.23)
  2. 分配结果:
    • 簇1:A,B,C
    • 簇2:D,E,F,G
  3. 更新质心:
    • 新质心1:( (1+1+2)/3, (1+2+2)/3 ) = (1.33, 1.67)
    • 新质心2:( (5+6+6+7)/4, (4+5+6+5)/4 ) = (6, 5)

第二轮迭代:重新计算距离后,簇分配不变,算法收敛。最终聚类结果:

  • 簇1:A,B,C
  • 簇2:D,E,F,G

2.2 解题技巧备忘录

  1. 距离矩阵法:建议先构建距离矩阵避免重复计算
  2. 质心更新验证:每次更新后检查是否仍在样本空间内
  3. 终止条件设定:常用Δ质心位置<1e-4或迭代次数>100
  4. 空簇处理:当某簇无样本时,可重新选择最远点作为新质心

3. Python实现与工程实践

3.1 原生代码实现

import numpy as np def k_means(X, k, max_iters=100): # 随机初始化质心 centroids = X[np.random.choice(len(X), k, replace=False)] for _ in range(max_iters): # 分配样本到最近质心 distances = np.sqrt(((X - centroids[:, np.newaxis])**2).sum(axis=2)) labels = np.argmin(distances, axis=0) # 更新质心 new_centroids = np.array([X[labels==i].mean(axis=0) for i in range(k)]) # 收敛判断 if np.allclose(centroids, new_centroids): break centroids = new_centroids return labels, centroids # 示例数据 data = np.array([[1,1],[1,2],[2,2],[5,4],[6,5],[6,6],[7,5]]) labels, centers = k_means(data, k=2) print("Cluster labels:", labels) print("Final centers:", centers)

3.2 工业级优化方案

  1. 使用sklearn的MiniBatchKMeans处理大数据:
from sklearn.cluster import MiniBatchKMeans mbk = MiniBatchKMeans(n_clusters=2, batch_size=100) mbk.fit(data)
  1. 特征标准化最佳实践:
from sklearn.preprocessing import StandardScaler scaler = StandardScaler() X_scaled = scaler.fit_transform(X)
  1. 并行计算配置:
KMeans(n_clusters=3, n_init=10, n_jobs=-1) # n_jobs=-1使用所有CPU核心

4. 实战避坑指南

4.1 参数选择黄金法则

  1. K值确定方法对比:

    方法实现方式适用场景
    肘部法则观察SSE下降拐点数据分布明显
    轮廓系数计算样本与其簇的相似度各类形状簇
    Gap Statistic比较实际数据与参考分布噪声较多数据
  2. 初始质心优化:

# k-means++初始化 from sklearn.cluster import KMeans kmeans = KMeans(n_clusters=3, init='k-means++')

4.2 典型问题解决方案

问题1:聚类结果不稳定

  • 方案:设置random_state参数固定随机种子
  • 代码:
KMeans(n_clusters=3, random_state=42)

问题2:存在离群点干扰

  • 方案1:使用DBSCAN预处理去除噪声点
  • 方案2:改用K-medoids算法(基于中心点而非均值)

问题3:高维数据效果差

  • 降维处理:
from sklearn.decomposition import PCA pca = PCA(n_components=0.95) # 保留95%方差 X_reduced = pca.fit_transform(X)

5. 进阶应用场景

5.1 图像颜色量化

from sklearn.utils import shuffle image = plt.imread('flower.jpg') w, h, d = image.shape image_array = shuffle(image.reshape(w*h, d), n_samples=1000) kmeans = KMeans(n_clusters=64).fit(image_array) new_colors = kmeans.cluster_centers_[kmeans.predict(image.reshape(w*h, d))] plt.imshow(new_colors.reshape(w, h, d))

5.2 用户分群实战

电商用户RFM聚类:

  1. 特征工程:
    • R(最近购买时间)
    • F(购买频率)
    • M(消费金额)
  2. 三维特征标准化
  3. 寻找最佳K值:
from sklearn.metrics import silhouette_score scores = [] for k in range(2,8): kmeans = KMeans(n_clusters=k).fit(rfm_data) scores.append(silhouette_score(rfm_data, kmeans.labels_)) optimal_k = np.argmax(scores) + 2 # 索引偏移补偿

工程经验:商业场景中常结合业务知识调整聚类结果,比如将高价值用户单独细分。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 12:53:05

单机无穷大系统仿真:从Simulink建模到暂态稳定分析

简介&#xff1a;单机无穷大系统是电力系统暂态稳定性分析的经典简化模型&#xff0c;这份MATLAB脚本仿真代码面向电力系统专业学生、研究人员及工程技术人员&#xff0c;用于研究一台发电机经无穷大母线接入电网时的功率振荡与稳定恢复特性。压缩包内仅含1个m文件&#xff0c;…

作者头像 李华
网站建设 2026/9/13 12:52:43

泰克示波器OpenChoice通信原理与VISA驱动深度排错指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/13 12:51:48

Gopeed 本地开发如何启动 API 后端与 Flutter 前端进行联调?

Gopeed 本地开发如何启动 API 后端与 Flutter 前端进行联调&#xff1f; 【免费下载链接】gopeed A fast, modern download manager for HTTP, BitTorrent, Magnet, and ed2k. Cross-platform, built with Golang and Flutter. 项目地址: https://gitcode.com/GitHub_Trendi…

作者头像 李华
网站建设 2026/9/13 12:49:30

Next.js + LangChain.js 构建前端可控AI Agent实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/13 12:47:55

Lithe-IDEA:面向Java开发者的轻量级开源IDE重构实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华