某航空公司的客户价值分析

某航空公司的客户价值分析

根据2/8定律,80%的收益来自于20%的高价值客户,客户价值分析的目的是为了对客户进行分群,然后采取精细化和针对性的经营,将有限的资源运营在高价值客户或者有机会成为高价值客户的客户。
数据集为某航空公司的若干客户信息,数据集包含用户相关信息、用户消费信息以及折扣积分等相关信息,利用这些信息对客户进行分群,并对不同价值的客户进行分析,提出精细化和针对性的运营策略。
原数据链接:https://pan.baidu.com/s/1HHbsYw8DYcNg9RYUTJQNdA 提取码:3hpm

#-*- coding:utf8 -*-
import pandas as pd
import numpy as np
from sklearn.cluster import KMeans
from sklearn import preprocessing
import matplotlib.pyplot as plt

加载相关包

datafile='air_data.csv'
data=pd.read_csv(datafile,encoding='utf-8')
print(data.info())
print('+'*30)
print(data.describe())
print('+'*30)
print(data.head())
print('+'*30)
<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
None
++++++++++++++++++++++++++++++
          MEMBER_NO      FFP_TIER           AGE  FLIGHT_COUNT         BP_SUM  \
count  62988.000000  62988.000000  62568.000000  62988.000000   62988.000000   
mean   31494.500000      4.102162     42.476346     11.839414   10925.081254   
std    18183.213715      0.373856      9.885915     14.049471   16339.486151   
min        1.000000      4.000000      6.000000      2.000000       0.000000   
25%    15747.750000      4.000000     35.000000      3.000000    2518.000000   
50%    31494.500000      4.000000     41.000000      7.000000    5700.000000   
75%    47241.250000      4.000000     48.000000     15.000000   12831.000000   
max    62988.000000      6.000000    110.000000    213.000000  505308.000000   

       EP_SUM_YR_1   EP_SUM_YR_2       SUM_YR_1       SUM_YR_2     SEG_KM_SUM  \
count      62988.0  62988.000000   62437.000000   62850.000000   62988.000000   
mean           0.0    265.689623    5355.376064    5604.026014   17123.878691   
std            0.0   1645.702854    8109.450147    8703.364247   20960.844623   
min            0.0      0.000000       0.000000       0.000000     368.000000   
25%            0.0      0.000000    1003.000000     780.000000    4747.000000   
50%            0.0      0.000000    2800.000000    2773.000000    9994.000000   
75%            0.0      0.000000    6574.000000    6845.750000   21271.250000   
max            0.0  74460.000000  239560.000000  234188.000000  580717.000000   

            ...         ADD_Point_SUM  Eli_Add_Point_Sum  L1Y_ELi_Add_Points  \
count       ...          62988.000000       62988.000000        62988.000000   
mean        ...           1355.006223        1620.695847         1080.378882   
std         ...           7868.477000        8294.398955         5639.857254   
min         ...              0.000000           0.000000            0.000000   
25%         ...              0.000000           0.000000            0.000000   
50%         ...              0.000000           0.000000            0.000000   
75%         ...              0.000000         345.000000            0.000000   
max         ...         984938.000000      984938.000000       728282.000000   

        Points_Sum  L1Y_Points_Sum  Ration_L1Y_Flight_Count  \
count   62988.0000    62988.000000             62988.000000   
mean    12545.7771     6638.739585                 0.486419   
std     20507.8167    12601.819863                 0.319105   
min         0.0000        0.000000                 0.000000   
25%      2775.0000      700.000000                 0.250000   
50%      6328.5000     2860.500000                 0.500000   
75%     14302.5000     7500.000000                 0.711111   
max    985572.0000   728282.000000                 1.000000   

       Ration_P1Y_Flight_Count  Ration_P1Y_BPS  Ration_L1Y_BPS  \
