超简单聚类项目 —— Customer Segmentation

84 阅读5分钟

️‍🪟Mall Customer Segmentation

1.png


🤔问题陈述

你拥有商场,想要了解哪些客户可以很容易地聚集在一起(目标客户),这样就可以给营销团队提供这种感觉,并制定相应的策略。

✅理解数据含义

特征含义说明
CustomerIDIDAnnual Income (k dollar) 的排序
Gender性别Male 男 & Female 女
Age年龄\
Annual Income (k dollar)年收入k dollar = 千美元
Spending Score (1-100)支出分数支出分数是你根据客户行为和购买数据等定义的参数分配给客户的东西

🎯部分可视化数据展示

5.png

🧑‍💻部分代码展示

from sklearn.cluster import KMeans
kmeans_list = [KMeans(n_clusters=k, random_state=29).fit(df_scaler) for k in range(2, 10)]
inertia_list = [model.inertia_ for model in kmeans_list]
plt.figure(figsize=(8, 4))
plt.plot(range(2, 10), inertia_list, 'go-')
plt.xlabel('Cluster Num')
plt.ylabel('Inertia')
plt.title('Inertia Metrics')
from sklearn.metrics import silhouette_score
silhouette_scores = [silhouette_score(df_scaler, model.labels_) for model in kmeans_list]
plt.plot(range(2, 10), silhouette_scores, 'yo-')
plt.xlabel('Cluster Num')
plt.ylabel('Contour Factor')
plt.title('Contour Factor Shift')
kmeans_5 = KMeans(n_clusters=5, random_state=29).fit(df_scaler)
kmeans_6 = KMeans(n_clusters=6, random_state=29).fit(df_scaler)

from plotly.subplots import make_subplots
fig = make_subplots(
    rows=1, cols=2,
    specs=[[{'type': 'scatter3d'}, {'type': 'scatter3d'}]],
    subplot_titles=("K=5 Clusters", "K=6 Clusters")
)

fig_k5 = px.scatter_3d(np.c_[df_scaler, kmeans_5.labels_], x=0, y=1, z=2, color=3, color_discrete_sequence=px.colors.qualitative.Plotly)
fig_k6 = px.scatter_3d(np.c_[df_scaler, kmeans_6.labels_], x=0, y=1, z=2, color=3, color_discrete_sequence=px.colors.qualitative.Plotly)

for trace in fig_k5.data:
    fig.add_trace(trace, row=1, col=1)
for trace in fig_k6.data:
    fig.add_trace(trace, row=1, col=2)

camera = dict(
    up=dict(x=0, y=0, z=1),
    center=dict(x=0, y=0, z=0),
    eye=dict(x=1.5, y=1.5, z=0.5)
)

fig.update_layout(
    scene=dict(
        domain=dict(x=[0, 0.5], y=[0, 1]),  # 第一个子图位置
        xaxis_title='Age',
        yaxis_title='Annual Income (k$)',
        zaxis_title='Spending Score (1-100)',
        camera=camera
    ),
    scene2=dict(
        domain=dict(x=[0.5, 1], y=[0, 1]),  # 第二个子图位置
        xaxis_title='Age',
        yaxis_title='Annual Income (k$)',
        zaxis_title='Spending Score (1-100)',
        camera=camera
    ),
    width=1200,
    height=600,
    margin=dict(r=10, l=10, b=10, t=40)
)
def plot_data(data, choose, y, label=False):
    choose_data = data.iloc[:, choose]
    plt.scatter(choose_data.iloc[:, 0], choose_data.iloc[:, 1], c=y, cmap=plt.cm.brg)
    if label:
        label = choose_data.columns
        plt.xlabel(label[0])
        plt.ylabel(label[1])

