问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

聚类分析算法——K-means聚类详解

创作时间:
作者:
@小白创作中心

聚类分析算法——K-means聚类详解

引用
1
来源
1.
http://www.coreui.cn/news/469155.html

K-means聚类算法是机器学习领域中一种常用的基于距离的聚类方法,其主要目标是将数据集划分为K个簇,使得簇内的点到簇中心的距离总和最小。本文将从K-means的底层原理、算法步骤、数学基础、距离度量方法、参数选择、优缺点以及源代码实现等多个维度进行详细解析。

1. K-means的核心思想

K-means的目标是将数据集划分为K个簇(clusters),使得每个数据点属于距离最近的簇中心。通过反复调整簇中心的位置,K-means不断优化簇内的紧密度,从而获得尽量紧凑、彼此分离的簇。

  • 簇(Cluster):K-means通过最小化簇内距离的平方和,使得数据点在簇内聚集。
  • 簇中心(Centroid):簇中心是簇中所有点的平均值,表示簇的中心位置。
  • 簇分配和更新:K-means通过不断更新簇分配和簇中心,来逐步收敛。

2. K-means的算法步骤

K-means聚类的流程分为两个主要步骤:分配(Assignment)和更新(Update)。以下是详细步骤:

  1. 选择K值:设定簇的数量K。
  2. 初始化簇中心:随机选择K个数据点作为初始簇中心(centroids)。
  3. 分配步骤(Assignment Step):对于数据集中的每个点,将它分配到最近的簇中心对应的簇。这里的“距离”通常使用欧氏距离(Euclidean distance)。
  4. 更新步骤(Update Step):根据当前的簇分配,重新计算每个簇的中心,即计算簇内所有点的均值作为新的簇中心。
  5. 重复3和4步:不断重复分配和更新步骤,直到簇中心不再发生变化(收敛)或达到指定的最大迭代次数。

3. K-means的数学公式

K-means的目标是最小化簇内平方误差和(Within-Cluster Sum of Squares,WCSS),即每个点到其所属簇中心的距离的平方和,公式如下:

其中:

  • K是簇的数量。
  • Ci是第i个簇的点集。
  • xi是属于Ci的数据点。
  • μi是第i个簇的中心。
  • d(xi, μi)表示数据点xi与簇中心μi之间的欧氏距离平方。

欧氏距离

K-means通常采用欧氏距离来衡量点到簇中心的距离,其公式为:

其中n是数据的维度。

4. K-means的伪代码

KMeans(X, K):
1. 随机选择K个点作为初始簇中心
2. 重复以下步骤,直到簇中心不再发生变化:
   a. 分配每个点到最近的簇中心
   b. 重新计算每个簇的中心,作为簇内所有点的均值
3. 返回最终的簇分配和簇中心

分配步骤(Assignment Step)

对于每个数据点,找到距离最近的簇中心μj:

更新步骤(Update Step)

更新每个簇的中心μi为簇内所有点的均值:

5. K-means的时间复杂度分析

  • 每次分配步骤:需要计算每个点到K个簇中心的距离,复杂度为O(nKd)。
  • 更新步骤:重新计算每个簇的中心,需要遍历所有点,复杂度也是O(nKd)。
  • 总复杂度:若迭代次数为T,则总体复杂度为O(TnKd)。

6. K-means的优缺点

优点

  • 简单高效:在样本数量较少或维度较低时效果很好。
  • 收敛速度快:在适合的初始中心选择下,K-means通常可以较快收敛。

缺点

  • 对初始点敏感:初始簇中心的选择对最终结果影响较大。
  • 只能发现球形簇:K-means假设每个簇是凸形且大小相近,不能处理非球形的簇。
  • 对离群点敏感:离群点会影响簇的中心计算。

7. K值的选择

确定最佳的簇数K是K-means聚类中的一个难点。常用的选择方法有:

  1. 肘部法(Elbow Method):绘制不同K值下的WCSS图,寻找“肘部”点作为最佳K值。
  2. 轮廓系数(Silhouette Coefficient):衡量聚类结果的紧密度和分离度。通常,轮廓系数越高,聚类效果越好。
  3. Calinski-Harabasz指数:衡量簇内的方差与簇间方差之比,值越大越好。

8. Python实现K-means

我们可以使用scikit-learn中的KMeans,以及手动实现以便更深入理解。

8.1 使用scikit-learn实现K-means

from sklearn.cluster import KMeans
import numpy as np

# 生成示例数据
X = np.array([[1, 2], [2, 2], [3, 3], [8, 7], [8, 8], [25, 80]])

# 初始化并训练KMeans模型
kmeans = KMeans(n_clusters=2, random_state=0).fit(X)

# 获取簇标签和簇中心
labels = kmeans.labels_
centroids = kmeans.cluster_centers_

print("Cluster labels:", labels)
print("Centroids:", centroids)

输出

Cluster labels: [0 0 0 1 1 1]
Centroids: [[ 2.   2.33333333]
            [13.66666667 31.66666667]]

8.2 手动实现K-means算法

以下是K-means的核心逻辑手动实现:

import numpy as np

def initialize_centroids(X, k):
    indices = np.random.choice(len(X), k, replace=False)
    return X[indices]

def closest_centroid(X, centroids):
    distances = np.linalg.norm(X[:, np.newaxis] - centroids, axis=2)
    return np.argmin(distances, axis=1)

def update_centroids(X, labels, k):
    return np.array([X[labels == i].mean(axis=0) for i in range(k)])

def kmeans(X, k, max_iters=100, tol=1e-4):
    centroids = initialize_centroids(X, k)
    for i in range(max_iters):
        labels = closest_centroid(X, centroids)
        new_centroids = update_centroids(X, labels, k)
        if np.all(np.abs(new_centroids - centroids) < tol):
            break
        centroids = new_centroids
    return labels, centroids

# 示例数据
X = np.array([[1, 2], [2, 2], [3, 3], [8, 7], [8, 8], [25, 80]])

# 运行K-means
labels, centroids = kmeans(X, k=2)
print("Cluster labels:", labels)
print("Centroids:", centroids)

9. 收敛性与初始中心的选择

K-means的收敛性受到初始簇中心选择的影响。K-means++是一种改进的初始化方法,可以帮助选择更合理的初始中心,减少陷入局部最优的风险。

K-means++初始中心选择步骤

  1. 随机选择一个点作为第一个中心。
  2. 对于每个点,计算其与已选择中心的最小距离。
  3. 根据与最近中心的距离平方值选择下一个中心,概率越大则越有可能成为下一个中心。

10. 总结

K-means是一种简单、快速的聚类算法,广泛应用于数据聚类任务。通过反复优化簇中心位置,K-means不断收敛并找到数据的聚类结构。然而,它对初始条件敏感,对簇形状有限制,适合于球形且均匀分布的簇。在实际应用中,可通过结合K-means++、肘部法和轮廓系数等手段改进其效果。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号