【ShuQiHere】 K-means 聚类算法详解:公式、代码与实战

🧠 【ShuQiHere】 🎓

目录 📜

  1. [K-means 简介](#K-means 简介)
  2. [K-means 工作原理](#K-means 工作原理)
  3. 理论基础
  4. [K-means 算法步骤](#K-means 算法步骤)
  5. [K-means 的优缺点](#K-means 的优缺点)
  6. [如何选择正确的 K 值](#如何选择正确的 K 值)
  7. [K-means 的改进与变体](#K-means 的改进与变体)
  8. [案例分析:如何使用 K-means 聚类?](#案例分析:如何使用 K-means 聚类?)
  9. 总结

1. K-means 简介 🔍

K-means 是一种常见的无监督学习算法Unsupervised Learning Algorithm ),用于解决聚类Clustering )问题。该算法的目标是将数据集中的 (n) 个数据点分成 (K) 个簇(Clusters),使得同一簇内的数据点之间尽可能相似,而不同簇的数据点尽可能不同。🧑‍🏫

K-means 在市场细分、图像压缩、模式识别等领域得到了广泛应用。其因简单高效而受欢迎,但要充分利用它,理解其工作原理至关重要。


2. K-means 工作原理 🛠️

K-means 通过迭代优化 的方式将数据划分为 (K) 个簇。每个数据点分配到距离最近的簇中心Centroid),并不断更新簇中心的位置,直到结果收敛。

📝 核心概念

  • 簇中心Centroid):簇的中心,通常是簇内所有数据点的平均值。
  • Cluster):由相似数据点构成的组。

3. 理论基础 📊

3.1 目标函数 🎯

K-means 的目标是最小化簇内平方误差和Sum of Squared Errors, SSE),即所有数据点到其对应簇中心的距离平方和。目标函数公式为:

J = ∑ k = 1 K ∑ x i ∈ C k ∣ ∣ x i − μ k ∣ ∣ 2 J = \sum_{k=1}^{K} \sum_{x_i \in C_k} ||x_i - \mu_k||^2 J=k=1∑Kxi∈Ck∑∣∣xi−μk∣∣2

其中:

  • (x_i) 表示每个数据点;
  • (\mu_k) 表示第 (k) 个簇的簇中心;
  • (C_k) 表示第 (k) 个簇中的所有数据点。

该函数的目的是使每个簇内部的数据点尽可能接近其簇中心,从而减少簇内的"离散度"。

3.2 距离度量 🏃‍♂️

K-means 通常使用欧几里得距离Euclidean Distance)来计算数据点到簇中心的距离:

d ( x i , μ k ) = ∑ j = 1 n ( x i j − μ k j ) 2 d(x_i, \mu_k) = \sqrt{\sum_{j=1}^{n}(x_{ij} - \mu_{kj})^2} d(xi,μk)=j=1∑n(xij−μkj)2

其中:

  • (x_{ij}) 和 (\mu_{kj}) 分别是数据点 (x_i) 和簇中心 (\mu_k) 的第 (j) 个特征;
  • (n) 是数据的维度。

欧几里得距离是最常用的距离度量方法,它通过计算两个点在多维空间中的直线距离来度量相似性。


4. K-means 算法步骤 📝

下面是 K-means 聚类的详细步骤:

  1. 初始化 🌱:随机从数据集中选择 (K) 个点作为初始簇中心。这些点将作为初始簇的中心点。

  2. 分配簇 📌:对每个数据点,计算其到每个簇中心的距离,并将其分配到最近的簇。

  3. 更新簇中心 🔄:对于每个簇,重新计算簇内所有数据点的均值作为新的簇中心:

μ k = 1 ∣ C k ∣ ∑ x i ∈ C k x i \mu_k = \frac{1}{|C_k|}\sum_{x_i \in C_k} x_i μk=∣Ck∣1xi∈Ck∑xi

  1. 重复迭代 🔁:重复步骤 2 和 3,直到簇中心不再发生变化或达到预设的迭代次数。

4.1 具体代码实现 💻

python 复制代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans

# 生成测试数据
X, y = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)

# 可视化数据
plt.scatter(X[:, 0], X[:, 1])
plt.show()

# 使用 K-means 聚类
kmeans = KMeans(n_clusters=4)
kmeans.fit(X)
y_kmeans = kmeans.predict(X)

# 绘制聚类结果
plt.scatter(X[:, 0], X[:, 1], c=y_kmeans, s=50, cmap='viridis')

centers = kmeans.cluster_centers_
plt.scatter(centers[:, 0], centers[:, 1], c='red', s=200, alpha=0.75)
plt.show()

📊 代码解释

  • make_blobs() 函数生成具有多个中心的测试数据;
  • 使用 KMeans() 函数对数据进行 K-means 聚类;
  • 通过 fit() 方法训练模型,predict() 方法预测簇;
  • 最后可视化数据及其簇中心。

