Python案例详解如何用Scikit-learn做聚类KMeans(附完整代码与问答)
目录导读
KMeans聚类原理与适用场景
KMeans是无监督学习的经典算法,核心思想是基于距离度量将样本划分为K个簇,其工作流程为:随机初始化K个质心→计算每个样本到各质心距离→分配样本到最近簇→更新质心为簇内均值→迭代至收敛,Python实现中,Scikit-learn提供了高效且稳定的封装。

适用场景包括:客户画像分群、文档主题聚类、图像压缩、异常检测前的数据划分等,不建议用于高维稀疏数据(可先降维)或非凸形状簇(可改用DBSCAN)。
Scikit-learn环境配置与数据准备
安装非常简单,通过pip命令即可:
pip install scikit-learn numpy pandas matplotlib
我们使用经典的make_blobs生成测试数据,以便清晰观察聚类效果,以下是数据生成代码:
from sklearn.datasets import make_blobs import matplotlib.pyplot as plt # 生成500个样本,4个簇中心 X, y_true = make_blobs(n_samples=500, centers=4, cluster_std=0.60, random_state=0) plt.scatter(X[:, 0], X[:, 1], s=50)'原始数据分布') plt.show()
此步骤模拟了实际业务中尚未标注标签的数据形态,便于后续验证聚类质量。
经典案例:客户分群实战
假设有一份电商客户数据(包含消费频率、客单价、活跃天数三个特征),我们使用KMeans进行分群。
完整代码实现:
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
import pandas as pd
# 模拟数据(实际项目中读取CSV)
data = pd.DataFrame({
'frequency': [5, 20, 3, 50, 2, 33, 45, 10],
'avg_spend': [200, 800, 150, 1200, 100, 950, 1100, 400],
'active_days': [3, 15, 2, 28, 1, 20, 25, 8]
})
# 标准化(重要!避免量纲影响)
scaler = StandardScaler()
data_scaled = scaler.fit_transform(data)
# 建模:设置K=3
kmeans = KMeans(n_clusters=3, random_state=0, n_init='auto')
clusters = kmeans.fit_predict(data_scaled)
data['cluster'] = clusters
print(data)
输出结果将显示每个客户被归入0、1、2号群体,配合kmeans.cluster_centers_可查看各簇中心特征,用于解读“高价值用户”、“沉睡用户”等业务含义。
可视化评估:
from sklearn.decomposition import PCA pca = PCA(2) data_pca = pca.fit_transform(data_scaled) plt.scatter(data_pca[:, 0], data_pca[:, 1], c=clusters, cmap='viridis')'KMeans聚类结果(PCA降维展示)') plt.show()
核心参数调优:如何选择K值
选择最优K是KMeans应用中的关键步骤,常用方法有肘部法和轮廓系数法。
肘部法示例:
inertias = []
K_range = range(1, 11)
for k in K_range:
model = KMeans(n_clusters=k, random_state=0, n_init='auto')
model.fit(data_scaled)
inertias.append(model.inertia_)
plt.plot(K_range, inertias, 'bo-')
plt.xlabel('K值')
plt.ylabel('惯量(inertia)')'肘部法确定K值')
plt.show()
当惯量下降趋势变缓时对应的K即为较优值,同时可结合轮廓系数:
from sklearn.metrics import silhouette_score
for k in range(2, 7):
model = KMeans(n_clusters=k, random_state=0, n_init='auto')
labels = model.fit_predict(data_scaled)
score = silhouette_score(data_scaled, labels)
print(f'K={k}, 轮廓系数={score:.3f}')
轮廓系数接近1表示簇内紧凑、簇间分离好。
常见问题与SEO优化问答
Q1:KMeans对初始质心敏感怎么办?
A:Scikit-learn的KMeans默认启用k-means++初始化,可显著降低随机性,建议同时设置random_state固定种子便于复现。
Q2:如何解释聚类结果?
A:查看各簇中心对应的原始特征均值,例如客户分群中,簇0的频次和客单价均高,可标记为“VIP客户”,也可用箱线图对比各簇特征分布。
Q3:数据量很大时运行缓慢?
A:可调整n_init减少迭代次数,或使用MiniBatchKMeans(适合10万+样本),若特征维度高,先PCA降至50维以内。
Q4:K值始终无法明确确定?
A:业务知识优先,例如电销团队只需3类客户标签,则强制K=3,也可尝试Gap Statistic或Calinski-Harabasz指数辅助判断。
Q5:聚类后怎么评估效果(无真实标签)?
A:使用轮廓系数、Davies-Bouldin指数、Calinski-Harabasz指数,实际业务中,可观察簇内用户在后续转化率、留存率上是否存在显著差异。
总结与扩展建议
本文通过电商客户分群案例,完整演示了用Scikit-learn实现KMeans聚类的全过程,核心步骤包括:数据标准化→肘部法选K→模型训练→结果可视化→业务解读,实践中建议注意三点:一是标准化避免特征权重失衡;二是多次运行取稳定解;三是结合业务校正K值。
扩展方向:
- 尝试使用
MiniBatchKMeans处理大规模数据 - 用
SpectralClustering处理非凸形状簇 - 将聚类结果作为特征输入分类模型(半监督学习)
任何聚类模型都需要在真实业务场景中验证其有效性,建议读者用自己领域的数据(如用户行为、文本标签、地理坐标)运行上述代码,理解“簇”的实际含义。
(全文共1428字,含代码块与图表说明)