手把手教你利用Python进行客户价值识别,实现差异化管理

怎么辨别客户价值:
哪些是重点客户?
哪些是要保持的客户?
哪些客户会流失?
阅读完本文,用科学决策!

差异化管理、精准营销,提高客户忠诚度、满意度,延长客户高水平消费。

企业除了产品优势,更多的焦点是客户经营。企业没有“人”就变成“止”业,而人不光指企业的人力人才资源,还有企业的“衣食父母”——客户。客户千千万,如何识别出有价值的客户,将客户进行精细科学的划分,从而进行精准营销,对不同价值的客户类别提供个性化服务,制定相应的营销策略,实现利润最大化,是一个企业做大做强必须考虑并着手贯彻的重要举措之一。

今天给大家介绍,怎么通过公司的数据,建立合理的客户价值评估模型,实现客户分类,识别不同客户的价值,从而为客户经营提供策略依据。

目 录

1、背景和目标

2、技术和分析方法

3、读取数据,数据探索分析

4、数据预处理,数据转换

5、模型构建

6、基于模型结果的分析应用

一、背景和目标

背景

1、航空公司业务竞争激烈,企业营销焦点从产品中心转为客户中心;

2、针对不同类型客户,进行精准营销,实现利润最大化;

3、建立合理的客户价值评估模型,进行客户分类,是解决问题的关键。

目标

1、借助航空公司客户数据,对客户进行分类;

2、对不同的客户类别进行特征分析,比较不同类客户的客户价值;

3、对不同价值的客户类别提供个性化服务,制定相应的营销策略。

二、技术和分析方法

涉及技术

A、RFM模型

作用是识别出高价值的客户

客户细分模型是通过三个指标:

  最近消费时间间隔(Recency)

  消费频率(Frequency)

  消费金额(Monetary)

传统RFM模型分析的属性分箱方法,如下图:



B、K-means聚类算法简介

聚类算法:属于无监督机器学习算法,通过计算样本项之间的相似度(也称为样本间的距离),按照数据内部存在的数据特征将数据集划分为多个不同的类别,使类别内的数据比较相似,类别之间的数据相似度比较小。

    闵可夫斯基距离(Minkowski):

    当p为1的时候是曼哈顿距离(Manhattan)

    当p为2的时候是欧式距离(Euclidean)

    当p为无穷大的时候是切比雪夫距离(Chebyshev)
算法思想(步骤):

a、选择初始化的k个类别中心a1,a2,...ak;
b、计算每个样本Xi到类别中心aj的距离,设定最近的类别j
c、将每个类别的中心点aj,替换为隶属该类别的所有样本的均值,作为新的质心。
d、重复上面两步操作,直到达到某个中止条件

中止条件为:组内最小平方误差MSE最小,或者达到迭代次数,或者簇中心点不再变化
图解:

三、读取数据,数据探索分析

1、读取数据

一如既往的,先引入需要的包。

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib as mpl
import sklearn.datasets as ds
import matplotlib.colors
from sklearn.cluster import KMeans
%matplotlib inline

## 设置属性防止中文乱码
mpl.rcParams['font.sans-serif'] = [u'SimHei']
mpl.rcParams['axes.unicode_minus'] = False

利用pandas包,将数据读入Python环境,查看前10条,看长什么样子

data = pd.read_csv('C:\\Users\\Administrator\\Desktop\\air_data.csv', encoding='utf-8') 
data.head(10)

从上面可以看到成功读入数据,数据的样子,读入10行,总共有44列,通过data.shape,可以看到数据有62988行,44列。还需要了解数据。

每个特征(列)的中英文对照如下:

MEMBER_NO会员卡号
FFP_DATE入会时间
FIRST_FLIGHT_DATE第一次飞行日期

GENDER性别

FFP_TIER会员卡级别

WORK_CITY工作地城市

WORK_PROVINCE工作地所在省份

WORK_COUNTRY工作地所在国家

AGE年龄

LOAD_TIME观测窗口的结束时间

FLIGHT_COUNT飞行次数

BP_SUM观测窗口总基本积分

EP_SUM_YR_1第一年精英资格积分

