0%

Python数据科学_13_案例:航空公司客户价值分析【聚类案例】

背景和目标

行业内竞争

民航的竞争除了三大航空公司之间的竞争之外,还将加入新崛起的各类小型航空公司、民营航空公司,甚至国外航空巨头。航空产品生产过剩,产品同质化特征愈加明显,于是航空公司从价格、服务间的竞争逐渐转向对客户的竞争。

行业外竞争

随着高铁、动车等铁路运输的兴建,航空公司受到巨大冲击。

目标

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

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

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

1
import pandas as pd

数据集下载

读取数据

1
data = pd.read_csv('air_data.csv', encoding='gb18030')
1
data.head()
MEMBER_NO FFP_DATE FIRST_FLIGHT_DATE GENDER FFP_TIER WORK_CITY WORK_PROVINCE WORK_COUNTRY AGE LOAD_TIME ... ADD_Point_SUM Eli_Add_Point_Sum L1Y_ELi_Add_Points Points_Sum L1Y_Points_Sum Ration_L1Y_Flight_Count Ration_P1Y_Flight_Count Ration_P1Y_BPS Ration_L1Y_BPS Point_NotFlight
0 54993 2006/11/2 2008/12/24 6 . 北京 CN 31.0 2014/3/31 ... 39992 114452 111100 619760 370211 0.509524 0.490476 0.487221 0.512777 50
1 28065 2007/2/19 2007/8/3 6 NaN 北京 CN 42.0 2014/3/31 ... 12000 53288 53288 415768 238410 0.514286 0.485714 0.489289 0.510708 33
2 55106 2007/2/1 2007/8/30 6 . 北京 CN 40.0 2014/3/31 ... 15491 55202 51711 406361 233798 0.518519 0.481481 0.481467 0.518530 26
3 21189 2008/8/22 2008/8/23 5 Los Angeles CA US 64.0 2014/3/31 ... 0 34890 34890 372204 186100 0.434783 0.565217 0.551722 0.448275 12
4 39546 2009/4/10 2009/4/15 6 贵阳 贵州 CN 48.0 2014/3/31 ... 22704 64969 64969 338813 210365 0.532895 0.467105 0.469054 0.530943 39

5 rows × 44 columns

数据探索

查看数据的摘要信息

1
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 62988 entries, 0 to 62987
Data columns (total 44 columns):
 #   Column                   Non-Null Count  Dtype  
---  ------                   --------------  -----  
 0   MEMBER_NO                62988 non-null  int64  
 1   FFP_DATE                 62988 non-null  object 
 2   FIRST_FLIGHT_DATE        62988 non-null  object 
 3   GENDER                   62985 non-null  object 
 4   FFP_TIER                 62988 non-null  int64  
 5   WORK_CITY                60719 non-null  object 
 6   WORK_PROVINCE            59740 non-null  object 
 7   WORK_COUNTRY             62962 non-null  object 
 8   AGE                      62568 non-null  float64
 9   LOAD_TIME                62988 non-null  object 
 10  FLIGHT_COUNT             62988 non-null  int64  
 11  BP_SUM                   62988 non-null  int64  
 12  EP_SUM_YR_1              62988 non-null  int64  
 13  EP_SUM_YR_2              62988 non-null  int64  
 14  SUM_YR_1                 62437 non-null  float64
 15  SUM_YR_2                 62850 non-null  float64
 16  SEG_KM_SUM               62988 non-null  int64  
 17  WEIGHTED_SEG_KM          62988 non-null  float64
 18  LAST_FLIGHT_DATE         62988 non-null  object 
 19  AVG_FLIGHT_COUNT         62988 non-null  float64
 20  AVG_BP_SUM               62988 non-null  float64
 21  BEGIN_TO_FIRST           62988 non-null  int64  
 22  LAST_TO_END              62988 non-null  int64  
 23  AVG_INTERVAL             62988 non-null  float64
 24  MAX_INTERVAL             62988 non-null  int64  
 25  ADD_POINTS_SUM_YR_1      62988 non-null  int64  
 26  ADD_POINTS_SUM_YR_2      62988 non-null  int64  
 27  EXCHANGE_COUNT           62988 non-null  int64  
 28  avg_discount             62988 non-null  float64
 29  P1Y_Flight_Count         62988 non-null  int64  
 30  L1Y_Flight_Count         62988 non-null  int64  
 31  P1Y_BP_SUM               62988 non-null  int64  
 32  L1Y_BP_SUM               62988 non-null  int64  
 33  EP_SUM                   62988 non-null  int64  
 34  ADD_Point_SUM            62988 non-null  int64  
 35  Eli_Add_Point_Sum        62988 non-null  int64  
 36  L1Y_ELi_Add_Points       62988 non-null  int64  
 37  Points_Sum               62988 non-null  int64  
 38  L1Y_Points_Sum           62988 non-null  int64  
 39  Ration_L1Y_Flight_Count  62988 non-null  float64
 40  Ration_P1Y_Flight_Count  62988 non-null  float64
 41  Ration_P1Y_BPS           62988 non-null  float64
 42  Ration_L1Y_BPS           62988 non-null  float64
 43  Point_NotFlight          62988 non-null  int64  
