目录

K-means-算法核心原理

K-means 算法核心原理

一、K-means 算法核心原理

1. 算法目标

n 个样本 划分到 k 个簇 中,使得每个样本到所属簇中心的 距离平方和最小

2. 数学公式

目标函数 (SSE,簇内平方误差):

J

∑ i

1 k ∑ x ∈ C i ∥ x − μ i ∥ 2 J = \sum_{i=1}^k \sum_{x \in C_i} |x - \mu_i|^2

J

=

i

=

1

k

x

C

i

x

μ

i

2

其中:

  • C i C_i

    C

    i

    表示第

    i i

    i 个簇

  • μ i \mu_i

    μ

    i

    表示第

    i i

    i 个簇的质心


二、算法步骤详解

随机初始化k个质心

分配样本到最近质心

重新计算质心位置

质心是否变化?

输出聚类结果


三、Python 代码实现

1. 手动实现(理解原理)
import numpy as np
from sklearn.datasets import make_blobs

class KMeans:
    def __init__(self, k=3, max_iter=100):
        self.k = k
        self.max_iter = max_iter
        
    def fit(self, X):
        # 随机初始化质心
        self.centroids = X[np.random.choice(X.shape[0], self.k, replace=False)]
        
        for _ in range(self.max_iter):
            # 分配样本到最近质心
            distances = np.sqrt(((X - self.centroids[:, np.newaxis])**2).sum(axis=2))
            labels = np.argmin(distances, axis=0)
            
            # 更新质心
            new_centroids = np.array([X[labels == i].mean(axis=0) for i in range(self.k)])
            
            # 收敛判断
            if np.allclose(self.centroids, new_centroids):
                break
            self.centroids = new_centroids
        
        return labels

# 生成测试数据
X, y = make_blobs(n_samples=300, centers=3, cluster_std=0.6, random_state=42)

# 使用手写模型
kmeans = KMeans(k=3)
labels = kmeans.fit(X)
2. Scikit-learn 生产级实现
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler

# 数据标准化(重要!)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 建模
kmeans = KMeans(n_clusters=3, init='k-means++', n_init=10)
kmeans.fit(X_scaled)
labels = kmeans.labels_

四、关键参数解析

参数作用推荐值
n_clusters指定簇的数量 K通过肘部法则确定
init初始化方法'k-means++' (默认优化)
n_init随机初始化的次数10-50(避免局部最优)
max_iter最大迭代次数300-500(复杂数据)

五、聚类质量评估

1. 轮廓系数 (Silhouette Score)

s

b − a max ⁡ ( a , b ) s = \frac{b - a}{\max(a, b)}

s

=

max

(

a

,

b

)

b

a

  • a a

    a :样本到同簇其他样本的平均距离

  • b b

    b :样本到最近其他簇样本的平均距离

  • 取值范围:[-1, 1],值越大越好

from sklearn.metrics import silhouette_score

score = silhouette_score(X_scaled, labels)
print(f"轮廓系数:{score:.2f}")
2. 肘部法则 (Elbow Method)
import matplotlib.pyplot as plt

sse = []
k_range = range(1, 10)

for k in k_range:
    kmeans = KMeans(n_clusters=k)
    kmeans.fit(X_scaled)
    sse.append(kmeans.inertia_)

plt.plot(k_range, sse, 'bx-')
plt.xlabel('K')
plt.ylabel('SSE')
plt.title('肘部法则')
plt.show()

六、算法优缺点分析

优点缺点
简单高效,时间复杂度 O(nkt)需要预先指定 K 值
适合球形簇结构对噪声和异常值敏感
可扩展性强(MiniBatch 变体)初始质心选择影响结果
结果易于解释不适合非凸形状簇

七、工业级优化技巧

1. 数据预处理
  • 标准化 :确保各特征量纲一致

  • 降维 :对高维数据先用 PCA 降维

    from sklearn.decomposition import PCA
    
    pca = PCA(n_components=0.95)
    X_pca = pca.fit_transform(X_scaled)
2. 改进初始化方法

使用 K-means++ (Scikit-learn 默认方法):

  1. 随机选择第一个质心
  2. 后续质心选择距离已有质心较远的点
3. 处理大数据集

使用 MiniBatch K-means

from sklearn.cluster import MiniBatchKMeans

mb_kmeans = MiniBatchKMeans(n_clusters=3, batch_size=100)
mb_kmeans.fit(X_scaled)

八、应用案例:客户分群

1. 数据特征
  • 年龄、消费金额、购买频率、浏览次数等
2. 实施步骤

数据清洗

特征标准化

PCA降维

K-means聚类

分析簇特征

制定营销策略

3. 分群结果分析
客户群特征营销策略
群组1高消费、低频次推送高端产品
群组2低消费、高频次发放优惠券
群组3中等消费、浏览量大推荐热门商品

九、常见问题解答

Q1:如何选择最佳 K 值?
  • 优先使用 轮廓系数 (定量评估)
  • 结合 肘部法则 和业务理解
  • 尝试 Gap Statistic 等高级方法
Q2:如何处理非球形数据?
  • 使用 谱聚类DBSCAN 替代

  • 通过 核方法 将数据映射到高维空间

    from sklearn.cluster import SpectralClustering
    
    spec = SpectralClustering(n_clusters=3, affinity='nearest_neighbors')
    labels = spec.fit_predict(X)
Q3:如何解释聚类结果?
  • 分析每个簇的 特征分布

  • 计算各特征的 簇间差异

    df['cluster'] = labels
    print(df.groupby('cluster').mean())

十、进阶学习建议

  1. 深入研究 :K-means++ 初始化原理
  2. 对比算法 :学习 DBSCAN、层次聚类等
  3. 可视化工具 :掌握 Plotly、Seaborn 的聚类可视化方法
  4. 实战项目 :尝试电商用户分群、新闻主题聚类等案例