EP_SUM_YR_2第二年精英资格积分

SUM_YR_1第一年总票价

SUM_YR_2第二年总票价

SEG_KM_SUM观测窗口总飞行公里数

WEIGHTED_SEG_KM观测窗口总加权飞行公里数(Σ舱位折扣×航段距离)

LAST_FLIGHT_DATE末次飞行日期

AVG_FLIGHT_COUNT观测窗口季度平均飞行次数

AVG_BP_SUM观测窗口季度平均基本积分累积

BEGIN_TO_FIRST观察窗口内第一次乘机时间至MAX(观察窗口始端,入会时间)时长

LAST_TO_END最后一次乘机时间至观察窗口末端时长

AVG_INTERVAL平均乘机时间间隔

MAX_INTERVAL观察窗口内最大乘机间隔

ADD_POINTS_SUM_YR_1观测窗口中第1年其他积分(合作伙伴、促销、外航转入等)

ADD_POINTS_SUM_YR_2观测窗口中第2年其他积分(合作伙伴、促销、外航转入等)

EXCHANGE_COUNT积分兑换次数

avg_discount平均折扣率

P1Y_Flight_Count第1年乘机次数

L1Y_Flight_Count第2年乘机次数

P1Y_BP_SUM第1年里程积分

L1Y_BP_SUM第2年里程积分

EP_SUM观测窗口总精英积分

ADD_Point_SUM观测窗口中其他积分(合作伙伴、促销、外航转入等)

Eli_Add_Point_Sum非乘机积分总和

L1Y_ELi_Add_Points第2年非乘机积分总和

Points_Sum总累计积分

L1Y_Points_Sum第2年观测窗口总累计积分

Ration_L1Y_Flight_Count第2年的乘机次数比率

Ration_P1Y_Flight_Count第1年的乘机次数比率

Ration_P1Y_BPS第1年里程积分占最近两年积分比例

Ration_L1Y_BPS第2年里程积分占最近两年积分比例

Point_NotFlight非乘机的积分变动次数

2、数据探索分析

查看每个特征的数据类型和数量:

data.info()

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 62988 entries, 0 to 62987
Data columns (total 44 columns):
MEMBER_NO                  62988 non-null int64
FFP_DATE                   62988 non-null object
FIRST_FLIGHT_DATE          62988 non-null object
GENDER                     62985 non-null object
FFP_TIER                   62988 non-null int64
WORK_CITY                  60719 non-null object
WORK_PROVINCE              59740 non-null object
WORK_COUNTRY               62962 non-null object
AGE                        62568 non-null float64
LOAD_TIME                  62988 non-null object
FLIGHT_COUNT               62988 non-null int64
BP_SUM                     62988 non-null int64
EP_SUM_YR_1                62988 non-null int64
EP_SUM_YR_2                62988 non-null int64
SUM_YR_1                   62437 non-null float64
SUM_YR_2                   62850 non-null float64
SEG_KM_SUM                 62988 non-null int64
WEIGHTED_SEG_KM            62988 non-null float64
LAST_FLIGHT_DATE           62988 non-null object
AVG_FLIGHT_COUNT           62988 non-null float64
AVG_BP_SUM                 62988 non-null float64
BEGIN_TO_FIRST             62988 non-null int64
LAST_TO_END                62988 non-null int64
AVG_INTERVAL               62988 non-null float64
MAX_INTERVAL               62988 non-null int64
ADD_POINTS_SUM_YR_1        62988 non-null int64
ADD_POINTS_SUM_YR_2        62988 non-null int64
EXCHANGE_COUNT             62988 non-null int64
avg_discount               62988 non-null float64
P1Y_Flight_Count           62988 non-null int64
L1Y_Flight_Count           62988 non-null int64
P1Y_BP_SUM                 62988 non-null int64
L1Y_BP_SUM                 62988 non-null int64
EP_SUM                     62988 non-null int64
ADD_Point_SUM              62988 non-null int64
Eli_Add_Point_Sum          62988 non-null int64
L1Y_ELi_Add_Points         62988 non-null int64
Points_Sum                 62988 non-null int64
L1Y_Points_Sum             62988 non-null int64
Ration_L1Y_Flight_Count    62988 non-null float64
Ration_P1Y_Flight_Count    62988 non-null float64
Ration_P1Y_BPS             62988 non-null float64
Ration_L1Y_BPS             62988 non-null float64
Point_NotFlight            62988 non-null int64
dtypes: float64(12), int64(24), object(8)
memory usage: 21.1+ MB