dtypes: float64(12), int64(24), object(8)
memory usage: 21.1+ MB
  1. 有大量的列存在缺失值
  2. 存在8列object数据

查看数据集的重复情况

1
data.shape
(62988, 44)
1
data.drop_duplicates().shape
(62988, 44)

说明数据集不存在重复值

查看数据集具体的缺失值情况

1
data.isna().sum()
MEMBER_NO                     0
FFP_DATE                      0
FIRST_FLIGHT_DATE             0
GENDER                        3
FFP_TIER                      0
WORK_CITY                  2269
WORK_PROVINCE              3248
WORK_COUNTRY                 26
AGE                         420
LOAD_TIME                     0
FLIGHT_COUNT                  0
BP_SUM                        0
EP_SUM_YR_1                   0
EP_SUM_YR_2                   0
SUM_YR_1                    551
SUM_YR_2                    138
SEG_KM_SUM                    0
WEIGHTED_SEG_KM               0
LAST_FLIGHT_DATE              0
AVG_FLIGHT_COUNT              0
AVG_BP_SUM                    0
BEGIN_TO_FIRST                0
LAST_TO_END                   0
AVG_INTERVAL                  0
MAX_INTERVAL                  0
ADD_POINTS_SUM_YR_1           0
ADD_POINTS_SUM_YR_2           0
EXCHANGE_COUNT                0
avg_discount                  0
P1Y_Flight_Count              0
L1Y_Flight_Count              0
P1Y_BP_SUM                    0
L1Y_BP_SUM                    0
EP_SUM                        0
ADD_Point_SUM                 0
Eli_Add_Point_Sum             0
L1Y_ELi_Add_Points            0
Points_Sum                    0
L1Y_Points_Sum                0
Ration_L1Y_Flight_Count       0
Ration_P1Y_Flight_Count       0
Ration_P1Y_BPS                0
Ration_L1Y_BPS                0
Point_NotFlight               0
dtype: int64

数据的预处理

结合业务逻辑进行数据预处理

删除票价为空的数据

1
2
data = data[~data['SUM_YR_1'].isna()]
data = data[~data['SUM_YR_2'].isna()]

丢弃票价为0,平均折扣率不为0,总飞行公里数大于0的记录

1
2
3
4
index_yr_1 = data['SUM_YR_1'] == 0
index_yr_2 = data['SUM_YR_2'] == 0
index_avg_discount = data['avg_discount'] != 0
index_seg_km_sum = data['SEG_KM_SUM'] > 0
1
data = data[~(index_yr_1 & index_yr_2 & index_avg_discount & index_seg_km_sum)]

