K Means算法实战:零售客户分群(三十一)

在当今数据驱动的时代,深入了解客户的需求和行为对于企业的成功至关重要。然而,当面对成千上万甚至更多的客户时,手动分析每个客户的特征和行为模式变得几乎不可能。此时,机器学习中的无监督学习技术,尤其是聚类算法,成为了强大的工具。本文将通过一个实战项目,详细介绍如何使用 K-Means 聚类算法对零售客户数据进行分群,从而为企业提供有价值的商业洞察。

什么是聚类分析?

聚类分析是一种无监督学习方法,旨在发现数据中的自然分组。与监督学习不同,聚类算法不需要预先标注好的“正确答案”(即标签)。它的目标是将相似的数据点自动归入同一组(称为“簇”),同时使不同组之间的数据点尽可能不相似。

一个简单的比喻:假设你有一个篮子,里面装着各种水果,包括苹果、橙子和香蕉。聚类算法的任务就是在没有任何人告诉你这些水果名称的情况下,自动将形状、颜色和大小相似的水果分别堆成一堆。

K-Means 算法的工作原理

K-Means 是最常用且直观的聚类算法之一。“K”代表我们希望将数据划分成的簇的数量。其工作原理可以概括为以下几个步骤:

  1. 初始化:随机选择 K 个数据点作为初始的“簇中心”(质心)。
  2. 分配:计算每个数据点到各个质心的距离(通常使用欧氏距离),然后将每个点分配到离它最近的质心所在的簇。
  3. 更新:重新计算每个簇的质心(即该簇所有点的平均值)。
  4. 迭代:重复步骤 2 和 3,直到质心的位置不再发生显著变化,或者达到预设的迭代次数。

算法核心要点

  • 距离度量:通常使用欧氏距离来衡量数据点之间的相似度,距离越近,相似度越高。
  • 质心:代表一个簇的“平均点”或中心点。
  • 目标:最小化每个簇内数据点到其质心的距离平方和(称为“簇内平方和”或 Inertia)。

实战演练:零售客户分群

接下来,我们将通过一个具体的实战项目,使用 Python 及其强大的数据科学库来完成客户分群。我们将使用一个模拟的零售客户数据集,从数据准备到模型评估,最终获得具有商业洞察力的分群结果。

第一步:环境准备与数据加载

首先,确保你的 Python 环境中安装了必要的库:pandas 用于数据处理,numpy 用于数值计算,matplotlib 和 seaborn 用于可视化,scikit-learn 是核心的机器学习库。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score

我们将使用一个模拟的客户数据集 customer_data.csv,它包含以下特征:

  • CustomerID: 客户唯一标识
  • Age: 年龄
  • AnnualIncome(k$): 客户年收入(千美元)
  • Spending_Score: 消费评分(0-100,由购买频率、金额等综合得出)

加载数据并查看基本信息:

df = pd.read_csv('customer_data.csv')

print("数据形状(行数,列数):", df.shape)
print("\n数据前5行:")
print(df.head())
print("\n数据基本信息:")
print(df.info())
print("\n描述性统计:")
print(df.describe())

输出:

数据形状(行数,列数): (50, 4)

数据前5行:
   CustomerID  Age  Annual_Income_(k$)  Spending_Score
0           1   19                  15              39
1           2   21                  15              81
2           3   20                  16               6
3           4   23                  16              77
4           5   31                  17              40

数据基本信息:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 50 entries, 0 to 49
Data columns (total 4 columns):
 #   Column              Non-Null Count  Dtype
---  ------              --------------  -----
 0   CustomerID          50 non-null     int64
 1   Age                 50 non-null     int64
 2   Annual_Income_(k$)  50 non-null     int64
 3   Spending_Score      50 non-null     int64
dtypes: int64(4)
memory usage: 1.7 KB
None

描述性统计:
       CustomerID        Age  Annual_Income_(k$)  Spending_Score
count    50.00000  50.000000           50.000000       50.000000
mean     25.50000  35.560000           28.160000       51.680000
std      14.57738  14.283085            8.739682       31.506682
min       1.00000  18.000000           15.000000        3.000000
25%      13.25000  23.000000           21.000000       20.750000
50%      25.50000  31.000000           27.500000       61.000000
75%      37.75000  47.500000           36.250000       77.000000

max      50.00000  67.000000           44.000000       99.000000

第二步:数据探索与预处理

在应用算法之前,我们需要对数据进行探索和预处理,以确保数据的质量和一致性。

1. 探索性数据分析

通过可视化和统计分析,初步了解数据的分布和特征之间的关系。

fig, axes = plt.subplots(1, 3, figsize=(15, 4))

sns.histplot(df['Age'], bins=30, kde=True, ax=axes[0])
axes[0].set_title('年龄分布')

sns.histplot(df['Annual_Income_(k$)'], bins=30, kde=True, ax=axes[1])
axes[1].set_title('年收入分布')

sns.histplot(df['Spending_Score'], bins=30, kde=True, ax=axes[2])
axes[2].set_title('消费评分分布')

plt.tight_layout()
plt.show()

sns.pairplot(df[['Age', 'Annual_Income_(k$)', 'Spending_Score']])
plt.suptitle('特征关系散点图矩阵', y=1.02)
plt.show()

2. 数据预处理

聚类算法对特征的量纲非常敏感。为了消除不同特征之间数值范围的差异,我们需要进行特征标准化,将各个特征缩放到均值为0、方差为1的标准正态分布。

