基于RFM分析 + Kmeans聚类的客户分群

一、引言

RFM模型是衡量客户价值和客户创利能力的重要工具和手段。在客户分类中,RFM模型是一个经典的分类模型,利用通用交易环节中最核心的三个维度——最近消费(Recency)、消费频率(Frequency)、消费金额(Monetary)细分客户群体,从而分析不同群体的客户价值。

数据集为英国在线零售商在2010年12月1日至2011年12月9日间发生的所有网络交易订单信息。该公司主要销售礼品为主,并且多数客户为批发商。

数据集特征说明:

  • nvoiceNo:订单编号,由六位数字组成,退货订单编号开头有字母C
  • StockCode:产品编号,由五位数字组成
  • Description:产品描述
  • Quantity:产品数量,负数表示退货
  • InvoiceDate:订单日期与时间
  • UnitPrice :单价(英镑)
  • CustomerID:客户编号,由5位数字组成
  • Country:国家

数据集介绍及来源:

  • https://archive.ics.uci.edu/ml/datasets/online+retail
  • https://www.kaggle.com/datasets/carrie1/ecommerce-data

使用算法: RFM模型、聚类算法

二、数据导入与预览

import pandas as pd 

# 数据导入
data = pd.read_excel(r'E:/大三(下)/数据分析课程设计/二/Online Retail.xlsx')
data.head()
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
# 查看数据基本信息
print('数据结构:')
print(data.info())    # 查看数据结构和缺失值

print('\n数据统计信息:\n', data.describe())    # 查看数据统计信息
数据结构:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 541909 entries, 0 to 541908
Data columns (total 8 columns):
 #   Column       Non-Null Count   Dtype         
---  ------       --------------   -----         
 0   InvoiceNo    541909 non-null  object        
 1   StockCode    541909 non-null  object        
 2   Description  540455 non-null  object        
 3   Quantity     541909 non-null  int64         
 4   InvoiceDate  541909 non-null  datetime64[ns]
 5   UnitPrice    541909 non-null  float64       
 6   CustomerID   406829 non-null  float64       
 7   Country      541909 non-null  object        
dtypes: datetime64[ns](1), float64(2), int64(1), object(4)
memory usage: 33.1+ MB
None

数据统计信息:
             Quantity                    InvoiceDate      UnitPrice  \
count  541909.000000                         541909  541909.000000   
mean        9.552250  2011-07-04 13:34:57.156386048       4.611114   
min    -80995.000000            2010-12-01 08:26:00  -11062.060000   
25%         1.000000            2011-03-28 11:34:00       1.250000   
50%         3.000000            2011-07-19 17:17:00       2.080000   
75%        10.000000            2011-10-19 11:27:00       4.130000   
max     80995.000000            2011-12-09 12:50:00   38970.000000   
std       218.081158                            NaN      96.759853   

          CustomerID  
count  406829.000000  
mean    15287.690570  
min     12346.000000  
25%     13953.000000  
50%     15152.000000  
75%     16791.000000  
max     18287.000000  
std      1713.600303  
# 缺失值检验
data.isnull().sum()

三、数据预处理

InvoiceNo           0
StockCode           0
Description      1454
Quantity            0
InvoiceDate         0
UnitPrice           0
CustomerID     135080
Country             0
dtype: int64
# 删除重复数据
data.drop_duplicates(inplace=True)
# 修正数据类型
data['CustomerID'] = data['CustomerID'].astype(str)
# 缺失值处理(特别是CustomerID缺失的记录)
data.dropna(subset=['CustomerID'], inplace=True)
# 删除异常值

data = data[data.Quantity > 0]    #(数量为负数的退货订单)
data = data[data.UnitPrice > 0]    #(单价为负数的数据)
# 增加总金额列
data['total_amount'] = data.Quantity * data.UnitPrice
data.head()
InvoiceNo StockCode Description Quantity InvoiceDate UnitPrice CustomerID Country total_amount
0 536365 85123A WHITE HANGING HEART T-LIGHT HOLDER 6 2010-12-01 08:26:00 2.55 17850.0 United Kingdom 15.30
1 536365 71053 WHITE METAL LANTERN 6 2010-12-01 08:26:00 3.39 17850.0 United Kingdom 20.34
2 536365 84406B CREAM CUPID HEARTS COAT HANGER 8 2010-12-01 08:26:00 2.75 17850.0 United Kingdom 22.00
3 536365 84029G KNITTED UNION FLAG HOT WATER BOTTLE 6 2010-12-01 08:26:00 3.39 17850.0 United Kingdom 20.34
4 536365 84029E RED WOOLLY HOTTIE WHITE HEART. 6 2010-12-01 08:26:00 3.39 17850.0 United Kingdom 20.34

