Excel数据一键跑K-means:Python全流程实战指南

当你面对Excel里密密麻麻的销售数据、用户行为记录或实验测量值时,是否想过用机器学习自动发现其中的隐藏规律?K-means聚类算法正是解决这类问题的利器。本文将手把手带你用Python实现从Excel数据读取、标准化处理、K-means聚类到三维可视化的完整流程,即使你是刚接触Python的数据分析人员也能轻松上手。

1. 环境准备与数据加载

在开始之前,确保已安装以下Python库。如果尚未安装,可以通过pip命令快速获取:

pip install pandas scikit-learn matplotlib openpyxl

为什么选择这些工具组合

  • pandas :Excel文件读取与数据处理的瑞士军刀
  • scikit-learn :提供现成的K-means实现和数据预处理工具
  • matplotlib :强大的可视化库,支持三维图形展示
  • openpyxl :处理新版Excel文件格式的依赖库

假设我们有一个名为 sales_data.xlsx 的Excel文件,包含三列数据:客户年消费额、购买频率和最近一次购买间隔天数。用pandas加载数据只需一行代码:

import pandas as pd

# 读取Excel文件
df = pd.read_excel('sales_data.xlsx', engine='openpyxl')  
print(df.head())  # 查看前5行数据

常见问题处理:

  • 若遇到"File is not a zip file"错误,检查文件是否损坏或尝试指定engine='openpyxl'
  • 中文路径可能导致读取失败,建议使用英文路径
  • 数据量较大时(>10万行),可添加参数 chunksize=1000 分块读取

2. 数据预处理:标准化的艺术

原始数据往往存在量纲差异,比如消费金额可能上万,而购买频率是个位数。直接聚类会导致数值大的特征主导结果。我们需要进行 标准化 处理:

from sklearn.preprocessing import MinMaxScaler

# 提取特征列(假设前三列是特征)
features = df.iloc[:, :3].values  

# 创建标准化器并转换数据
scaler = MinMaxScaler(feature_range=(0, 1))
normalized_data = scaler.fit_transform(features)

标准化方法对比:

方法 公式 适用场景 优缺点
MinMax (x-min)/(max-min) 数据边界已知 对异常值敏感
Z-Score (x-μ)/σ 数据分布近似正态 保持原始分布形态
Robust (x-median)/IQR 存在异常值 计算开销较大

提示:标准化后的数据最好保存为新文件,避免每次重复计算:

pd.DataFrame(normalized_data).to_csv('normalized_data.csv', index=False)

3. K-means聚类实战

scikit-learn提供了高度优化的K-means实现,我们无需从零开始编写算法:

from sklearn.cluster import KMeans

# 确定最佳K值:肘部法则
wcss = []
for i in range(1, 11):
    kmeans = KMeans(n_clusters=i, init='k-means++', random_state=42)
    kmeans.fit(normalized_data)
    wcss.append(kmeans.inertia_)

# 可视化肘部曲线
import matplotlib.pyplot as plt
plt.plot(range(1, 11), wcss)
plt.title('The Elbow Method')
plt.xlabel('Number of clusters')
plt.ylabel('WCSS')  # 组内平方和
plt.show()

假设通过肘部法则确定最佳K值为3,进行最终聚类:

# 最终聚类
kmeans = KMeans(n_clusters=3, init='k-means++', random_state=42)
clusters = kmeans.fit_predict(normalized_data)

# 将聚类结果添加回原始DataFrame
df['Cluster'] = clusters
print(df.groupby('Cluster').mean())  # 查看各簇特征均值

关键参数解析:

  • n_clusters :预设的簇数量,可通过肘部法则或轮廓系数确定
  • init='k-means++' :智能初始化中心点,加速收敛
  • random_state :固定随机种子确保结果可复现
  • max_iter :最大迭代次数(默认300),对复杂数据可适当增加

4. 三维可视化与结果解读

三维散点图能直观展示聚类效果,matplotlib的mplot3d工具包让这变得简单:

from mpl_toolkits.mplot3d import Axes3D

# 创建3D图形
fig = plt.figure(figsize=(10, 7))
ax = fig.add_subplot(111, projection='3d')

# 为每个簇设置不同颜色和标签
colors = ['r', 'g', 'b']
labels = ['低价值', '中价值', '高价值']