count             62988.000000    62988.000000    62988.000000   
mean                  0.513581        0.522293        0.468422   
std                   0.319105        0.339632        0.338956   
min                   0.000000        0.000000        0.000000   
25%                   0.288889        0.258150        0.167954   
50%                   0.500000        0.514252        0.476747   
75%                   0.750000        0.815091        0.728375   
max                   1.000000        0.999989        0.999993   

       Point_NotFlight  
count     62988.000000  
mean          2.728155  
std           7.364164  
min           0.000000  
25%           0.000000  
50%           0.000000  
75%           1.000000  
max         140.000000  

[8 rows x 36 columns]
++++++++++++++++++++++++++++++
   MEMBER_NO    FFP_DATE FIRST_FLIGHT_DATE GENDER  FFP_TIER    WORK_CITY  \
0      54993  2006/11/02        2008/12/24      男         6            .   
1      28065  2007/02/19        2007/08/03      男         6          NaN   
2      55106  2007/02/01        2007/08/30      男         6            .   
3      21189  2008/08/22        2008/08/23      男         5  Los Angeles   
4      39546  2009/04/10        2009/04/15      男         6           贵阳   

  WORK_PROVINCE WORK_COUNTRY   AGE   LOAD_TIME       ...         \
0            北京           CN  31.0  2014/03/31       ...          
1            北京           CN  42.0  2014/03/31       ...          
2            北京           CN  40.0  2014/03/31       ...          
3            CA           US  64.0  2014/03/31       ...          
4            贵州           CN  48.0  2014/03/31       ...          

   ADD_Point_SUM  Eli_Add_Point_Sum  L1Y_ELi_Add_Points  Points_Sum  \
0          39992             114452              111100      619760   
1          12000              53288               53288      415768   
2          15491              55202               51711      406361   
3              0              34890               34890      372204   
4          22704              64969               64969      338813   

   L1Y_Points_Sum  Ration_L1Y_Flight_Count  Ration_P1Y_Flight_Count  \
0          370211                 0.509524                 0.490476   
1          238410                 0.514286                 0.485714   
2          233798                 0.518519                 0.481481   
3          186100                 0.434783                 0.565217   
4          210365                 0.532895                 0.467105   

   Ration_P1Y_BPS Ration_L1Y_BPS  Point_NotFlight  
0        0.487221       0.512777               50  
1        0.489289       0.510708               33  
2        0.481467       0.518530               26  
3        0.551722       0.448275               12  
4        0.469054       0.530943               39  

[5 rows x 44 columns]
++++++++++++++++++++++++++++++

加载数据,观察数据,可发现数据包含很多类型,有类别属性、数值属性、时间属性,有些属性是唯一识别属性,各属性观测值的范围也不相同,差别很大,有些属性还存在缺失值。

explore=data.describe().T
explore['null']=len(data)-explore['count']
explore=explore[['null','max','min']]
explore.rename(columns={i:j for i,j in zip(['null','max','min'],[u'空值数',u'最大值',u'最小值'])},inplace=True)
print(explore)
                           空值数            最大值     最小值
