基于客户细分的在线零售数据分析及营销策略
1. 《基于客户细分的在线零售数据分析及营销策略》
2. 客户细分数据分析文档说明
3. 项目概述
通过对在线零售数据集的分析,实现客户细分,帮助企业更好地了解客户群体特征,制定精准的营销策略。分析过程包括数据预处理、探索性数据分析、特征工程和聚类分析等步骤,最终将客户分为不同的群体。
4. 环境准备与数据导入
5. 2.1导入必要的库
|
6. 读取并查看数据集
|
| InvoiceNo | StockCode | Description | Quantity | InvoiceDate | UnitPrice | CustomerID | Country | |
| 0 | 536365 | 85123A | WHITE HANGING HEART T-LIGHT HOLDER | 6 | 2010-12-01 08:26:00 | 2.55 | 17850.0 | United Kingdom |
| 1 | 536365 | 71053 | WHITE METAL LANTERN | 6 | 2010-12-01 08:26:00 | 3.39 | 17850.0 | United Kingdom |
| 2 | 536365 | 84406B | CREAM CUPID HEARTS COAT HANGER | 8 | 2010-12-01 08:26:00 | 2.75 | 17850.0 | United Kingdom |
| 3 | 536365 | 84029G | KNITTED UNION FLAG HOT WATER BOTTLE | 6 | 2010-12-01 08:26:00 | 3.39 | 17850.0 | United Kingdom |
| 4 | 536365 | 84029E | RED WOOLLY HOTTIE WHITE HEART. | 6 | 2010-12-01 08:26:00 | 3.39 | 17850.0 | United Kingdom |
数据集包含在线零售交易记录,主要字段包括:
InvoiceNo:发票编号
StockCode:商品代码
Description:商品描述
Quantity:购买数量
- InvoiceDate:发票日期
UnitPrice:单价 - CustomerID:客户编号
Country:国家
7. 数据检查与探索性分析(EDA)
8. 数据基本信息检查
9. 查看数据维度(行列数)
print(“Number of Columns in the Data: “, df.shape[1])
print(“Number of Rows in the Data: “, df.shape[0])
|
可以看到该数据集有 8 列,541909 行
10. 检查各列数据类型
df.info()
|
11. 统计非空值情况、缺失值数量和重复记录数量
检查数据中的缺失值数量
|
12. 3.2探索性数据分析(EDA)
13. 描述性统计
des $=$ df.describe().transpose()
palette = sns.color_\palette(“icefire”, as_\cmap=True)
des.stylebackground_\gradient(cmap=palette)
生成数值型变量的描述性统计表格,包括均值、标准差、四分位数等。
| count | mean | min | 25% | 50% | 75% | max | std | |
| Quantity | 541909.000000 | 9.552250 | -80995.000000 | 1.000000 | 3.000000 | 10.000000 | 80995.000000 | 218.081158 |
| InvoiceDate | 541909 2011-07-04 13:34:57.156386048 | 2010-12-01 08:26:00 | 2011-03-28 11:34:00 | 2011-07-19 17:17:00 | 2011-10-19 11:27:00 | 2011-12-09 12:50:00 | nan | |
| UnitPrice | 541909.000000 | 4.611114 | -11062.050000 | 1.250000 | 2.080000 | 4.130000 | 38970.000000 | 96.759853 |
| CustomerID | 406829.000000 | 15287.690570 | 12346.000000 | 13953.000000 | 15152.000000 | 16791.000000 | 18287.000000 | 1713.600303 |
14. 国家分布分析
绘制前10个最频繁国家的柱状图
country_count = df.Country.value_counts().head(10)
plt.figure(figsize=(10,6))
sns.barplot(x=country_count.values, y=country_count.index,
palette=’viridis’)
plt.title(“Top 10 Most Frequent Countries”, fontsize=16)
plt.xlabel(“Number of Repetitions”)
plt;ylabel(“Country”)
plt.show()
绘制条形图展示购买次数最多的前10个国家,帮助了解主要市场分布。可以看到购买次数最多的就是United Kingdom,其购买数量远远超过其他国家

Top 10 Most Frequent Countries
15. 时间趋势分析
绘制前10个最频繁时间的柱状图
df[‘InvoiceDate’] = pd.todatetime(df[‘InvoiceDate’], format=’%Y-%m-%d.%f’)
time_trfriend $=$ df[‘InvoiceDate’].value_counts().head(10)
plt.figure(figsize=(10,6))
sns.barplot(x = time_trfriend.values, y = time_trfriend.index,
palette=’viridis’)
plt.title(‘Top 10 Most Frequent Time’, fontsize=16)
plt.xlabel(‘Number of Orders’)
pltylabel(‘Time’)
plt.show()
将发票日期转换为 datetime 格式,分析订单最频繁的前 10 个时间点,了解购买时间趋势。如图所示,购买时间最多的时 2011-10-31 14:41:00,其他的时间购买频数远低于这
个时间。

