一、K-Means
K-Means是GMM的特例(硬聚类,基于原型的聚类)。假设多元高斯分布的协方差为0,方差相同。
K-Means算法思想
对于给定的样本集,按照样本之间的距离大小,将样本集划分为K个簇。让簇内的点尽量紧密的连在一起,而让簇间的距离尽量的大。

N个d维样本,时间复杂度 O(kLNd)
- 初始K个类(簇心)
- E步:对每个样本,计算到K个类的欧式距离,并分配类标签 O(kNd)
- M步:基于类内的样本,以样本均值更新类(均值最小化,类到类内样本的误差) O(Nd)
- 重复2-3步,直到聚类结果不变化或收敛
迭代次数为L
收敛性证明:
聚类处理:
特征归一化,缺失值,异常值
K-Means的主要优点有:
1)基于原型的聚类,实现简单收敛速度快。
2)聚类效果较优。
3)算法的可解释度比较强。
4)主要需要调参的参数仅仅是簇数k。
K-Means的主要缺点有:
1)K值的选取不好把握
2)对于不是凸的数据集比较难收敛
3)如果各隐含类别的数据不平衡,比如各隐含类别的数据量严重失衡,或者各隐含类别的方差不同,则聚类效果不佳。
4) 采用迭代方法,得到的结果只是局部最优(本身是个NP-hard问题,组合优化,多项式系数)
5) 对噪音和异常点比较的敏感。
# 基于Cursor生成的代码 import numpy as np def k_means(X, k, max_iters=100): # randomly initialize centroids centroids = X[np.random.choice(range(len(X)), k, replace=False)] for i in range(max_iters): # calculate distances between each point and each centroid distances = np.sqrt(((X - centroids[:, np.newaxis])**2).sum(axis=2)) # assign each point to the closest centroid labels = np.argmin(distances, axis=0) # update centroids to be the mean of the points assigned to them for j in range(k): centroids[j] = X[labels == j].mean(axis=0) return centroids, labels d = 3 k = 3 X = np.random.rand(100, 3) centroids, labels = k_means(X, k, max_iters=100) import matplotlib.pyplot as plt fig = plt.figure(figsize=(10, 7)) 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='*', s=300, c='r') ax.set_xlabel('X Label') ax.set_ylabel('Y Label') ax.set_zlabel('Z Label') plt.show()