一.项目背景
为了建立客户信息资源管理及运营模式,某公司希望通过客户的基本消费信息进行分析,
衡量客户价值和客户创利能力,优化客户资源,提高营销效率,避免不必要的资源
二.实现步骤
1.导包读入数据,筛选所需数据
# 导入所需库
import numpy as np
import pandas as pd
import datetime
import matplotlib.pyplot as plt
import time
import matplotlib.gridspec as gridspec
#import pyecharts
# 解决 matplotlib 显示中文、负号问题
plt.rcParams['font.family'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
#获取数据
def get_data(file_path):
#读取数据
df1= pd.read_excel(file_path)
# 提取 RFM 模型所需特征列:'订单编号','买家会员名','买家实际支付货款','订单付款时间','宝贝总数量'
df2 = df1[['订单编号','买家会员名','买家实际支付金额','订单付款时间','宝贝总数量']]
#返回数据
return df2
2.数据重复值缺失值处理
#处理数据
def process_data(df):
#判断有没有重复值
if df.duplicated().sum()==0:
print('无重复数据')
else:
#删除重复值
df=df.drop_duplicates(inplace=True)
#判断有没有缺失值
if df.isnull().any().sum()==0:
print('无缺失值')
else:
#删除缺失值
df=df.dropna(inplace=True)
#返回数据
return df
3.获取RFMP各项值
#获取R值
def get_R(df):
# 计算时间差
time_minus = datetime.datetime.now()- df['订单付款时间']
# 将时间差转换成数字格式
df['prior_R'] = time_minus.astype(str).str.findall('d+.*d*').map(lambda x: int(x[0]) + (int(x[1]) / 24) +
(int(x[2]) / (24 * 60)) + (float(x[3]) / (24 * 3600)))
# 按会员进行分组,确定每个会员最近一次购买离现在的时间间隔
R = df.groupby('买家会员名')['prior_R'].min()
return R
#获取FMP值,P值表示买家购买数量
def get_F_M_P(df):
# 按会员进行分组,确定每个会员的订单数量
F = df.groupby('买家会员名')['订单编号'].count()
# 按会员进行分组,确定每个会员的实际支付金额
M = df.groupby('买家会员名')['买家实际支付金额'].sum()
# 按会员进行分组,确定每个会员的宝贝总数量
P = df.groupby('买家会员名')['宝贝总数量'].sum()
return (F,M,P)
#将RFMP数据合成DataFrame
def get_data(R,F,M,P):
#列名称
col_list = list('RFMP')
#创建DataFrame
model_data = pd.DataFrame([], index=R.index)
#添加数据
for col_names, values in zip(col_list, [R, F, M, P]):
model_data[col_names] = values
#类型转换
model_data = model_data.astype(float)
#返回数据
return model_data
4.利用Kmeans算法进行分类
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
from sklearn.preprocessing import StandardScaler, MinMaxScaler
#获取数据
df0 = model_data.iloc[:, 0:4]
#标准化数据
res_std = StandardScaler().fit_transform(df0)
#分类簇数
n_clusters = range(2, 7)
#评分标准
scores = []
#遍历每种分类
for i in range(len(n_clusters)):
#训练模型
clf = KMeans(n_clusters = n_clusters[i], random_state = 20).fit(res_std)
#获取评分
scores.append(silhouette_score(res_std, clf.labels_))
#获取最大评分索引
maxindex = scores.index(max(scores))
#初始画布
plt.figure(figsize = (8, 6), dpi = 100)
#绘制图形
plt.plot(n_clusters, scores, linestyle = '-.', c = 'b', alpha = 0.6, marker = 'o')
#编辑最佳簇数
plt.axvline(x = n_clusters[maxindex], linestyle = '--', c = 'r', alpha = 0.5)
#设置标题
plt.title('RFMP的聚类轮廓系数图')
#设置y轴标签
plt.ylabel('silhouette_score')
#设置x轴标签
plt.xlabel('n_clusters')
#存储图形
plt.savefig('./RFMP聚类轮廓系数图.png')
#获取最佳分簇数模型
clf = KMeans(n_clusters = 2, random_state = 20).fit(res_std)
#添加label
df0['labels'] = clf.labels_
df0
# 统计一下两类用户之间的差异,发现两类客户之间数量相差过大
print(f"类别0所占比例为:{df0['labels'].value_counts().values[0] / df0.shape[0]} t 类别1所占的比例为:{df0['labels'].value_counts().values[1] / df0.shape[0]}")
df0['labels'].value_counts()
#用均值来评估两类样本之间的LRFMP
R_avg = df0.groupby('labels').agg({'R': np.mean}).reset_index()
F_avg = df0.groupby('labels').agg({'F': np.mean}).reset_index()
M_avg = df0.groupby('labels').agg({'M': np.mean}).reset_index()
P_avg = df0.groupby('labels').agg({'P': np.mean}).reset_index()
# 绘制相关的条形图
def plot_bar(df_list, nrow, ncol):
#初始画布
fig, axs = plt.subplots(nrow, ncol, figsize = (2 * (ncol + 2), 2.5), dpi = 100)
#遍历每个坐标系
for i in range(len(axs)):
#获取坐标系
ax = axs[i]
#获取数据
df = df_list[i]
#画柱状图
ax.bar(df.iloc[:, 0], df.iloc[:, 1], color = 'm', alpha = 0.4, width = 0.5)
#获取RFMP标签对应数值
for x, y in enumerate(df.iloc[:, 1].tolist()):
#标注数据
ax.text(x, y / 2, '%.0f' % y, va = 'bottom', ha = 'center', fontsize = 12)
#设置x轴刻度
ax.set_xticks([0, 1])
#设置y轴刻度
ax.set_yticks(())
#设置小标题
ax.set_title(f'{df.columns[1]}')
#设置大标题
plt.suptitle('两类客户的RFMP均值差异', y = 1.1, fontsize = 14)
#存储图片
plt.savefig('./两类客户LRFMP均值差异.png')
#获取数据
df_list = [ R_avg, F_avg, M_avg, P_avg]
#绘制图形
plot_bar(df_list, 1, 4)
总结:分为两类用户效果确实很明显,但是分析还是有点一刀切,我们发现图中四类效果也
不是很差,后期感兴趣读者可以进行四类用户分类,在这里主要还是给大家一个思维拓展.
全部0条评论
快来发表一下你的评论吧 !