聚类算法(K-Means算法)
K-Means是一种常见的聚类算法,广泛应用于数据集的样本分组。该算法根据样本之间的相似性,将数据集中的样本划分为不同的簇(cluster),并设定簇的数量为K。
K-Means的目标是使得簇内的样本尽可能相似,而不同簇之间的样本尽可能不同。为衡量样本之间的相似性,通常使用欧几里德距离或其他距离度量。
该算法的结果取决于初始簇中心点的选择,可能会陷入局部最优解。为了解决这个问题,可以多次运行K-Means算法,并选择具有最小误差的结果作为最终的聚类结果。
K-Means广泛应用于图像分割、用户分群、异常检测等领域。虽然它是一种简单且高效的聚类算法,但在处理带有噪声、异常值或非凸形状的数据集时可能效果不佳。
算法原理
假设有 n n n 个样本 x 1 , x 2 , . . . , x n {x_1, x_2, ..., x_n} x1,x2,...,xn,每个样本有 m m m 个特征,可以表示为 x i = ( x i 1 , x i 2 , . . . , x i m ) x_i = (x_{i1}, x_{i2}, ..., x_{im}) xi=(xi1,xi2,...,xim),则K-Means算法的目标是将这些样本划分为 k k k 个簇。
为了衡量样本之间的距离,通常使用欧几里德距离(Euclidean distance),用公式表示如下:
d ( x i , x j ) = ∑ p = 1 m ( x i p − x j p ) 2 d(x_i, x_j) = \sqrt{\sum_{p=1}^m(x_{ip}-x_{jp})^2} d(xi,xj)=p=1∑m(xip−xjp)2
K-Means算法的核心是寻找一组簇中心点 c 1 , c 2 , . . . , c k {c_1, c_2, ..., c_k} c1,c2,...,ck,其中 c i c_i ci 是第 i i i 个簇的中心点。对于每个样本 x i x_i xi,将其归属于距离最近的簇中心点所在的簇。
假设 S 1 , S 2 , . . . , S k {S_1, S_2, ..., S_k} S1,S2,...,Sk 是将样本集 x 1 , x 2 , . . . , x n {x_1, x_2, ..., x_n} x1,x2,...,xn 划分后得到的 k k k 个簇,其中 S i S_i Si 表示第 i i i 个簇包含的样本集合。则每个簇的中心点可以表示为:
c i = 1 ∣ S i ∣ ∑ x j ∈ S i x j c_i = \frac{1}{|S_i|}\sum_{x_j\in S_i}x_j ci=∣Si∣1xj∈Si∑xj
其中 ∣ S i ∣ |S_i| ∣Si∣ 表示第 i i i 个簇包含的样本数量。
K-Means算法的目标是最小化所有样本与其所属簇中心点之间的距离平方和,即:
min ∑ i = 1 k ∑ x j ∈ S i ∣ ∣ x j − c i ∣ ∣ 2 \min \sum_{i=1}^k\sum_{x_j\in S_i} ||x_j-c_i||^2 mini=1∑kxj∈Si∑∣∣xj−ci∣∣2
其中 ∣ ∣ x j − c i ∣ ∣ 2 ||x_j-c_i||^2 ∣∣xj−ci∣∣2 表示样本 x j x_j xj 与其所属簇中心点 c i c_i ci 之间的距离的平方。
为了实现K-Means算法,需要通过以下几步来迭代求解:
- 初始化簇中心点,可以随机选择 k k k 个样本作为初始中心点;
- 将所有样本分配到距离最近的簇中心点所在的簇中;
- 更新每个簇的中心点;
- 重复执行步骤2和3,直到簇中心点不再发生变化或达到最大迭代次数。
代码实现
from sklearn.cluster import KMeans
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
# 加载Iris数据集
iris = load_iris()
X = iris.data
# 创建K-Means模型并训练
kmeans = KMeans(n_clusters=3) # 设置簇的数量为3
kmeans.fit(X)
# 获取簇中心点的坐标和样本所属的簇
centroids = kmeans.cluster_centers_
labels = kmeans.labels_
# 可视化聚类结果(以两个特征为例)
plt.scatter(X[:, 0], X[:, 1], c=labels)
plt.scatter(centroids[:, 0], centroids[:, 1], marker='x', color='black')
plt.xlabel("Sepal Length")
plt.ylabel("Sepal Width")
plt.title("K-Means Clustering on Iris dataset")
plt.show()
在上述代码中,我们首先使用load_iris()函数加载了Iris数据集,并将特征数据赋值给变量X。然后,我们创建了一个K-Means模型,将簇的数量设置为3,并数据进行训练。我们使用cluster_centers_属性获取簇中心点的坐标,并使用labels_属性获取每个样本所属的簇。最后,我们使用Matplotlib库将聚类结果可视化(如下图所示)。
总结
本文介绍了K-Means算法的原理和代码实现。K-Means算法是一种无监督学习算法,旨在将样本划分为K个簇,并最小化所有样本与其所属簇中心点之间的距离平方和。该算法的主要步骤包括初始化簇中心点、分配样本到最近的簇中心点、更新簇中心点等。本文给出了一个使用sklearn库实现K-Means聚类的代码示例,并展示了聚类结果的可视化结果。