K-Means算法理论及Python实现

本文深入探讨了K-means算法的基本原理,包括其在欧式空间下的应用假设、初始化策略、迭代流程及收敛性证明。同时提供了Python代码实现,并通过实例展示了算法在数据集上的应用效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简述

K-means Algorithm(s)

  • Assumes Euclidean space/distance 假设是在欧式空间下的。因为means本身是需要在欧式空间下才可以计算。但K-means有很多的推广版本,将欧式空间中所提到的Centroid转成Clustroid,是一种比较常见的推广方式。
  • 算法先取k个类: Initialization 的时候需要避免ill-initialization 这里考虑到病态的初始化。最为经典的是使用 Rival penalized competitive learning1

总之,通过一定的方式,可以实现初始化的K个类中心的选取。

算法流程

  • For each point, place it in the cluster whose current centroid it is nearest.对于每个点,将其放在那个类中心离它最近的那个类中。
  • After all points are assigned, update the locations of centroids of the K clusters. 每个点都被分配完之后,更新每个类的中心位置。
  • Reassign all points to their closet centroid. 再分配每个点(方法类似)直到整个分配没什么变化。(直到收敛)

收敛性证明

这里我只给出不是很严谨的证明~ 至于详细的可以看60年前的那篇论文。

我们认为K-means一定会收敛。
下面使用反证法:
假设该算法不收敛。

那么根据假设就存在有这样的一个点。在添加它之后,即类中心发生移动后,就该删除掉它。
而这是不合理的。添加上该点之后,该类中心会向该点的发生移动。即距离比之前更近了。而根据算法,我们知道这样的点是不会被抛弃的。所以,这样的点不存在。即该算法会收敛。

证明不是很严谨,但是却可以拿来做对于算法收敛的直观认知~
欢迎大家在评论区补充~

Python实现

  • 注意,这里采用的是完全随机初始化,这样的效果不是很好。因为可能会存在有病态的初始化结果。
def k_means(X, k=3):
    index_list = np.arange(len(X))
    np.random.shuffle(index_list)
    centroids_index = index_list[:k]
    centroids = X[centroids_index]
    y = np.arange(len(X))
    while True:
        y_new = np.arange(len(X))
        for i, xi in enumerate(X):
            y_new[i] = np.argmin([np.linalg.norm(xi - cj) for cj in centroids])
        if sum(y != y_new) == 0:
            break
        for j in range(k):
            centroids[j] = np.mean(X[np.where(y_new == j)], axis=0)
        y = y_new.copy()
    return y
  • 直接用PCA截取部分特征,主要是为了画图
from sklearn import datasets
iris = datasets.load_iris()
from sklearn.decomposition import PCA
X_reduced = PCA(n_components=2).fit_transform(iris.data)
import matplotlib.pyplot as plt
plt.scatter(X_reduced[:, 0], X_reduced[:, 1], c=y, cmap=plt.cm.Set1)

原图:
在这里插入图片描述

K-means:
在这里插入图片描述

  • 直接选用前两个特征
plt.scatter(iris.data[:, 0], iris.data[:, 1], c=y, cmap=plt.cm.Set1)
y_test_2 = k_means(iris.data)
plt.scatter(iris.data[:, 0], iris.data[:, 1], c=y_test, cmap=plt.cm.Set1)

原图:
在这里插入图片描述

K-means:
在这里插入图片描述


  1. https://ieeexplore.ieee.org/abstract/document/238318) ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gc.collect()

公众号“肥宅Sean”欢迎关注

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值