MEMBER_NO                  0.0   62988.000000    1.00
FFP_TIER                   0.0       6.000000    4.00
AGE                      420.0     110.000000    6.00
FLIGHT_COUNT               0.0     213.000000    2.00
BP_SUM                     0.0  505308.000000    0.00
EP_SUM_YR_1                0.0       0.000000    0.00
EP_SUM_YR_2                0.0   74460.000000    0.00
SUM_YR_1                 551.0  239560.000000    0.00
SUM_YR_2                 138.0  234188.000000    0.00
SEG_KM_SUM                 0.0  580717.000000  368.00
WEIGHTED_SEG_KM            0.0  558440.140000    0.00
AVG_FLIGHT_COUNT           0.0      26.625000    0.25
AVG_BP_SUM                 0.0   63163.500000    0.00
BEGIN_TO_FIRST             0.0     729.000000    0.00
LAST_TO_END                0.0     731.000000    1.00
AVG_INTERVAL               0.0     728.000000    0.00
MAX_INTERVAL               0.0     728.000000    0.00
ADD_POINTS_SUM_YR_1        0.0  600000.000000    0.00
ADD_POINTS_SUM_YR_2        0.0  728282.000000    0.00
EXCHANGE_COUNT             0.0      46.000000    0.00
avg_discount               0.0       1.500000    0.00
P1Y_Flight_Count           0.0     118.000000    0.00
L1Y_Flight_Count           0.0     111.000000    0.00
P1Y_BP_SUM                 0.0  246197.000000    0.00
L1Y_BP_SUM                 0.0  259111.000000    0.00
EP_SUM                     0.0   74460.000000    0.00
ADD_Point_SUM              0.0  984938.000000    0.00
Eli_Add_Point_Sum          0.0  984938.000000    0.00
L1Y_ELi_Add_Points         0.0  728282.000000    0.00
Points_Sum                 0.0  985572.000000    0.00
L1Y_Points_Sum             0.0  728282.000000    0.00
Ration_L1Y_Flight_Count    0.0       1.000000    0.00
Ration_P1Y_Flight_Count    0.0       1.000000    0.00
Ration_P1Y_BPS             0.0       0.999989    0.00
Ration_L1Y_BPS             0.0       0.999993    0.00
Point_NotFlight            0.0     140.000000    0.00

统计所有属性观测值的空值数、最大值和最小值,可以更详细的观测各个属性,可发现共有三个属性存在缺失值,这些缺失值个数占总体观测值比率很小。

data=data[data['SUM_YR_1'].notnull()&data['SUM_YR_2'].notnull()]
data['SUM_YR']=data['SUM_YR_1']+data['SUM_YR_2']
index1=data['SUM_YR'] !=0
index2=(data['SEG_KM_SUM']==0)&(data['avg_discount']==0)
data=data[index1|index2]

数据清理:票价为空或者票价为0&折扣率为0&总飞行里程数大于0的记录都是一些异常记录,会对后面的分析产生不利影响,这里需要删除。

features=['LOAD_TIME','FFP_DATE','LAST_TO_END','FLIGHT_COUNT','SEG_KM_SUM','avg_discount']
data_choiced=data[features]
print(data_choiced.head())
    LOAD_TIME    FFP_DATE  LAST_TO_END  FLIGHT_COUNT  SEG_KM_SUM  avg_discount
0  2014/03/31  2006/11/02            1           210      580717      0.961639
1  2014/03/31  2007/02/19            7           140      293678      1.252314
2  2014/03/31  2007/02/01           11           135      283712      1.254676
3  2014/03/31  2008/08/22           97            23      281336      1.090870
4  2014/03/31  2009/04/10            5           152      309928      0.970658

这一步是特征选择,根据RFM模型和航空公司用户指标的特殊性,这里选择用户飞行总时间、最近一次飞行距观测窗口结束的时间、总飞行次数、总飞行里程数、平均折扣率这些属性作为指标进行后面的数据挖掘和分析,这里因为已有的属性作为指标已经足够进行后面的分析,这里就不再构建指标了。

train_x=pd.DataFrame()
train_x['总时间']=(pd.to_datetime(data_choiced.iloc[:,0])-pd.to_datetime(data_choiced.iloc[:,1]))/np.timedelta64(1,'D')
train_x['最近一次']=data_choiced.iloc[:,2]
train_x['次数']=data_choiced.iloc[:,3]
train_x['里程数']=data_choiced.iloc[:,4]
train_x['折扣率']=data_choiced.iloc[:,5]
print(train_x.head())
def train_x_show(raw_data):
    fig=plt.figure(figsize=(25,25))
    for i in range(5):
        ax=fig.add_subplot(3,2,i+1)
        ax.hist(raw_data.iloc[:,i],bins=100)
        ax.set_xlabel(raw_data.columns[i],fontsize=30)
        ax.set_ylabel(u'频率',fontsize=30)
        plt.xticks(fontsize=30)
        plt.yticks(fontsize=30)
    ax=fig.add_subplot(3,2,6)
    ax.hist(raw_data['里程数']/raw_data['次数'],bins=100)
    ax.set_xlabel('平均里程数',fontsize=30)
    ax.set_ylabel(u'频率',fontsize=30)    
    plt.xticks(fontsize=30)
    plt.yticks(fontsize=30)
    plt.rcParams['font.sans-serif']=['Simhei']
    plt.show()