Top 10 Most Frequent Time
16. 商品描述分析
绘制前10个最频繁商品的柱状图
description_count = df[“Description”].value_counts().head(10)
plt.figure(figsize=(10,6))
sns.barplot(x=description_count.values, y=description_count.index, palette=’viridis’)
plt.title(“Top 10 Frequent Items”, fontsize=16)
plt.xlabel(“Number of Orders”)
plt;ylabel(“Items”)
plt.show()
分析购买次数最多的前10种商品,帮助识别畅销商品。
- WHITE HANGING HEART T - LIGHT HOLDER:白色悬挂心形小烛台
- REGENCY CAKESTAND 3 TIER:摄政风格三层蛋糕架
JUMBO BAG RED RETROSPOT:大号红色复古波点袋
PARTY BUNTING:派对彩旗
LUNCH BAG RED RETROSPOT:红色复古波点午餐袋
ASSORTED COLOUR BIRD ORNAMENT:各色鸟类装饰品 - SET OF 3 CAKE TINS PANTRY DESIGN:三件套食品间风格蛋糕模具
- PACK OF 72 RETROSPOT CAKE CASES : 72 个装复古波点蛋糕纸杯
LUNCH BAG BLACK SKULL:黑色骷髅图案午餐袋 - NATURAL SLATE HEART CHALKBOARD:天然板岩心形小黑板

Top 10 Frequent Items
17. 数值型变量分布与异常值检查
绘制数值型特征的直方图
|
绘制数值型特征的箱线图
|
绘制直方图和箱线图,分析数值型变量 (Quantity, UnitPrice 等) 的分布特征和异常值情况。
18. 数据预处理
19. 数据去重
删除重复值
|
移除重复记录,确保数据唯一性,有助于提高聚类模型的泛化能力。
20. 4.2异常值处理
使用四分位距(IQR)方法识别并移除异常值:
- 计算第 1 四分位数 (q1) 和第 3 四分位数 (q3)
- 计算 $\mathrm{IQR} = \mathrm{q3 - q1}$
- 定义异常值边界:upper_limit = q3 + 1.5IQR, lower_limit = q1 - 1.5IQR
- 保留在边界范围内的数据
21. 4.2.1“数量”特征异常值处理
处理“数量”特征的异常值
|
|
|
22. 数值型变量异常值处理
处理“单价”特征的异常值
|
|
|
23. 数据处理后的箱线图
绘制处理后数值型特征的箱线图
|



从这组箱线图(Box Plot)来看,可初步对三个变量
(Quantity、UnitPrice、CustomerID) 的数据集分布做如下分析:
24. Quantity (数量)
集中趋势:中位数(箱内横线位置)大概在3-7区间(因图中刻度,大致估算),说明半数数据的数量处于这个中间位置,数据有一定集中性。
离散程度:箱体上下限代表四分位数范围(IQR,即第25百分位数到第75百分位数),能看到数据在箱体范围内相对集中;须线延伸到-5到15左右(非异常值的最值),不过左侧须线到-5,但数量理论上不能为负,可能存在异常值或者数据录入问题,也可能是业务中特殊场景(比如退货等导致数量为负,需结合实际业务判断),整体离散程度可通过箱体长度和须线判断,数据有一定波动。
异常值:从须线看,若超出 $1.5^{*}\mathrm{IQR}$ 范围可视为异常值,这里左右须线延伸情况,结合数量不能为负,左侧可能存在异常负值,需进一步核查数据。
25. UnitPrice (单价)
集中趋势:中位数在2-3左右,表明半数数据的单价处于此区间,数据集中趋势较明显,大部分单价围绕这个中间值分布。
离散程度:箱体较短,说明四分位数范围内数据比较集中;须线延伸到0到6左右,整体数据离散程度相对小,单价波动不算特别大,大部分单价在较窄区间内。异常值:图中未明显看出超出 $1.5^{*}\mathrm{IQR}$ 范围的极端异常值,数据分布相对规整
26. CustomerID(客户编号)
集中趋势:中位数在14000-16000区间,客户编号是标识类数据,这里看其数值分布的中间位置,反映数据集中点。
离散程度:箱体展示了客户ID数值的四分位数范围,须线延伸到14000以下和18000左右,因客户ID是编号,理论上是有序或随机分配的数值,从箱线图看有一定离散性,不过主要关注其分布是否符合业务逻辑(比如是否连续、有无不合理间隔等),若客户ID是按顺序分配,这种离散可能是正常的新老客户编号跨度。
异常值:未明显看到极端异常的客户ID数值(如极大或极小的突兀值),数据分布相对合理
27. 特征编码
准备用于分析的特征变量,对分类变量 “Country” 使用标签编码 (Label Encoding) 转换为数值型。
选择用于聚类的特征
|
对“国家”特征进行编码
|
|
28. 4.4缺失值处理
移除包含缺失值的记录,确保分析数据的完整性。
删除缺失值
X.dropna(inplace=True)
检查缺失值的数量
X.isnull().sum()
29. 特征工程
创建新特征”total_price”,表示每个订单的总金额
|
30. 相关性分析
计算特征之间的相关系数矩阵,并通过热力图可视化:
计算特征之间的相关性矩阵
|
绘制相关性矩阵的热力图
plt.figure(figsize $\coloneqq$ (10,6))
sns_heatmap(corr, annot=True, fmt=”.2f”, cmap=”viridis”)
plt.title(“Correlation Matrix”)
plttightlayout()
plt.show()