特征构造

将入会时间和观测窗口结束时间转化为时间类型的数据

1
2
data['FFP_DATE'] = pd.to_datetime(data['FFP_DATE'])
data['LOAD_TIME'] = pd.to_datetime(data['LOAD_TIME'])

构建LRFMC特征

1
data['L'] = (data['LOAD_TIME'] - data['FFP_DATE']).apply(lambda x: x.days/30)
1
data['R'] = data['LAST_TO_END']
1
data['F'] = data['FLIGHT_COUNT']
1
data['M'] = data['SEG_KM_SUM']
1
data['C'] = data['avg_discount']
1
new_data = data[['L', 'R', 'F', 'M', 'C']]
1
2
3
4
5
# 归一化处理
from sklearn.preprocessing import StandardScaler

standard_scaler = StandardScaler()
new_data = standard_scaler.fit_transform(new_data)

对筛选出来的特征进行聚类分析

1
from sklearn.cluster import KMeans
1
2
K = 5
kmeans_model = KMeans(n_clusters=K)
1
kmeans_model.fit(new_data)
KMeans(n_clusters=5)
1
2
# 聚类中心
kmeans_model.cluster_centers_
array([[ 0.06233588, -0.00491015, -0.22698558, -0.23067735,  2.18473313],
       [-0.31475997,  1.68627777, -0.57395798, -0.53669472, -0.17389533],
       [ 0.48278764, -0.7994434 ,  2.48377146,  2.42496111,  0.30842462],
       [ 1.16095498, -0.37732257, -0.0867671 , -0.09463321, -0.159118  ],
       [-0.70027213, -0.41492263, -0.16102864, -0.1609829 , -0.2536324 ]])
1
2
# 聚类类别
sum(kmeans_model.labels_ == 4)
24665

可视化

1
2
3
4
5
# 绘制雷达图
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
1
2
ax = plt.subplot(111, polar=True)
plt.show()

output_40_0_202303092116

1
2
3
# 获取特征数
feature_num = new_data.shape[1]
feature_num
5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 计算极角
angle = list(np.linspace(0, 2*np.pi, feature_num, endpoint=False))
# 将第一个角度再次加入到数组中,使得最终绘制出来的图形是闭合
angle.append(angle[0])
angle = np.array(angle)

# 设置画布
plt.figure(figsize=(5, 5), dpi=150)
# 定义子图类型为极坐标系
ax = plt.subplot(111, polar=True)
# 设置子图标题
ax.set_title('客户群雷达图')
# 定义颜色列表,使得后续绘制出来的不同的图形颜色有区别
color = ['r--', 'b--', 'g--', 'y--', 'm--']
for i in range(K):
# 计算极径
length = list(kmeans_model.cluster_centers_[i])
length.append(length[0])
length = np.array(length)
# 绘制图形
ax.plot(angle, length, color[i])
# ax.set_xticklabels(['L', 'R', 'F', 'M', 'C'])
# 给图形增加图例,区分不同的客户群体
plt.legend(['客户群体1', '客户群体2', '客户群体3', '客户群体4', '客户群体5'])
plt.show()

output_42_0_202303092116

  1. 客户群体1:乘坐飞机的折扣系数比较大,并且其他几个指标都比较低,说明这类客户只在,机票打折时乘坐飞机,属于低价值客户
  2. 客户群体2:这类客户最近一次乘坐飞机距离观测窗口结束时间比较长,说明这类客户属于流失客户。
  3. 客户群体3:这类客户乘坐飞机的次数较高,并且飞行的总里程数也较高,说明这类客户是高价值客户。
  4. 客户群体4:这类客户注册会员时间距离观测窗口结束时间较大,说明这类客户注册会员的时间较长,属于忠诚客户。
  5. 客户群体5:这类客户5个指标都比较低,说明这类客户要么是新用户,要么是无价值客户。
-------------本文结束感谢您的阅读-------------