查看每个特征的总条数以及五值分布:平均值、最大值、最小值、标准差、四分位数。

data.describe().T
查看缺失值情况:
data.isnull().sum().sort_values(ascending=False)

WORK_PROVINCE              3248
WORK_CITY                  2269
SUM_YR_1                    551
AGE                         420
SUM_YR_2                    138
WORK_COUNTRY                 26
GENDER                        3
Point_NotFlight               0
EP_SUM_YR_2                   0
AVG_FLIGHT_COUNT              0
LAST_FLIGHT_DATE              0
WEIGHTED_SEG_KM     

三、数据预处理、数据转换

1、数据预处理

其实根据RFM模型的要求,我们不去过多关注其他特征,只需要选取和最近消费时间间隔(Recency)、 消费频率(Frequency)、消费金额(Monetary)相关的特征即可。

数据清洗,丢弃票价为空的记录:

保留总票价非空值

data=data[data['SUM_YR_1'].notnull() & data['SUM_YR_2'].notnull()]  
# 保留票价非零值或平均折扣率为零的值
term_1 = data['SUM_YR_1'] != 0
term_2 = data['SUM_YR_2'] != 0
term_3 = data['avg_discount'] == 0
data = data[term_1 | term_2 | term_3] 
# 导出数清洗后的数据
result = '../客户价值识别/data_cleaned.csv'  
data.to_csv(result, sep=",", encoding='utf-8')
2、特征提取、数据转换

原始数据中属性太多,根据航空公司客户价值LRFMC模型,选择与模型相关的六个属性,删除不相关、弱相关或冗余属性。
根据RFM的需要,我们来选择需要的特征:

R是最近消费时间间隔(Recency),可以用LAST_TO_END(最后一次乘机时间至观察窗口末端时长);

