K-Means 聚类算法
一、基本原理
1.定义:K-Means 是无监督划分式聚类算法。
个人指定聚类数量K
把n样本划分为K个簇
以簇内平方误差和 SSE为目标,不断迭代更新聚类中心,使得同一簇样本距离簇中心最近,不同簇中心尽可能远离。
2.两个核心:
距离度量:默认欧氏距离
终止条件:中心点不再变动 / SSE 变化小于阈值 / 达到最大迭代次数。
3.特点:
无标签、自动分组、只能凸球形簇、对异常值和初始中心点敏感。
二、算法执行步骤
给定数据集X,设定聚类数 K,随机从样本中选 K 个作为初始聚类中心。
遍历每一个样本
初始化
给定数据集X = { x 1 , x 2 , … , x n } X = \{x_1,x_2,\dots,x_n\}X={x1,x2,…,xn},设定聚类数K KK,随机从样本中选K KK个作为初始聚类中心μ 1 , μ 2 , … , μ K \mu_1,\mu_2,\dots,\mu_Kμ1,μ2,…,μK。分配样本
遍历每一个样本x i x_ixi,计算它到K KK个中心点的距离,归入距离最近的簇C j C_jCj。
C j = { x i ∣ j = arg min j d i s t ( x i , μ j ) } C_j = \left\{ x_i \mid j = \arg\min_j \mathrm{dist}(x_i, \mu_j) \right\}Cj={xi∣j=argjmindist(xi,μj)}更新聚类中心
对每个簇,用簇内所有样本均值作为新的簇中心。
μ j = 1 ∣ C j ∣ ∑ x i ∈ C j x i \mu_j = \frac{1}{|C_j|}\sum_{x_i\in C_j} x_iμj=∣Cj∣1xi∈Cj∑xi
∣ C j ∣ |C_j|∣Cj∣:第j jj个簇内样本总数迭代收敛
重复步骤 2、3,直至聚类中心不再变动,或达到预设的最大迭代次数时,算法终止。
损失函数 SSE
K-Means迭代优化的目标函数:
S S E = ∑ j = 1 K ∑ x i ∈ C j ∥ x i − μ j ∥ 2 2 SSE = \sum_{j=1}^K \sum_{x_i \in C_j} \Vert x_i - \mu_j \Vert_2^2SSE=j=1∑Kxi∈Cj∑∥xi−μj∥22
轮廓系数(Silhouette Coefficient)最优K值选择
- 单样本轮廓系数公式
s ( i ) = b ( i ) − a ( i ) max { a ( i ) , b ( i ) } s(i) = \frac{b(i) - a(i)}{\max\left\{a(i), b(i)\right\}}s(i)=max{a(i),b(i)}b(i)−a(i)
- a ( i ) a(i)a(i):样本i ii到自身簇内其他样本的平均距离,衡量簇内紧凑度;
- b ( i ) b(i)b(i):样本i ii到最近异族样本的平均距离,衡量簇间分离度。
全局平均轮廓系数
Silhouette Score = 1 n ∑ i = 1 n s ( i ) \text{Silhouette Score} = \frac{1}{n}\sum_{i=1}^n s(i)Silhouette Score=n1i=1∑ns(i)择优规则
遍历K ∈ { 2 , 3 , … , K max } K \in \{2,3,\dots,K_{\text{max}}\}K∈{2,3,…,Kmax},取**平均轮廓系数最大值对应的K KK**作为最优聚类数量
四、代码演示
"""class sklearn.cluster.KMeans( n_clusters=8, # 核心参数:聚类数量K init='k-means++', # 初始中心选择方式,k-means++最优,避免局部最优 n_init='auto', # 运行多少次聚类取最优结果 max_iter=300, # 单次聚类最大迭代次数 tol=0.0001, # 中心点变化阈值,小于该值判定收敛 verbose=0, # 日志打印等级 random_state=None, # 随机种子,固定结果可复现 copy_x=True, algorithm='lloyd' ) """fromsklearn.clusterimportKMeansimportpandasaspdfromsklearnimportmetrics data=pd.read_table('data(1).txt',sep=' ',encoding='utf-8',engine='python')x=data[['calories','sodium','alcohol','cost']]""" 根据不同的簇,自动计算轮廓系数 """scores=[]forkinrange(2,10):labels=KMeans(n_clusters=k).fit(x).labels_ score=metrics.silhouette_score(x,labels)scores.append(score)print(scores)五、API
基础导入与实例化
| 项目 | 内容说明 |
| ---- | ---- |
| 导入语句 |from sklearn.cluster import KMeans|
| 算法类型 | 无监督聚类 |
| 距离度量 | 默认欧氏距离 |核心超参数对照表
| 参数名 | 含义 | 常用取值 |
| ---- | ---- | ---- |
| n_clusters | 设定聚类簇数量K | 整数,根据肘部法则确定 |
| init | 中心点初始化方式 |k-means++(默认最优)、random随机 |
| max_iter | 最大迭代次数 | 默认300 |
| n_init | 随机初始化运行多少次取最优结果 | 默认10 |
| random_state | 随机种子,结果可复现 | 任意整数如42 |常用方法与属性
| 方法/属性 | 功能 | 调用示例 |
| ---- | ---- | ---- |
|.fit(X)| 仅训练模型 |kmeans.fit(X)|
|.fit_predict(X)| 训练 + 返回每个样本聚类标签 |labels = kmeans.fit_predict(X)|
|.predict(X)| 对新数据预测所属簇 |new_label = kmeans.predict(new_X)|
|.cluster_centers_| 输出K个聚类中心坐标 |kmeans.cluster_centers_|
|.inertia_| 输出SSE总簇内误差和 |kmeans.inertia_|
|.labels_| 训练集所有样本聚类标签 |kmeans.labels_|