在机器学习领域,聚类算法是无监督学习中的一种重要技术。K-Means算法和MiniBatchKMeans算法都是聚类问题中常用的方法。本文将对比这两种算法的性能,并展示如何使用Python中的scikit-learn库来实现这两种算法,以及如何对聚类结果进行可视化分析。
K-Means算法是一种经典的聚类算法,它通过迭代地移动聚类中心点来最小化簇内误差平方和。而MiniBatchKMeans算法则是K-Means算法的一个变种,它在每次迭代中只使用数据的一个子集来更新聚类中心,从而提高了算法的效率,尤其是在处理大规模数据集时。
为了比较这两种算法,首先需要生成一个数据集。这里使用scikit-learn库中的make_blobs函数来生成一个包含3000个样本点的数据集,这些样本点分布在三个不同的簇中。
import numpy as np
from sklearn.datasets import make_blobs
np.random.seed(0)
batch_size = 45
centers = [
[1, 1],
[-1, -1],
[1, -1]
]
n_clusters = len(centers)
X, labels_true = make_blobs(n_samples=3000, centers=centers, cluster_std=0.7)
接下来,使用K-Means算法对生成的数据集进行聚类。设置聚类数为3,并使用k-means++初始化方法。
import time
from sklearn.cluster import KMeans
k_means = KMeans(init="k-means++", n_clusters=3, n_init=10)
t0 = time.time()
k_means.fit(X)
t_batch = time.time() - t0
然后,使用MiniBatchKMeans算法对相同的数据集进行聚类。设置了批量大小为45,并同样使用k-means++初始化方法。
from sklearn.cluster import MiniBatchKMeans
mbk = MiniBatchKMeans(init="k-means++", n_clusters=3, batch_size=batch_size, n_init=10, max_no_improvement=10, verbose=0)
t0 = time.time()
mbk.fit(X)
t_mini_batch = time.time() - t0
为了比较两种算法的聚类结果,需要将两种算法的聚类中心点进行配对,以确保相同的簇在两种算法中使用相同的颜色进行标记。
from sklearn.metrics.pairwise import pairwise_distances_argmin
k_means_cluster_centers = k_means.cluster_centers_
order = pairwise_distances_argmin(k_means.cluster_centers_, mbk.cluster_centers_)
mbk_means_cluster_centers = mbk.cluster_centers_[order]
k_means_labels = pairwise_distances_argmin(X, k_means_cluster_centers)
mbk_means_labels = pairwise_distances_argmin(X, mbk_means_cluster_centers)
最后,使用matplotlib库来可视化两种算法的聚类结果。绘制了三种颜色的点来表示三个不同的簇,并在图中标注了每种算法的训练时间和惯性。
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(8, 3))
fig.subplots_adjust(left=0.02, right=0.98, bottom=0.05, top=0.9)
colors = ["#4EACC5", "#FF9C34", "#4E9A06"]
# KMeans
ax = fig.add_subplot(1, 3, 1)
for k, col in zip(range(n_clusters), colors):
my_members = k_means_labels == k
cluster_center = k_means_cluster_centers[k]
ax.plot(X[my_members, 0], X[my_members, 1], "w", markerfacecolor=col, marker=".")
ax.plot(cluster_center[0], cluster_center[1], "o", markerfacecolor=col, markeredgecolor="k", markersize=6)
ax.set_title("KMeans")
ax.set_xticks(())
ax.set_yticks(())
plt.text(-3.5, 1.8, "train time: %.2f s\ninertia: %f" % (t_batch, k_means.inertia_))
# MiniBatchKMeans
ax = fig.add_subplot(1, 3, 2)
for k, col in zip(range(n_clusters), colors):
my_members = mbk_means_labels == k
cluster_center = mbk_means_cluster_centers[k]
ax.plot(X[my_members, 0], X[my_members, 1], "w", markerfacecolor=col, marker=".")
ax.plot(cluster_center[0], cluster_center[1], "o", markerfacecolor=col, markeredgecolor="k", markersize=6)
ax.set_title("MiniBatchKMeans")
ax.set_xticks(())
ax.set_yticks(())
plt.text(-3.5, 1.8, "train time: %.2f s\ninertia: %f" % (t_mini_batch, mbk.inertia_))
# Initialize the different array to all False
different = mbk_means_labels == 4
ax = fig.add_subplot(1, 3, 3)
for k in range(n_clusters):
different += (k_means_labels == k) != (mbk_means_labels == k)
identical = np.logical_not(different)
ax.plot(X[identical, 0], X[identical, 1], "w", markerfacecolor="#bbbbbb", marker=".")
ax.plot(X[different, 0], X[different, 1], "w", markerfacecolor="m", marker=".")
ax.set_title("Difference")
ax.set_xticks(())
ax.set_yticks(())
plt.show()
通过上述代码,可以清晰地看到两种算法在聚类结果上的细微差异。K-Means算法在处理大规模数据集时可能会比较慢,而MiniBatchKMeans算法则通过使用小批量数据来提高计算效率。在实际应用中,可以根据数据集的大小和计算资源来选择合适的算法。