F是消费频率(Frequency
FLIGHT_COUNT(观测窗口内的飞行次数)

M是消费金额(Monetary),消费金额航空票价收到距离和舱位等级多种因素的影响,
舱位因素=舱位所对应的折扣系数AVG_DISCOUNT的平均值
距离因素=一定时间内累积的飞行里程

SEG_KM_SUM航空公司的会员系统,用户的入会时间长短能在一定程度上影响客户价值,所以增加指标入会时间长度,即客户关系长度:会员入会时间距观测窗口结束的月数=观测窗口的结束时间-入会时间(单位:月),即LOAD_TIME-FFP_DATE。

这样,我们需要5个指标LRFMC:

L=LOAD_TIME-FFP_DATE(会员入会时间距观测窗口结束的月数=观测窗口的结束时间-入会时间(单位:月))

R=LAST_TO_END(客户最近一次乘坐公司距观测窗口结束的月数=最后一次。。。)

F=FLIGHT_COUNT(观测窗口内的飞行次数)

M=SEG_KM_SUM(观测窗口的总飞行里程)

C=AVG_DISCOUNT(平均折扣率)

# 数据筛选
# 选出模型需要的特征
df=data[["FFP_DATE","LOAD_TIME","LAST_TO_END","FLIGHT_COUNT","SEG_KM_SUM","avg_discount"]]
df.head()
# 构造LRFMC
def STRCTURE_LRFMC(data_set):
#     data_set=data_set[["FFP_DATE","LOAD_TIME","LAST_TO_END","FLIGHT_COUNT","SEG_KM_SUM","avg_discount"]]
    dt_FFP_DATE=pd.to_datetime(data_set["FFP_DATE"])
    dt_LOAD_TIME=pd.to_datetime(data_set["LOAD_TIME"])
    FFP_LOAD_DATE=dt_LOAD_TIME-dt_FFP_DATE
    df2=data_set.copy()
    df2["L"]=FFP_LOAD_DATE.map(lambda x:x/np.timedelta64(30*24*60,"m"))
    df2["R"]=data_set["LAST_TO_END"]
    df2["F"]=data_set["FLIGHT_COUNT"]
    df2["M"]=data_set["SEG_KM_SUM"]
    df2["C"]=data_set["avg_discount"]
    df3=df2[["L","R","F","M","C"]]
    return df3

df3=STRCTURE_LRFMC(df)
df3.head()

经过如上处理的数据:

5个指标的取值范围差异较大,需进行标准化处理,消除数量级的影响;

# 数据标准化
def zscore_data(data):
    data2=(data-data.mean(axis=0))/data.std(axis=0)
    data2.columns=["Z"+i for i in data.columns]
    return data2

df4=zscore_data(df3)
df4.head()

经过上述的处理,我们就可以用上面的数据进行建立模型了。

四、模型构建

1、K-means聚类

采用K-Means算法对客户数据进行客户分群,聚成五类(需结合业务的理解与分析来确定客户的类别数量)

k=5
# 调用k-means算法
model = KMeans(n_clusters=k, init='random',random_state=28,n_jobs=4)  
# 输入聚类类别数目,n_jobs为并行数
#n_clusters就是K值,也是聚类值
#init初始化方法,可以是kmeans++,随机,或者自定义的ndarray
model.fit(df4)  # 训练

# 训练结果如下:
KMeans(algorithm='auto', copy_x=True, init='k-means++', max_iter=300,
       n_clusters=5, n_init=10, n_jobs=1, precompute_distances='auto',
       random_state=None, tol=0.0001, verbose=0)

K-Means算法的API以及实例可以参考sklearn官网


#  model.cluster_centers_ 聚类中心
#  labels = model.labels_ 每个样本对应的簇类别标签
r1 = pd.Series(model.labels_).value_counts()  # 统计各个类别的数目
r2 = pd.DataFrame(model.cluster_centers_)  # 找出聚类中心
r = pd.concat([r2, r1], axis=1)   # 得到聚类中心对应的类别下的数目
r.columns = list(df4.columns) + [u'类别数目']  # 重命名表头
r.to_excel('../客户价值识别/KMeansNum.xls')

r3 = pd.concat([df4, pd.Series(model.labels_, index=df4.index)], axis=1)   # 详细输出每个样本对应的类别
r3.columns = list(df4.columns) + [u'聚类类别']  # 重命名表头
r3.to_excel('../客户价值识别/KMeans.xls')

r为每个类别的数目,r3为每个样本聚类的类别,r和r3分别如下:


聚为几类合适?

除了业务,我们还可以通过聚类的性能进行评估:

聚类类别数和组内误方差的变化,出现“肘点”对应的类别数可以认为最优。

distortions=[]
for i in range(1,10):
    km=KMeans(n_clusters=i,init='random',random_state=28)
    #n_clusters就是K值,也是聚类值
    #init初始化方法,可以是kmeans++,随机,或者自定义的ndarray
    km.fit(df4)
    distortions.append(km.inertia_)

plt.plot(range(1,10),distortions,marker="o")
plt.xlabel("簇数量")
plt.ylabel("簇内误方差(SSE)")
plt.show()

上图可知,聚为5类,还是比较理想的。

2、图片展示

通过K-Means聚类模型的构建和训练,以及将每个观测(每个人)划分为1-5中的其中一类,并将结果保存在KMeans.xlsx文件中,但是不直观,需要我们可视化形象直观输出我们的结果,选择雷达图展示。

max = r2.values.max()
min = r2.values.min()
# 绘图
fig=plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, polar=True)
center_num = r.values
feature = ["客户关系长度","消费的时间间隔","总消费次数","总消费金额","平均折扣率"]
N =len(feature)
for i, v in enumerate(center_num):
    # 设置雷达图的角度,用于平分切开一个圆面
    angles=np.linspace(0, 2*np.pi, N, endpoint=False)
    # 为了使雷达图一圈封闭起来,需要下面的步骤
    center = np.concatenate((v[:-1],[v[0]]))
    angles=np.concatenate((angles,[angles[0]]))
    # 绘制折线图
    ax.plot(angles, center, 'o-', linewidth=2, label = "第%d类客群:%d人"% (i+1,v[-1]))
    # 填充颜色
    ax.fill(angles, center, alpha=0.25)
    # 添加每个特征的标签
    ax.set_thetagrids(angles * 180/np.pi, feature, fontsize=15)
    # 设置雷达图的范围
    ax.set_ylim(min-0.1, max+0.1)
    # 添加标题
    plt.title('客户群特征分析图', fontsize=20)
    # 添加网格线
    ax.grid(True)
    # 设置图例
    plt.legend(loc='upper right', bbox_to_anchor=(1.3,1.0),ncol=1,fancybox=True,shadow=True)