四、计算R、F、M的值

import datetime as dt

# 设置当前日期(数据中的最新订单日期)
latest_date = data['InvoiceDate'].max() + dt.timedelta(days=1)

# 计算R、F、M
rfm = data.groupby(by='CustomerID').agg({
    
    
    'InvoiceDate': lambda x: (latest_date - x.max()).days,
    'InvoiceNo': 'nunique', 
    'total_amount': 'sum'
})

rfm.rename(columns={
    
    
    'InvoiceDate': 'R', 
    'InvoiceNo': 'F',
    'total_amount': 'M'
}, inplace=True)

# 查看RFM数据
rfm.head()
R F M
CustomerID
12346.0 326 1 77183.60
12347.0 2 7 4310.00
12348.0 75 4 1797.24
12349.0 19 1 1757.55
12350.0 310 1 334.40

五、数据标准化

from sklearn.preprocessing import StandardScaler

# 数据标准化
scaler = StandardScaler()
rfm_scaled = scaler.fit_transform(rfm)

# 转为DataFrame
rfm_scaled = pd.DataFrame(rfm_scaled, columns=rfm.columns, index=rfm.index)

六、绘制肘部图

from sklearn.cluster import KMeans
import matplotlib.pyplot as plt 

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']

sse = {
    
    }
for k in range(1, 11):
    kmeans = KMeans(n_clusters=k, random_state=40)
    kmeans.fit(rfm_scaled)
    sse[k] = kmeans.inertia_    # 簇内平方和 SSE(越小越好)

# 绘制肘部法则图
plt.figure(figsize=(8, 5))
plt.plot(list(sse.keys()), list(sse.values()), marker='o')
plt.xlabel('k')
plt.ylabel('SSE')
plt.title('肘部法则图')
plt.show()

在这里插入图片描述

七、选择合适的k,建模

# 根据肘部法则图,选择k=3最优。
kmeans = KMeans(n_clusters=3, random_state=40)
kmeans.fit(rfm_scaled)

# 将聚类结果添加到RFM数据中
rfm['Cluster'] = kmeans.labels_

print(rfm.head())
              R  F         M  Cluster
CustomerID                           
12346.0     326  1  77183.60        1
12347.0       2  7   4310.00        0
12348.0      75  4   1797.24        0
12349.0      19  1   1757.55        0
12350.0     310  1    334.40        1

八、结果展示

from sklearn.decomposition import PCA
import seaborn as sns

# 使用PCA降维到2D
pca = PCA(n_components=2)
rfm_pca = pca.fit_transform(rfm_scaled)
rfm_pca = pd.DataFrame(rfm_pca, columns=['PC1', 'PC2'], index=rfm.index)
rfm_pca['Cluster'] = rfm['Cluster']

# 可视化聚类结果
plt.figure(figsize=(10, 6))
sns.scatterplot(x='PC1', y='PC2', hue='Cluster', data=rfm_pca, palette='viridis')
plt.show()

在这里插入图片描述

九、客户群体特征分析

# 计算每个群体的RFM平均值
cluster_summary = rfm.groupby('Cluster').agg({
    
    
    'R': 'mean',
    'F': 'mean',
    'M': 'mean'
}).round(2)

print(cluster_summary)
              R      F          M
Cluster                          
0         40.98   4.85    2005.83
1        246.02   1.58     629.36
2          7.14  80.21  122748.79
  • 高价值客户:Recency低、Frequency高、Monetary高(如Cluster 2)。

    流失客户:Recency高、Frequency低、Monetary低(如Cluster 1)。

十、根据客户群体的特征制定相应的运营策略(粗略带过)

  • 高价值客户(Cluster 2):提供VIP服务、个性化推荐、专属折扣。

  • 潜在高价值客户(Cluster 0):通过促销活动提高消费频率。

  • 流失客户(Cluster 1):发送召回邮件、提供优惠券。

# 文章如有错误,欢迎大家指正。我们下期再见叭

猜你喜欢

转载自blog.csdn.net/weixin_74268817/article/details/146263900
今日推荐