5. K-means 的优缺点 ⚖️

优点 🌟:

  1. 简单高效:K-means 易于实现,并且在大数据集上效率较高。
  2. 扩展性好:算法对大规模数据集的处理表现优越,时间复杂度为 (O(n \cdot K \cdot I \cdot d)),其中 (I) 是迭代次数,(d) 是特征数。

缺点 ⚠️:

  1. 对初始值敏感 :簇中心的随机选择可能导致局部最优解。💡 推荐使用 K-means++ 进行初始化。
  2. 需预设 K 值:需要事先指定簇的数量,这在实际应用中可能较难确定。
  3. 对异常值敏感:异常值可能极大影响簇中心,导致聚类结果偏差。
  4. 假设簇为凸形:K-means 假设簇是球形的,无法处理复杂形状的簇。

6. 如何选择正确的 K 值 🧠

选择合适的 (K) 值是 K-means 聚类的一个关键问题。以下是几种常用的方法:

  1. 肘部法 💪:绘制不同 (K) 值对应的 SSE 曲线,寻找"肘部"位置,该点通常是一个较好的 (K) 值。

  2. 轮廓系数 👤:用于评估聚类效果,取值范围为 ([-1, 1]),值越大表示聚类效果越好。

  3. Gap Statistic 📈:通过比较聚类的 SSE 与随机数据集的 SSE,选择能最大化差距的 (K) 值。


7. K-means 的改进与变体 🚀

为了解决 K-means 的一些局限性,出现了若干改进方法:

  1. K-means++ 🎯:改进了初始簇中心的选择,能显著减少局部最优解的可能性,收敛速度更快。

  2. Mini-batch K-means ⚡:在每次迭代中只使用数据的一个子集,极大提升了处理大规模数据时的速度。

  3. 模糊 C 均值 🤹‍♂️:允许每个数据点属于多个簇,并为每个簇分配一个

隶属度,从而解决了硬分配的局限性。


8. 案例分析:如何使用 K-means 聚类? 🔍

📝 问题描述

假设我们有一组客户购买数据,想通过 K-means 聚类识别不同的客户群体,进而制定更精准的营销策略。

🔧 步骤

  1. 数据准备:首先收集客户的购买金额和购买频率数据。

  2. 预处理:对数据进行标准化处理,以确保不同量纲的特征对聚类结果的影响是均衡的。

  3. K-means 聚类 :使用 KMeans() 函数对数据进行聚类,选择 (K=4)。

  4. 结果分析:通过聚类结果,可以识别出低频低消费、高频高消费等不同的客户群体,并针对性地制定促销策略。

📊 代码实现

python 复制代码
from sklearn.preprocessing import StandardScaler

# 标准化数据
scaler = StandardScaler()
data_scaled = scaler.fit_transform(customer_data)

# 聚类分析
kmeans = KMeans(n_clusters=4)
kmeans.fit(data_scaled)
labels = kmeans.predict(data_scaled)

# 输出聚类标签
print(labels)

通过这种方式,我们能够快速地将客户群体分为若干簇,并进一步分析每个簇的消费习惯和购买行为。


9. 总结 🏁

K-means 聚类是一种简单但强大的工具,用于将数据集划分为有意义的组别。虽然它有一些局限性,比如对初始点敏感、无法处理复杂形状的簇等,但通过改进方法(如 K-means++)和正确选择 (K) 值,可以大大提高算法的性能。

🚀 最佳实践提示:在应用 K-means 时,建议先对数据进行可视化,采用 K-means++ 初始化策略,并通过肘部法或轮廓系数等方法选择合适的 (K) 值。


进一步阅读 📚


希望这篇博客对你有帮助!如果有任何问题或建议,欢迎在评论区讨论。 🎉

相关推荐
网易独家音乐人Mike Zhou2 小时前
【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)
c语言·python·单片机·物联网·算法·嵌入式·iot
Swift社区6 小时前
LeetCode - #139 单词拆分
算法·leetcode·职场和发展
Kent_J_Truman7 小时前
greater<>() 、less<>()及运算符 < 重载在排序和堆中的使用
算法
IT 青年7 小时前
数据结构 (1)基本概念和术语
数据结构·算法
Dong雨7 小时前
力扣hot100-->栈/单调栈
算法·leetcode·职场和发展
SoraLuna8 小时前
「Mac玩转仓颉内测版24」基础篇4 - 浮点类型详解
开发语言·算法·macos·cangjie
liujjjiyun8 小时前
小R的随机播放顺序
数据结构·c++·算法
¥ 多多¥8 小时前
c++中mystring运算符重载
开发语言·c++·算法
trueEve9 小时前
SQL,力扣题目1369,获取最近第二次的活动
算法·leetcode·职场和发展
天若有情6739 小时前
c++框架设计展示---提高开发效率!
java·c++·算法