train_x_show(train_x)
      总时间  最近一次   次数     里程数       折扣率
0  2706.0     1  210  580717  0.961639
1  2597.0     7  140  293678  1.252314
2  2615.0    11  135  283712  1.254676
3  2047.0    97   23  281336  1.090870
4  1816.0     5  152  309928  0.970658

png

对数据进行处理,这里可以看出大部分客户的飞行次数、飞行里程数都是比较小的,这也符合了2/8定律。

std_scaler=preprocessing.StandardScaler()
train_x=std_scaler.fit_transform(train_x)
print(train_x)
plt.hist(train_x)
plt.show()
[[ 1.43571897 -0.94495516 14.03412875 26.76136996  1.29555058]
 [ 1.30716214 -0.9119018   9.07328567 13.1269701   2.86819902]
 [ 1.32839171 -0.88986623  8.71893974 12.65358345  2.88097321]
 ...
 [-0.14942206 -0.73561725 -0.70666211 -0.77233818 -2.68990622]
 [-1.20618274  1.6056619  -0.70666211 -0.77984321 -2.55464809]
 [-0.47965977  0.60304353 -0.70666211 -0.78668323 -2.39233833]]

png

对数据进行标准化处理,这里选择标准差标准化。

def model_test(data_,start=2,stop=10):
    SSE_table=pd.DataFrame()
    numb,SSE=[],[]
    for i in range(start,stop):
        kmeans_model=KMeans(n_clusters=i,n_jobs=4)
        kmeans_model.fit(data_)
        predict_y=kmeans_model.predict(data_)
        predict_vector=[]
        for j in predict_y:
            predict_vector.append(kmeans_model.cluster_centers_[j])
        sse=np.sum(np.power(data_-predict_vector,2))
        numb.append(i)
        SSE.append(sse)
    SSE_table['簇数']=numb
    SSE_table['SSE']=SSE
    return SSE_table
SSE_table=model_test(train_x,2,10)

这里用K-Means进行聚类分析,一般客户分群k值选取为4,5个左右,不易过多,这里采用计算SSE的方法,尝试找到最好的K数值。

print(SSE_table)
SSE_table.plot(x='簇数',y='SSE')
   簇数            SSE
0   2  229348.669720
1   3  184346.806281
2   4  151013.114090
3   5  133362.301139
4   6  118069.047171
5   7  107635.877614
6   8  100707.980570
7   9   94069.592981





<matplotlib.axes._subplots.AxesSubplot at 0x1b5b16a3a58>

在这里插入图片描述

可以看出当簇数为4时出现了拐点,由于k值选择不易过大,下面选k为4和5进行分析。

kmeans_model=KMeans(n_clusters=4,n_jobs=4)
kmeans_model.fit(train_x)
predict_y=kmeans_model.predict(train_x)

kmeans_model2=KMeans(n_clusters=5,n_jobs=4)
kmeans_model2.fit(train_x)
predict_y2=kmeans_model2.predict(train_x)

训练模型,得出各用户所属群的类别。