# 显示图形
plt.show()
plt.savefig("客户群特征分析图.jpg",dpi=200)

五、基于模型结果的分析应用

客户价值分析

针对“客户群特征分析图”所示的聚类结果,结合业务进行特征分析。我们重点关注的是L(户关系长度)、F(消费频率)、M(飞行里程)三个指标:

客户群1:在C属性上最大,可定义为重要挽留客户;

客户群2:在R属性上最大,在F、M属性上最小,可定义为低价值客户;

客户群3:在F、M属性上最大,在R属性上最小,可定义为重要保持客户;

客户群4:在L、C属性上最小,可定义为一般客户;

客户群5:在L属性上最大,可定义为重要发展客户;

客户群价值排名

重要保持客户:C(平均折扣率较高、仓位等级较高)、F(乘坐次数)、M(里程)较高,R(最近乘坐航班)低。应将资源优先投放到这类客户身上,进行差异化管理,提高客户的忠诚度和满意度。

重要发展客户:C较高,R、F、M较低。这类客户入会时长(L)短、当前价值低、发展潜力大,应促使客户增加在本公司和合作伙伴处的消费。

重要挽留客户:C、F 或 M 较高,R较高 或 L变小,客户价值变化的不确定性高。应掌握客户最新信息、维持与客户的互动。

一般和低价值客户:C、F、M、L低、R较高。这类客户可能在打折促销时才会选择消费。


应用

差异化管理、精准营销,提高客户忠诚度、满意度,延长客户高水平消费。

1)会员升级与保级(积分削减等)

在会员升级或保级评价的时间点前,对接近但尚未达到要求的较高消费客户进行提醒或促销活动,提高客户满意度。

2)首次兑换

对接近但尚未达到标准的会员进行提醒或促销活动,提高客户满意度。

3)交叉销售

通过与非航空类企业的合作,使客户在其他消费过程中获得本公司积分,增强与公司联系,提高忠诚度

原文在这里:
https://mp.weixin.qq.com/s/Tn7nwduS8aMik9bjKxeQvQ

还有好多好多干货


如果你对数据分析数据挖掘感兴趣

在上面原文中关注,
(或者搜索微信公众号ywq885889)

一起学习交流哇!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • 1.背景与挖掘目标 1.1背景 航空公司业务竞争激烈,从产品中心转化为客户中心。 针对不同类型客户,进行精准营销,...
    peiyang阅读 3,073评论 0 3
  • 机器学习术语表 本术语表中列出了一般的机器学习术语和 TensorFlow 专用术语的定义。 A A/B 测试 (...
    yalesaleng阅读 1,952评论 0 11
  • 今天是腊月初八日,过了腊八就是年了。 腊月初八日,亦是佛祖释迦牟尼成道日,每年的今天,许多寺院都有祈福庆祝活动,也...
    湘女在姚阅读 228评论 2 2
  • 时光匆匆,又是一个周六日,又该做周检视的时间了,感觉做周检视成了我的负担。因为每次都得求人帮我在YY上代发言,求的...
    春暖花开6091阅读 137评论 0 0
  • 好几天没打卡了~其实每天都有动笔~ 只是效率太低~被风景虐的失去信心~ 没有微博转存的图真是好灰啊… 不多说了继续...
    敬文水彩阅读 433评论 4 16