Python AI数据分析进阶教程55:
确定K-Means最佳聚类数的三大核心方法
涉及的关键技术:K-Means聚类算法、肘部法则(Elbow Method)、轮廓系数法(Silhouette Score)、间隙统计量法(Gap Statistic)、簇内误差平方和(WCSS/Inertia)。
核心思路:本文详解如何为K-Means聚类选择最优的K值。我们将介绍三种主流技术:肘部法则通过分析不同K值下簇内误差平方和的变化拐点来定位K;轮廓系数法则评估数据点聚类划分的内聚性和分离性,取分数最高的K值;间隙统计量法通过比较实际分布与随机参考分布的聚类效果来确定K。每种方法均附有工作原理、实操要点、注意事项以及完整的Python代码实现和可视化图形。
在进行K-Means聚类分析时,如何确定最合适的聚类数目K是每个分析师都会面临的核心挑战。K值过小会导致类别划分过于笼统,失去细分价值;而K值过大则会产生过多无意义的碎片化群组,导致过拟合。为了科学地解决“K值选择”这一难题,本教程将系统梳理几种在实践中被广泛验证的有效方法,涵盖其底层原理、操作技巧、常见陷阱及可直接应用的Python实践代码。
一、肘部法则(Elbow Method)
1、原理与机制
肘部法则的核心依据是观察簇内误差平方和(Inertia,也称WCSS)随K值增加的变化趋势。Inertia计算了所有样本到其所属簇中心点的距离平方总和。随着K值的增大,每个簇包含的样本变少,样本离质心更近,因此Inertia会持续下降。当K值增加到接近真实簇数时,聚类效果的提升会大幅减缓,Inertia的下降速率会形成一个显著的“拐点”,形如人的肘关节,该点即被建议为最佳K值。通过绘制K-Inertia曲线,我们可以直观地识别这个“肘点”。
2、关键实施步骤
- 准确计算Inertia序列:这是判断的基础,需要为一系列候选K值(如1到10)分别运行K-Means并记录其Inertia值。
- 可视化与主观判断:在生成的折线图上,寻找曲线斜率从陡峭转为平缓的转折位置,即“肘部”点。
3、注意事项与局限
- 肘点不清晰:对于结构不明确或边界模糊的数据集,下降曲线可能平缓、呈线性或存在多个疑似拐点,使得判断变得困难。
- 算法随机性影响:K-Means的聚类结果受初始质心随机选取的影响,可能导致Inertia值存在轻微波动,影响肘点的稳定性判断。通常建议多次运行取平均值。
- 适用场景:肘部法对于簇结构明显、大小和密度均衡的数据效果较好。
4、Python实现代码
# 导入 numpy 库,用于数值计算和数组操作
import numpy as np
# 导入 matplotlib 库的 pyplot 模块,用于绘制图形
import matplotlib.pyplot as plt
# 从 sklearn 库的 cluster 模块导入 KMeans 类,用于执行 K-Means 聚类算法
from sklearn.cluster import KMeans
# 从 sklearn 库的 datasets 模块导入 make_blobs 函数,用于生成聚类分析所需的示例数据
from sklearn.datasets import make_blobs
def generate_sample_data():
"""生成示例数据"""
return make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)[0]
def calculate_inertia(X, k_range):
"""计算不同 K 值下的簇内误差平方和"""
inertia = []
for k in k_range:
kmeans = KMeans(n_clusters=k, random_state=0)
try:
kmeans.fit(X)
inertia.append(kmeans.inertia_)
except Exception as e:
print(f"在 K={k} 时发生错误: {e}")
return inertia
def plot_elbow_curve(K, inertia):
"""绘制肘部曲线"""
plt.plot(K, inertia, 'bx-')
plt.xlabel('Number of clusters (K)')
plt.ylabel('Inertia')
plt.title('The Elbow Method showing the optimal K')
plt.grid(True)
plt.tight_layout()
plt.show()
if __name__ == "__main__":
X = generate_sample_data()
K = range(1, 11)
inertia = calculate_inertia(X, K)
plot_elbow_curve(K, inertia)
应用提示:上述代码首先生成了一个包含4个中心点的模拟数据集。通过遍历K值从1到10,计算并绘制每条Inertia曲线。在实际业务数据分析中,只需将 X 替换为你自己的数据集矩阵,即可运行并观察确定聚类数的肘部位置。