labels=np.array([u'总时间',u'最近一次',u'次数',u'里程数',u'折扣率'])
def spide(x,n,num):
    fig=plt.figure(figsize=(5,5))
    ax=fig.add_subplot(1,1,1,polar=True)
    for i in range(n):
        angles=np.linspace(0,2*np.pi,len(labels),endpoint=False)
        stats=x.iloc[i,:]
        stats=np.concatenate((stats,[stats[0]]))
        angles=np.concatenate((angles,[angles[0]]))
        ax.plot(angles,stats,'o-',linewidth=2, label = '类%d:%d'%(i,num[i]))
        ax.fill(angles,stats,alpha=0.25)
        ax.set_thetagrids(angles * 180/np.pi,labels, fontsize=15)
        ax.set_xlabel('%d类特征分析图'%n, fontsize=20)
        plt.legend(loc='upper right', bbox_to_anchor=(1.4,1.0),ncol=1,fancybox=True,shadow=True)
    plt.show()
r2=pd.DataFrame(kmeans_model.cluster_centers_)
num2=pd.Series(kmeans_model.labels_).value_counts()
r2_new=pd.concat([r2,num2],axis=1)
r2_new.columns=list(labels)+[u'类别数量']
print(r2_new)
print('+'*30)
r3=pd.DataFrame(kmeans_model2.cluster_centers_)
num3=pd.Series(kmeans_model2.labels_).value_counts()
r3_new=pd.concat([r3,num3],axis=1)
r3_new.columns=list(labels)+[u'类别数量']
print(r3_new)
print('+'*30)
spide(r2,4,num2)
spide(r3,5,num3)
        总时间      最近一次        次数       里程数       折扣率   类别数量
0 -0.696202 -0.408644 -0.169954 -0.170097 -0.133801  26277
1 -0.311455  1.659763 -0.572081 -0.535889 -0.020545  12925
2  1.138629 -0.364145 -0.098711 -0.107696  0.095677  17258
3  0.478723 -0.795991  2.430013  2.374625  0.381567   5584
++++++++++++++++++++++++++++++
        总时间      最近一次        次数       里程数       折扣率   类别数量
0 -0.700212 -0.414892 -0.161144 -0.160959 -0.255134  24659
1  0.483332 -0.799390  2.483222  2.424743  0.308633   5336
2 -0.313681  1.686272 -0.574021 -0.536825 -0.173328  12125
3  0.051843 -0.002668 -0.226805 -0.231256  2.191365   4184
4  1.160676 -0.377224 -0.086919 -0.094845 -0.155906  15740
++++++++++++++++++++++++++++++

在这里插入图片描述

在这里插入图片描述

这里可以看出,
当k值取4时,可以看出各群的特征还是比较明显的,类2次数和里程数都较大,数量较少,显然是高价值用户群,类1显然是低价值用户群,数目也较大,类3是老客户,可以看出这一部分客户正在流失,需要采取手段降低流失率,类0是飞行里程和次数都很少的顾客,且最近一次乘机时间距观察窗口末也较长,为低价值客户。
当k值取5时,可以看出它包括k取4值的用户群而且它又多出来一个群类3,这个群可以看做是由类0分出来的群,可以发现这个群享受的折扣率较高,是个挺有意思的发现,有些用户可能在有折扣的时候才会偶尔消费。
综上,k值取5比较合理。其中:
类1里程数和乘机次数都较高,为重要保留客户,应该把最主要的精力和资源放在和他们保持关系上。
类4为总乘机时间长,但是观测窗口内的里程数和乘机次数都较少,可能是正在流失的老客户,可以对他们进行一些调查,找出流失的原因,这些原因可能和航空公司某些的不足和失误有关,都蕴含着巨大价值,对这些客户采取一些手段,增加他们的生命周期。
类0是可能是最近有过乘机的新客户,而且这一人数很大,是重要的发展客户,也是运营团队未来要加大努力的方向。
类3也可能是最近有过乘机的新客户,但是他们的折扣率都较大,可以考虑在淡季时增加对其的折扣促进其消费。
类2是低价值客户。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值