features = ['Age', 'Annual_Income_(k$)', 'Spending_Score']
X = df[features].copy()

scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
X_scaled_df = pd.DataFrame(X_scaled, columns=features)

print("标准化后的数据前5行:")
print(X_scaled_df.head())

第三步:确定最佳簇数(K值)

K-Means 算法需要我们预先指定 K 值。选择一个合适的 K 值是聚类分析中的一个重要步骤。我们可以通过以下两种方法来确定最佳的 K 值:

1. 肘部法则

绘制不同 K 值对应的簇内平方和(Inertia),寻找曲线的拐点。拐点之后的 K 值带来的收益(Inertia 下降)逐渐减少。

inertia = []
K_range = range(1, 11)

for k in K_range:
    kmeans = KMeans(n_clusters=k, random_state=42, n_init='auto')
    kmeans.fit(X_scaled)
    inertia.append(kmeans.inertia_)

plt.figure(figsize=(8, 5))
plt.plot(K_range, inertia, 'bo-')
plt.xlabel('簇的数量 (K)')
plt.ylabel('簇内平方和 (Inertia)')
plt.title('肘部法则:选择最佳K值')
plt.xticks(K_range)
plt.show()

2. 轮廓系数法

轮廓系数衡量一个数据点与自身簇的相似度(内聚度)和与其他簇的分离度。其值在 -1 到 1 之间,越高越好,表示聚类效果越佳。

silhouette_scores = []
K_range = range(2, 11)

for k in K_range:
    kmeans = KMeans(n_clusters=k, random_state=42, n_init='auto')
    cluster_labels = kmeans.fit_predict(X_scaled)
    score = silhouette_score(X_scaled, cluster_labels)
    silhouette_scores.append(score)

plt.figure(figsize=(8, 5))
plt.plot(K_range, silhouette_scores, 'go-')
plt.xlabel('簇的数量 (K)')
plt.ylabel('轮廓系数')
plt.title('轮廓系数法:选择最佳K值')
plt.xticks(K_range)
plt.show()

综合肘部法则图(拐点)和轮廓系数图(峰值),我们假设确定 K=5 是一个不错的选择。

第四步:应用 K-Means 进行聚类

使用选定的 K 值训练模型,并为每个客户打上簇标签。

final_k = 5
kmeans_final = KMeans(n_clusters=final_k, random_state=42, n_init='auto')
df['Cluster'] = kmeans_final.fit_predict(X_scaled)

cluster_counts = df['Cluster'].value_counts().sort_index()
print("各簇客户数量分布:")
print(cluster_counts)

cluster_profile = df.groupby('Cluster')[features].mean().round(2)
print("\n各簇特征平均值:")
print(cluster_profile)

第五步:结果分析与可视化

将抽象的簇标签转化为直观的洞察。

1. 可视化聚类结果

由于我们有三个特征,可以在二维平面上选择两个最重要的特征进行可视化(例如收入和消费评分)。

plt.figure(figsize=(10, 6))
scatter = plt.scatter(df['Annual_Income_(k$)'], df['Spending_Score'], c=df['Cluster'], cmap='viridis', s=50, alpha=0.7)
plt.colorbar(scatter, label='簇标签')
plt.xlabel('年收入 (k$)')
plt.ylabel('消费评分')
plt.title('客户分群结果(基于年收入与消费评分)')
plt.show()

2. 刻画客户群画像

根据 cluster_profile 表格,我们可以为每个簇赋予商业含义:

簇标签年龄年收入消费评分可能的客户画像
0中等高收入谨慎型:收入高但消费保守,可能是储蓄者或对价格敏感的高净值人群。
1中等低收入低消费型:收入和消费能力都有限,需要高性价比产品。
2中等追求价值型:收入不高但很爱消费,注重潮流和体验,是促销活动的目标。
3中等理想VIP型:高收入高消费,是企业的核心利润来源,应提供顶级服务和专属权益。
4年轻中等中等年轻潜力型:年轻客户,收入和消费处于成长期,是培养品牌忠诚度的关键。

第六步:模型评估与应用建议

评估

除了轮廓系数,还可以查看簇内样本分布是否均衡,以及结合业务逻辑判断分群是否合理。

应用建议

  • 精准营销:向“理想VIP型”(簇3)推送高端新品和独家活动;向“追求价值型”(簇2)发送折扣券和团购信息。
  • 产品开发:针对“年轻潜力型”(簇4)设计时尚、社交属性强的产品。
  • 客户服务:为“高收入谨慎型”(簇0)提供详细的产品数据和安全保障,打消其顾虑。
  • 资源分配:将更多客服和营销资源倾斜到高价值客户群。

总结与扩展

通过这个实战案例,你已经完整地体验了使用 K-Means 算法进行客户分群的流程:数据准备 -> 探索分析 -> 预处理 -> 确定K值 -> 训练模型 -> 分析结果

关键要点回顾

  • 聚类是无监督学习,用于发现数据中的自然分组。
  • 特征标准化是使用基于距离的聚类算法前的关键步骤。
  • 肘部法则轮廓系数是确定最佳簇数的实用工具。
  • 聚类结果的解读必须结合业务知识,才能产生真正的价值。

希望这篇文章对你有所帮助,如果你有任何问题或建议,欢迎在评论区留言交流!