颜色深浅表示相关程度数值显示具体相关系数
31. 数据标准化
使用标准化(Standardization)处理特征数据:将数据转换为均值为0,标准差为1的分布,确保不同量纲的特征在聚类分析中具有相同的权重
|
32. 聚类分析
33. 肘部法则确定最佳聚类数量
使用肘部法则 (Elbow Method) 确定最佳聚类数量:计算 2 到 10 个聚类时的 WCSS (Within-Cluster Sum of Squares),WCSS 随聚类数量增加而减小,选择曲线拐点处的聚类数量作为最佳值
34. 使用K-Means聚类算法计算不同聚类数量下的WCSS值
|
绘制肘部曲线
|
|

从图中可以看出,随着聚类数的增大,WCSS逐渐减小。在前几个聚类数(2到4)中,WCSS的减少幅度比较大,而从4到10增加聚类数时,WCSS的下降幅度开始减缓。根据图的形状,3类是一个合理的选择,因为在这个点上,增加聚类数并没有带来显著的WCSS降低。选择3类可以更好地平衡模型的复杂度与解释力。
35. K-means 聚类
|
使用K-means算法将客户分为3个群体:
- nclusters=3:根据肘部法则确定的最佳聚类数量
- random state=42:确保结果可重现
36. 聚类结果可视化
|
使用散点图矩阵可视化聚类结果:

左上:Quantity 按 Cluster 分布的直方图
横轴是 Quantity(数量),纵轴是数量频次。
不同颜色(对应聚类0、1、2)的分布形态差异大:
- 聚类2(黄色):数量集中在0-5区间,峰值高,是最“集中”的类别。
- 聚类1(青绿色):数量在5-15有分布,且有多个小峰值,离散性更强。
- 聚类 0(紫色):数量分布较零散,覆盖负值到正数区间,可能包含特殊场景(如退货导致负数量)。
右上:Cluster 分组的散点矩阵(侧重类别分布)
横轴无明确数值,主要看聚类标签(0、1、2)的“块分布”。
• 聚类 1 (青绿色) 集中在上半区, 聚类 2 (黄色) 在下半区, 聚类 0 (紫色) 穿插其中。
- 直观呈现:聚类 1 和 2 有明显 “区域划分”,聚类 0 相对分散(可能是边界样本或异常点)。
左下:Quantity vs UnitPrice 散点图(带聚类颜色)
横轴 Quantity(数量),纵轴 UnitPrice(单价)。
• 聚类 2(黄色):集中在低单价(0-2)、低数量(0-5)区域,是“小单低价”群体。
- 聚类 1(青绿色):覆盖中高单价(2-6)、中高数量(5-15)区间,是“大单中高价”群体。
- 聚类 0(紫色):分布零散,部分重叠聚类 1/2,可能是 混合特征样本(如退货、特殊订单)。
右下:UnitPrice 按 Cluster 分布的直方图
横轴 UnitPrice(单价),纵轴是单价频次。
- 聚类2(黄色):单价集中在0-2区间,与左上直方图呼应(“小单低价”)。
- 聚类1(青绿色):单价在2-6有多个峰值,体现“中高价”的多样性。
- 聚类 0 (紫色) : 单价分布零散, 与其他聚类有重叠, 进一步验证 “边界 / 异常样本” 特征。
聚类2(黄色):小单低价(低数量、低单价,集中性强)。
聚类1(青绿色):大单中高价(中高数量、中高单价,离散但有区间)。
聚类0(紫色):混合/异常样本(特征零散,可能包含退货、特殊订单等)。