for i in range(3):
    ax.scatter(
        normalized_data[clusters == i, 0],  # x轴:消费金额
        normalized_data[clusters == i, 1],  # y轴:购买频率
        normalized_data[clusters == i, 2],  # z轴:最近购买间隔
        c=colors[i],
        label=labels[i],
        s=50,  # 点大小
        alpha=0.6  # 透明度
    )

# 添加图例和标签
ax.set_xlabel('标准化消费金额')
ax.set_ylabel('标准化购买频率')
ax.set_zlabel('标准化最近购买间隔')
ax.legend()
plt.title('客户价值三维聚类分析')
plt.tight_layout()

# 保存图像
plt.savefig('cluster_3d.png', dpi=300)
plt.show()

可视化优化技巧:

  • 调整 alpha 参数避免点重叠遮挡
  • 添加 view_init(elev=20, azim=30) 改变观察角度
  • 使用 plt.style.use('ggplot') 切换更美观的样式
  • 大数据集时可设置 s=10 减小点大小提升渲染速度

5. 结果导出与业务应用

聚类结果最终需要落地到业务决策中,我们可以将带标签的数据保存回Excel:

# 保存聚类结果
df.to_excel('clustered_sales_data.xlsx', index=False)

# 单独保存各簇客户ID(假设第一列是客户ID)
for i in range(3):
    cluster_ids = df[df['Cluster'] == i].iloc[:, 0]
    cluster_ids.to_csv(f'cluster_{i}_customers.csv', index=False)

业务解读示例:

  • 高价值客户 (红色簇):消费金额高、购买频繁、最近活跃 → 重点维护
  • 流失风险客户 (蓝色簇):历史消费尚可但久未购买 → 激活营销
  • 潜力客户 (绿色簇):购买频率高但单次金额低 → 交叉销售

实际项目中,我经常发现业务人员对三维图的理解存在困难。这时可以制作二维投影图矩阵辅助解释:

from pandas.plotting import scatter_matrix

# 选择两个关键特征做二维散点图
pd.plotting.scatter_matrix(
    df.iloc[:, [0, 1, -1]], 
    c=df['Cluster'],
    figsize=(12, 8),
    diagonal='kde'
)
plt.suptitle('特征间二维关系矩阵')
plt.tight_layout()

6. 进阶技巧与问题排查

处理非数值数据

如果数据包含分类变量(如地区、产品类型),需要先进行编码:

from sklearn.preprocessing import OneHotEncoder

# 假设第4列是分类变量
encoder = OneHotEncoder(sparse=False)
categorical = encoder.fit_transform(df.iloc[:, 3].values.reshape(-1, 1))

# 合并数值和分类特征
final_data = np.hstack((normalized_data, categorical))

常见报错解决方案

  • 内存不足 :对于超大数据集,使用 MiniBatchKMeans
  • 收敛警告 :增加 max_iter 或调整 tol 参数
  • 空簇问题 :设置 n_init=10 增加初始化次数

性能优化

当数据量超过10万行时,可以考虑:

from sklearn.cluster import MiniBatchKMeans

mbk = MiniBatchKMeans(n_clusters=3, batch_size=1000)
mbk.fit(large_data)

7. 自动化脚本整合

将全流程封装为函数,实现一键运行:

def excel_kmeans(input_file, output_dir, n_clusters=3):
    """Excel数据聚类全流程处理"""
    import os
    os.makedirs(output_dir, exist_ok=True)
    
    # 1. 数据加载
    df = pd.read_excel(input_file)
    
    # 2. 数据预处理
    scaler = MinMaxScaler()
    normalized = scaler.fit_transform(df.iloc[:, :3])
    
    # 3. 聚类分析
    kmeans = KMeans(n_clusters=n_clusters)
    clusters = kmeans.fit_predict(normalized)
    df['Cluster'] = clusters
    
    # 4. 可视化
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    colors = ['r', 'g', 'b']
    for i in range(n_clusters):
        ax.scatter(normalized[clusters==i, 0], 
                  normalized[clusters==i, 1],
                  normalized[clusters==i, 2],
                  c=colors[i], label=f'Cluster {i}')
    plt.legend()
    plt.savefig(f'{output_dir}/3d_cluster.png')
    
    # 5. 结果保存
    df.to_excel(f'{output_dir}/clustered_data.xlsx', index=False)
    return df

# 使用示例
result = excel_kmeans('sales_data.xlsx', 'output')

这个脚本在实际业务中已经帮助多个团队快速完成了客户分群分析,特别是当需要定期更新聚类结果时,只需替换输入文件即可获得最新分析。

更多推荐