Python K-Means聚类算法实战
·
一、什么是K-Means?新手也能懂的核心定义
K-Means是机器学习中无监督聚类算法的核心代表,简单来说,它的目标是:把一堆没有标签的数据,按照“相似度”自动分成K个类别——相似的数据被归到同一类,不同类的数据差异尽可能大。
举个直观例子:电商平台用K-Means把用户分成“高消费高频次”“低消费高频次”“高消费低频次”等群体,针对性做营销;外卖平台用它划分配送区域,优化骑手调度。
- 核心特点:简单、高效、易落地,适合处理大规模数据;
- 适用场景:用户分群、商品分类、区域划分、异常检测;
- 学习前提:掌握Python基础(列表、数组、Pandas),了解NumPy基本用法。
二、K-Means核心原理:4步搞懂聚类逻辑
K-Means的本质是“迭代优化”,核心流程只有4步,用通俗的话讲清楚:
步骤1:选定K值,随机初始化K个“聚类中心”
- K是你要划分的类别数(比如想把用户分成3类,K=3);
- 聚类中心:每个类的“代表点”,算法会随机在数据集中选K个点作为初始中心。
步骤2:计算所有数据到聚类中心的距离,归到最近的类
- 常用“欧氏距离”计算相似度(比如点A(x1,y1)到点B(x2,y2)的距离:√[(x1-x2)²+(y1-y2)²]);
- 每个数据点会被分配到“距离最近”的聚类中心所属的类别。
步骤3:重新计算每个类的聚类中心(取该类所有点的均值)
- 比如某类包含3个点(1,2)、(3,4)、(5,6),新的聚类中心就是(3,4)((1+3+5)/3=3,(2+4+6)/3=4);
- 这一步是“优化”的核心:让聚类中心更贴合当前类的特征。
步骤4:重复步骤2-3,直到聚类中心不再变化
- 当迭代到聚类中心的位置基本稳定(变化小于设定阈值),或达到最大迭代次数,算法停止;
- 最终得到的K个聚类中心,就是每个类的核心特征,所有数据也被划分到对应类别。
三、环境准备:Python K-Means实战必备库
K-Means无需手写算法,直接用Python经典库即可,推荐安装以下工具:
1. 安装核心库
# 基础数据处理+可视化+机器学习库
pip install numpy pandas matplotlib scikit-learn
2. 库功能说明
| 库名 | 核心作用 |
|---|---|
| NumPy | 数值计算,处理数组和矩阵 |
| Pandas | 数据读取、清洗、预处理 |
| Matplotlib | 可视化聚类结果,直观展示分类效果 |
| scikit-learn(sklearn) | 内置K-Means算法,无需手动实现 |
四、实战1:基础案例——对随机生成的数据做聚类
1. 完整代码(可直接复制运行)
# 导入所需库
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
# 步骤1:生成模拟数据(2维数据,便于可视化)
# n_samples=500:生成500个样本;centers=4:真实类别数为4;random_state=42:固定随机种子,结果可复现
X, y_true = make_blobs(n_samples=500, centers=4, cluster_std=0.6, random_state=42)
# 步骤2:可视化原始数据(无标签)
plt.figure(figsize=(8, 6))
plt.scatter(X[:, 0], X[:, 1], s=50, c='gray', alpha=0.6)
plt.title('原始无标签数据')
plt.xlabel('特征1')
plt.ylabel('特征2')
plt.show()
# 步骤3:构建K-Means模型并训练
kmeans = KMeans(n_clusters=4, random_state=42) # n_clusters=4:设定聚类数为4
kmeans.fit(X) # 训练模型
# 步骤4:获取聚类结果
y_kmeans = kmeans.predict(X) # 预测每个样本的类别
centers = kmeans.cluster_centers_ # 获取最终的聚类中心
# 步骤5:可视化聚类结果
plt.figure(figsize=(8, 6))
# 绘制样本,不同类别用不同颜色
plt.scatter(X[:, 0], X[:, 1], c=y_kmeans, s=50, cmap='viridis', alpha=0.8)
# 绘制聚类中心(红色五角星突出)
plt.scatter(centers[:, 0], centers[:, 1], c='red', s=200, marker='*', label='聚类中心')
plt.title('K-Means聚类结果(K=4)')
plt.xlabel('特征1')
plt.ylabel('特征2')
plt.legend()
plt.show()
2. 运行结果说明
- 第一个图:500个无标签的散点,无法区分类别;
- 第二个图:数据被分成4类(4种颜色),红色五角星是每个类的聚类中心;
- 核心API说明:
KMeans(n_clusters=4):指定聚类数K=4(关键参数);fit(X):用数据X训练模型;predict(X):预测每个样本的类别;cluster_centers_:获取聚类中心坐标。
五、实战2:真实场景——用户消费行为分群
1. 需求说明
用K-Means对电商用户的“消费金额”和“消费频次”做聚类,划分出高价值、中价值、低价值用户,辅助营销决策。
2. 完整代码
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
# 步骤1:构造用户消费数据(模拟真实场景)
data = {
'用户ID': range(1, 101),
'月消费金额(元)': [np.random.randint(10, 200) for _ in range(30)] + # 低价值
[np.random.randint(200, 800) for _ in range(50)] + # 中价值
[np.random.randint(800, 2000) for _ in range(20)], # 高价值
'月消费频次(次)': [np.random.randint(1, 3) for _ in range(30)] +
[np.random.randint(3, 8) for _ in range(50)] +
[np.random.randint(8, 15) for _ in range(20)]
}
df = pd.DataFrame(data)
print("原始数据前5行:")
print(df.head())
# 步骤2:数据预处理(标准化,避免量纲影响)
# 提取特征列(仅用消费金额和频次)
features = df[['月消费金额(元)', '月消费频次(次)']]
# 标准化:让特征均值为0,方差为1,避免金额(大数值)主导聚类结果
scaler = StandardScaler()
features_scaled = scaler.fit_transform(features)
# 步骤3:构建K-Means模型(K=3,划分3类用户)
kmeans = KMeans(n_clusters=3, random_state=42)
df['用户类别'] = kmeans.fit_predict(features_scaled)
# 步骤4:分析聚类结果
print("\n各类别用户数量:")
print(df['用户类别'].value_counts())
# 步骤5:可视化用户分群结果
plt.figure(figsize=(10, 6))
colors = ['red', 'green', 'blue']
labels = ['低价值用户', '中价值用户', '高价值用户']
for i in range(3):
cluster_data = df[df['用户类别'] == i]
plt.scatter(cluster_data['月消费金额(元)'],
cluster_data['月消费频次(次)'],
c=colors[i], label=labels[i], alpha=0.7)
# 绘制聚类中心(需反标准化回原始尺度)
centers_scaled = kmeans.cluster_centers_
centers = scaler.inverse_transform(centers_scaled)
plt.scatter(centers[:, 0], centers[:, 1], c='black', s=300, marker='*', label='聚类中心')
plt.title('电商用户消费行为分群')
plt.xlabel('月消费金额(元)')
plt.ylabel('月消费频次(次)')
plt.legend()
plt.grid(alpha=0.3)
plt.show()
# 步骤6:输出各类别用户的特征均值(原始尺度)
print("\n各类别用户消费特征均值:")
for i in range(3):
print(f"\n类别{i}({labels[i]}):")
print(df[df['用户类别'] == i][['月消费金额(元)', '月消费频次(次)']].mean())
3. 关键知识点说明
- 数据标准化:必须步骤!比如“消费金额”是几百到几千,“消费频次”是1-15,若不标准化,算法会只关注金额,忽略频次;
- fit_predict():合并fit()和predict(),直接返回每个样本的类别;
- 反标准化:聚类中心是标准化后的值,需用scaler.inverse_transform()转回原始尺度,方便分析。
六、K-Means核心问题:如何确定最优K值?
K-Means的最大痛点是“需要手动指定K值”,推荐用“肘部法则”解决:
1. 肘部法则原理
计算不同K值对应的“惯性值(inertia)”——即每个样本到其聚类中心的距离平方和,惯性值越小,聚类效果越好。但当K超过某个值后,惯性值下降速度会骤减,这个“拐点”就是最优K值。
2. 代码实现(以用户分群为例)
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
# 尝试K=1到10,计算惯性值
inertias = []
k_range = range(1, 11)
for k in k_range:
kmeans = KMeans(n_clusters=k, random_state=42)
kmeans.fit(features_scaled)
inertias.append(kmeans.inertia_)
# 可视化肘部法则曲线
plt.figure(figsize=(8, 5))
plt.plot(k_range, inertias, marker='o', linestyle='-')
plt.title('K-Means肘部法则(最优K值选择)')
plt.xlabel('聚类数K')
plt.ylabel('惯性值(Inertia)')
plt.grid(alpha=0.3)
plt.axvline(x=3, color='red', linestyle='--', label='最优K=3')
plt.legend()
plt.show()
3. 结果解读
- 曲线从K=1到K=3时,惯性值快速下降;
- K>3后,惯性值下降变缓,形成“肘部”,因此最优K值为3。
七、K-Means常见坑与避坑技巧
1. 初始聚类中心随机导致结果不稳定
- 问题:默认随机选初始中心,多次运行可能得到不同结果;
- 解决:设置
n_init=10(默认值),算法会运行10次,选惯性值最小的结果;kmeans = KMeans(n_clusters=3, n_init=10, random_state=42)
2. 数据量纲影响聚类结果
- 问题:特征间数值范围差异大(如金额vs频次),导致聚类偏向大数值特征;
- 解决:必做标准化/归一化(用StandardScaler或MinMaxScaler)。
3. 异常值干扰聚类中心
- 问题:极端值(如某用户月消费10万元)会让聚类中心偏离;
- 解决:先清洗异常值(比如用四分位数法剔除离群点)。
4. K值选择不合理
- 问题:K值太大/太小,聚类结果无业务意义;
- 解决:结合肘部法则+业务场景(比如用户分群通常选3-5类)。
八、K-Means进阶方向
- K-Means++:sklearn默认用该算法初始化聚类中心,解决随机初始化的问题,无需额外配置;
- Mini-Batch K-Means:适合超大规模数据(百万级样本),用小批次数据迭代,提升速度;
from sklearn.cluster import MiniBatchKMeans mini_kmeans = MiniBatchKMeans(n_clusters=3, batch_size=100, random_state=42) - 聚类效果评估:用轮廓系数(Silhouette Score)量化聚类质量,越接近1效果越好;
from sklearn.metrics import silhouette_score score = silhouette_score(features_scaled, y_kmeans) print(f"轮廓系数:{score:.2f}") # 0.7以上为优质聚类
更多推荐



所有评论(0)