宝子们👋,欢迎再次来到我的优快云技术分享小天地!在之前的一系列博客里,咱们已经深入探讨了多种K-means的优化算法,像基础的K-means算法、借助Canopy算法优化初始点的Canopy + K-means算法、改进初始中心选择的K-means++算法、通过二分策略优化聚类的二分K-means算法、能自动调整聚类数的ISODATA算法,还有能处理非线性数据的Kernel K-means算法。每一种算法都有其独特的魅力和适用场景🎉。今天,咱们要聚焦的Mini-batch K-Means算法,可是在大规模数据聚类领域大放异彩的“明星”算法哦👏!
📚 回顾与关联
先带大家简单回顾下之前提到的几种算法:
- K-means算法:简单直接,通过不断迭代把数据点分配到最近的聚类中心,但容易陷入局部最优,对初始中心点敏感,而且在处理大规模数据时计算开销大。👇点击回顾K-means算法原理
- Canopy + K-means算法:先用Canopy算法粗略聚类确定初始中心点,再用K-means精确聚类,提升了聚类效率和准确性,但面对超大规模数据,计算压力依然不小。👇点击回顾Canopy + K-means算法原理
- K-means++算法:精心挑选初始中心点,让初始中心分布更均匀,聚类效果更好,不过大规模数据下,初始中心点的选择过程也会变慢。👇点击回顾K-means++算法原理
- 二分K-means算法:通过不断二分聚类来优化结果,避免了随机初始化的不稳定,但在大规模数据上,迭代次数可能增多,计算时间变长。👇点击回顾二分K-means算法原理
- ISODATA算法:在K-means基础上增加了合并和分裂
操作,能自动调整聚类数量,但在大规模数据下,这些操作的计算复杂度也会显著增加。👇点击回顾ISODATA算法原理 - Kernel K-means算法:通过核函数把数据映射到高维空间,处理非线性数据能力强,但核函数的计算和存储在大规模数据下会消耗大量资源。👇点击回顾Kernel K-means算法原理
而Mini-batch K-Means算法则是从计算效率的角度对K-means进行优化,它特别适合处理大规模数据集,能显著减少计算时间和内存占用🎊。
💡 Mini-batch K-Means算法原理
Mini-batch K-Means算法的核心思想是在每次迭代中,不使用全部数据来更新聚类中心,而是随机抽取一小批数据(称为mini-batch)来进行更新。这样做的好处是大大减少了每次迭代的计算量,同时还能在一定程度上保证聚类的准确性。虽然每次只使用部分数据,但通过多次迭代,算法能够逐渐收敛到较好的聚类结果😃。
📈 算法步骤
- 初始化:随机选择𝑘个数据点作为初始聚类中心𝑐₁,𝑐₂,…,𝑐ₖ。
- 循环迭代:
- 抽取mini-batch:从数据集中随机抽取一个大小为𝑏的mini-batch(𝑏通常远小于数据集的大小)。
- 分配数据点:对于mini-batch中的每个数据点𝑥ᵢ,计算它与各个聚类中心的距离,并将其分配到距离最近的聚类中心所对应的簇中。距离的计算公式和普通K-means一样,为:
d(xi,cj)=∥xi−cj∥2 - 更新聚类中心:对于每个簇,根据mini-batch中属于该簇的数据点来更新聚类中心。新的聚类中心𝑐ⱼ的计算公式为:
cj=nj,new+count(xi∈mini-batch,xi∈Cj)nj,new⋅cj+∑xi∈mini-batch,xi∈Cjxi
其中,𝑛_{𝑗,new}是上一次迭代后簇𝐶ⱼ中数据点的数量,count(𝑥ᵢ ∈ mini-batch, 𝑥ᵢ ∈ 𝐶ⱼ)是mini-batch中属于簇𝐶ⱼ的数据点数量。
- 重复步骤2:直到聚类中心不再发生明显变化或达到最大迭代次数。
🎯 优缺点
优点:
- 计算效率高:由于每次只使用部分数据进行计算,大大减少了计算时间和内存占用,特别适合大规模数据集。
- 可扩展性强:可以轻松地处理海量数据,并且能够并行化处理,进一步提高计算效率。
缺点:
- 聚类结果可能不稳定:由于每次迭代使用的数据是随机抽取的,所以聚类结果可能会受到随机性的影响,存在一定的波动。
- 对mini-batch大小敏感:mini-batch的大小选择会影响聚类的准确性和计算效率,需要合适的参数调优。
🌐 适用场景
- 大规模数据聚类:(电商/金融场景)如用户行为数据分析、图像数据聚类等,数据量非常大,使用普通K-means算法计算成本过高。
-
from sklearn.cluster import MiniBatchKMeans # 10万用户画像聚类 model = MiniBatchKMeans(n_clusters=5, batch_size=500, init='k-means++') model.fit(user_embeddings)
- 实时数据处理:(网络安全场景)在一些需要实时聚类的场景中,如流数据处理,Mini-batch K-Means可以快速处理新到达的数据。
-
# 流式数据逐步更新 for i in range(0, len(logs), 1000): batch = logs[i:i+1000] model.partial_fit(batch) # 增量训练
-
图像颜色量化(计算机视觉应用)
-
from sklearn.utils import shuffle # 对像素采样 pixels = image.reshape(-1, 3) sample = shuffle(pixels, n_samples=10000) # 训练颜色聚类 kmeans = MiniBatchKMeans(n_clusters=64).fit(sample) new_image = kmeans.cluster_centers_[kmeans.predict(pixels)]
💻 场景示例代码
下面我们使用Python的scikit-learn库来实现Mini-batch K-Means算法,并对一个大规模数据集进行聚类。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.cluster import MiniBatchKMeans, KMeans
from time import time
# 生成大规模数据集
n_samples = 100000
n_features = 2
n_clusters = 5
X, y = make_blobs(n_samples=n_samples, n_features=n_features, centers=n_clusters, random_state=42)
# 使用Mini-batch K-Means进行聚类
batch_size = 1000
mbk = MiniBatchKMeans(init='k-means++', n_clusters=n_clusters, batch_size=batch_size,
n_init=10, max_no_improvement=10, verbose=0, random_state=42)
start_time = time()
mbk_labels = mbk.fit_predict(X)
mbk_time = time() - start_time
# 使用普通K-means进行聚类作为对比
kmeans = KMeans(init='k-means++', n_clusters=n_clusters, n_init=10, random_state=42)
start_time = time()
kmeans_labels = kmeans.fit_predict(X)
kmeans_time = time() - start_time
# 可视化结果(由于数据量大,我们只展示部分数据)
plt.figure(figsize=(12, 5))
plt.subplot(1, 2, 1)
plt.scatter(X[:1000, 0], X[:1000, 1], c=mbk_labels[:1000], cmap='viridis')
plt.scatter(mbk.cluster_centers_[:, 0], mbk.cluster_centers_[:, 1], c='red', marker='x', s=100)
plt.title(f'Mini-batch K-Means\nTime: {mbk_time:.2f}s')
plt.subplot(1, 2, 2)
plt.scatter(X[:1000, 0], X[:1000, 1], c=kmeans_labels[:1000], cmap='viridis')
plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], c='red', marker='x', s=100)
plt.title(f'K-means\nTime: {kmeans_time:.2f}s')
plt.tight_layout()
plt.show()
# 输出聚类中心对比
print("Mini-batch K-Means聚类中心:")
print(mbk.cluster_centers_)
print("\nK-means聚类中心:")
print(kmeans.cluster_centers_)
代码说明
- 我们使用
make_blobs
函数生成了一个包含100000个样本的大规模数据集。 - 然后分别使用
MiniBatchKMeans
和KMeans
类进行聚类,并记录了它们的运行时间。 - 在可视化部分,由于数据量太大,我们只展示了前1000个数据点的聚类结果。从图中可以直观地看到两种算法的聚类效果。
- 最后,我们输出了两种算法的聚类中心,可以进行对比分析。
运行这段代码,你会发现Mini-batch K-Means的运行时间明显短于普通K-means算法,而且在聚类效果上也比较接近😃。
📢 总结
1、什么时候不该使用Mini-Batch K-means?
尽管该算法强大,但以下场景需谨慎选择:
- 数据量<1万条:传统K-means精度更高且速度可接受
- 要求精确聚类:如科学计算场景,容忍不了>1%的惯性值差异
- 极度非凸数据:需配合Kernel方法(此时选Kernel K-means)
- 动态簇数需求:需ISODATA等动态调整方案
2、与前序优化算法的关联与定位
算法 | 核心创新 | 时间复杂度 | 适合场景 | 与Mini-Batch结合点 |
---|---|---|---|---|
K-means++ | 智能初始化 | O(n) | 所有K-means变种 | ✅ 必选初始化方案 |
Canopy | 预聚类降维 | O(n) | 超大规模初步聚类 | ✅ 先Canopy粗聚类再MBK细聚类 |
二分K-means | 层次分裂 | O(n log n) | 簇数未知场景 | ⚠️ 无法直接结合 |
ISODATA | 动态调簇数 | O(n²) | 中规模动态聚类 | ❌ 计算冲突 |
Kernel K-means | 核方法 | O(n²) | 非线性数据 | ❌ 计算复杂度叠加 |
希望今天的分享对你有所帮助,如果你有任何问题或建议,欢迎在评论区留言💬。咱们下次再见啦😘!