def plot_centroid(model, data, choose):
    choose_data = data.iloc[:, choose]
    centroids = model.cluster_centers_ * np.std(choose_data, axis=0).values + np.mean(choose_data, axis=0).values
    for centroid in centroids:
        plt.scatter(centroid[0], centroid[1], s=100, marker='o', color='k')
        plt.scatter(centroid[0], centroid[1], s=30, marker='x', color='r')
    return centroids

def plot_boundary(model, data, choose):
    np_data = data.iloc[:, choose].to_numpy()
    mins = np_data.min(axis=0) - 5
    maxs = np_data.max(axis=0) + 5

    x1, x2 = np.meshgrid(
        np.linspace(mins[0], maxs[0], 500), 
        np.linspace(mins[1], maxs[1], 500)
    )
    none_data = np.ones(500 ** 2 * 3).reshape(-1, 3)
    none_data[:, choose] = np.c_[x1.ravel(), x2.ravel()]
    z = model.predict(scaler.transform(none_data)[:, choose]).reshape(x1.shape)
    
    plt.contour(z, extent=(mins[0], maxs[0], mins[1], maxs[1]), linewidths=1, colors='r')

🚀对标实际业务


1. Annual Income (k$) | Spending Score (1-100)

客户 年收入 与 支付分数 聚类

9.png

根据 年收入支付分数 的不同将客户分为 5 类:

  1. 低收入、低支付:位于图像 左下角 红色散点区域,这些客户所创造的价值较低且数量较少。 --> 挽留客户
  2. 低收入、高支付:位于图像 左上角 绿色散点区域,这些客户单次花费较高,它们可能是储蓄购买。 --> 潜在客户
  3. 中等收入、中等支付:位于图像 中心 黄色散点区域,这些客户收支都处在中等水平,但客户群体大、数量多。 --> 重要发展客户
  4. 高收入、低支付:位于图像 右下角 蓝色散点区域,这些客户对商品的忠诚度并不高。 --> 重要价值客户
  5. 高收入、高支付:位于图像 右上角 粉色散点区域,这些客户所创造的价值最高! --> 重要保持客户

应对策略:

  1. 挽留客户
    • 推出更多廉价商品促销活动,刺激该群体消费。
    • 推出免费活动,帮助商城引流造势。
  2. 潜在客户
    • 降低部分与此类客户相关的商品价格,吸引客户提前消费。
    • 举办相应商品的联动等流量活动,增加销量。
  3. 重要发展客户
    • 设立相关商品专区架柜,方便客户快速购买。
    • 看见未来:利用客户心理,向该类客户推销更高支付产品。
  4. 重要价值客户
    • 针对客户需求,定制专属商品吸引消费。
    • 举办此类人群的社区活动,利用攀比心理促进消费。
  5. 重要保持客户
    • 提供 VIP 服务

2. Age | Spending Score (1-100)

客户 年龄 与 支付分数 聚类

13.png

根据 年龄支付分数 的不同将客户分为 2 类:

  1. 年龄15-40、支付高:位于图像 左上角 绿色散点区域,这些年轻客户消费欲望强,支付水平高。
  2. 年龄40+、支付低:位于图像 右下角 蓝色散点区域,这些中老年客户消费欲望低,支付水平低。

应对策略:

  1. 年轻客户
    • 对市面上的年轻流量商品进行引进推行,并为此举办活动。
    • 根据收入再次进行分层,提供不同层服务,刺激客户消费。
  2. 中老年客户
    • 提供社区服务,推销养老等相关合格商品吸引客户。
    • 为家庭出游提供热度与相关活动,以促进客户消费。

🔢学习总结

这纯纯是一个新手练习项目(而且还是七年前的项目),没太多技术研究,但还是有一些收获:

  1. 首先就是刚刚的用户分群问题,需要具有一定的业务能力。
  2. 其次对于特征和参数的选择需要对比验证。
  3. 聚类本身是无法衡量的,就比如 3D 聚类,有时无法自圆其说。

❤️‍🔥我们一起加油学习吧!

🪢相关链接

  1. Data
  2. GitHub
  3. GitCode