在机器学习领域,聚类分析是一种重要的无监督学习方法,用于将数据集中的样本划分为不同的组或簇,使得同一簇内的样本具有较高的相似性,而不同簇之间的样本具有较大的差异性。K-Means 聚类算法是最常用的聚类算法之一,它以其简单性和高效性在数据挖掘、图像分割、模式识别等领域得到了广泛应用。本文将详细介绍 K-Means 聚类算法,并分别给出调用现成函数和不调用任何现成函数实现 K-Means 聚类的代码示例,同时对两种实现方式进行对比分析。
K-Means 聚类算法的基本思想是通过迭代的方式将数据集中的样本分配到 k k k 个不同的簇中,使得每个样本到其所属簇的质心(即聚类中心)的距离之和最小。具体步骤如下:
import numpy as np
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
# 超参数设置
n_samples = 100 # 样本数量
n_features = 3 # 数据维度
k = 3 # 聚类数量
# 生成一些示例数据
X = np.random.rand(n_samples, n_features)
# 创建 K-Means 模型,指定聚类的数量
kmeans = KMeans(n_clusters=k, random_state=0).fit(X)
# 获取聚类标签
labels = kmeans.labels_
# 获取聚类中心
centroids = kmeans.cluster_centers_
# 若为二维数据,进行可视化
if n_features == 2:
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis')
plt.scatter(centroids[:, 0], centroids[:, 1], marker='X', s=200, c='red')
plt.title('K-Means Clustering with scikit-learn')
plt.show()
elif n_features == 3:
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(X[:, 0], X[:, 1], X[:, 2], c=labels, cmap='viridis')
ax.scatter(centroids[:, 0], centroids[:, 1], centroids[:, 2], marker='X', s=200, c='red')
plt.title('K-Means Clustering with scikit-learn (3D)')
plt.show()
else:
print(f"数据维度为 {n_features},无法直接可视化。")
这段代码使用了 Python 的 numpy
、sklearn
和 matplotlib
库来实现 K-Means 聚类。具体步骤如下:
numpy
用于数值计算,sklearn.cluster.KMeans
用于实现 K-Means 聚类,matplotlib.pyplot
用于数据可视化。n_samples
、数据维度 n_features
和聚类数量 k
。np.random.rand
函数生成随机样本数据。KMeans
类创建模型,并调用 fit
方法对数据进行训练。labels_
属性获取每个样本的聚类标签,通过 cluster_centers_
属性获取聚类中心。matplotlib
库对聚类结果进行可视化。import numpy as np
import matplotlib.pyplot as plt
def kmeans(X, k, max_iterations=100):
# 随机初始化聚类中心
centroids = X[np.random.choice(X.shape[0], k, replace=False)]
for _ in range(max_iterations):
# 计算每个样本到每个聚类中心的距离
distances = np.array([np.linalg.norm(X - centroid, axis=1) for centroid in centroids])
# 分配每个样本到最近的聚类中心
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
# 超参数设置
n_samples = 100 # 样本数量
n_features = 3 # 数据维度
k = 3 # 聚类数量
# 生成一些示例数据
X = np.random.rand(n_samples, n_features)
# 调用自定义的 K-Means 函数
labels, centroids = kmeans(X, k)
# 若为二维数据,进行可视化
if n_features == 2:
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis')
plt.scatter(centroids[:, 0], centroids[:, 1], marker='X', s=200, c='red')
plt.title('K-Means Clustering without Library')
plt.show()
elif n_features == 3:
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(X[:, 0], X[:, 1], X[:, 2], c=labels, cmap='viridis')
ax.scatter(centroids[:, 0], centroids[:, 1], centroids[:, 2], marker='X', s=200, c='red')
plt.title('K-Means Clustering without Library (3D)')
plt.show()
else:
print(f"数据维度为 {n_features},无法直接可视化。")
这段代码手动实现了 K-Means 聚类算法,不依赖任何现成的聚类库。具体步骤如下:
kmeans
函数:该函数接受数据矩阵 X
、聚类数量 k
和最大迭代次数 max_iterations
作为参数。kmeans
函数:设置超参数,生成随机样本数据,调用 kmeans
函数进行聚类。matplotlib
库对聚类结果进行可视化。sklearn
库的 KMeans
类,只需几行代码就可以完成聚类任务,无需手动实现复杂的迭代过程。sklearn
库提供了许多额外的功能,如随机种子设置、初始化方法选择、收敛判断标准等,可以方便地进行参数调整和模型优化。sklearn
库的实现经过了优化,具有较高的计算效率和稳定性。K-Means 聚类算法是一种简单而有效的聚类方法,在实际应用中具有广泛的用途。本文分别介绍了调用现成函数和不调用任何现成函数实现 K-Means 聚类的方法,并对两种实现方式进行了对比分析。在实际应用中,我们可以根据具体需求选择合适的实现方式。如果追求代码简洁和功能丰富,建议使用现成的机器学习库;如果需要深入理解算法原理或进行定制化开发,则可以手动实现算法。