航空公司客户价值分析

您所在的位置:网站首页 客户分群管理是根据客户特性和什么 航空公司客户价值分析

航空公司客户价值分析

2024-07-10 08:46| 来源: 网络整理| 查看: 265

Airline Customer Value Analysis based on the LRFMC Model.

背景#

信息时代的到来使得企业的营销焦点从产品中心转为了客户中心,为实现企业利润最大化目标。准确的对客户进行分类,根据分类结果制定个性化服务方案,优化企业营销资源分配方案。在航空营销行业中,各个航空公司通过推出更优惠的营销方式来吸引更多的客户,而通过建立合理的客户价值评估模型,对客户进行分群,分析比较不同群体的客户价值,并制定相应的营销策略,对不同的客户群提供个性化的客户服务是必须和有效的。

目标#

本实验基于此来对收集到的某航空公司2012年至2014年的会员档案信息和其乘坐航班记录进行分析,我们将根据这些数据实现以下目标:

借助航空公司客户数据,对客户进行分类。对不同的客户类别进行特征分析,比较不同类客户的客户价值。对不同价值的客户类别提供个性化服务,制定相应的营销策略。模型选择#

本实验的目标是客户价值识别,即对客户进行分类。识别客户价值最广泛的模型是通过RFM指标来对客户进行细分,识别出高价值的客户: Recency (最近消费时间间隔 )Frequency (消费频率 )Monetary (消费金额 )。在RFM模型中,消费金额表示在一段时间内,客户购买该企业产品金额的总和。但在本实验中,基于航空机票价格的多变性,同样消费金额的不同旅客对航空公司的价值是不同的。例如,一位购买长航线、低等级舱位票的旅客与一位购买短航线、高等级舱位票的旅客相比,自然是后者对于航空公司而言价值更高。

因此,在本实验中,我们将消费金额指标使用“客户在一定时间内累积的飞行里程M”和“客户在一定时间内乘坐舱位所对应的折扣系数的平均值C”来代替。由于航空公司会员入会时间的长短在一定程度上能够影响客户价值,我们在模型中增加客户关系长度L这一个指标。 本实验将客户关系长度L、消费时间间隔R、消费频率F、飞行里程M和折扣系数的平均值C五个指标作为航空公司识别客户价值指标,记为LRFMC模型。 针对LRFMC模型,如果采用传统的属性分箱方法,即依据各个属性的平均值进行划分,对其分类,得到的分类客户群过多,提高了针对性营销的成本。并未达到利益最大化目标。因此,选取聚类算法来识别客户价值。通过对航空公司客户价值的LRFMC模型的五个指标进行K-Means聚类,识别出最有价值客户。

总体框架#

1)从数据中选择性抽取与新增数据抽取分别形成历史数据和增量数据。

2)对1)中抽取的数据进行数据探索分析与预处理。包括数据清洗、属性规约和变换等。

3)利用2)中形成的处理后的建模数据,基于LRFMC模型进行客户分群,对每个客户群进行特征分析,识别出有价值的客户。

4)针对模型结果得到不同价值的客户,采用不同的营销手段,提供定制化服务。

探索分析#数据抽取#

对于航空公司抽取的以2014-03-31为结束时间的数据中,抽取所含客户基本信息、乘机信息以及积分信息等详细数据,总含有62,988条记录。 我们将数据的总共数据间隔视为分析观测窗口,在窗口的所有数据即源数据。其中包含了会员卡号、入会时间、性别、年龄、会员卡级别、工作地城市、工作地所在省份、工作地所在国家、观测窗口结束时间、观测窗口乘机积分、飞行公里数、飞行次数、飞行时间、成绩时间间隔和平均折扣率等44个属性。

分析#

对于原始数据,我们总要进行探索分析,即对数据进行缺失值分析和异常分析,分析出数据的规律以及异常值。 在我们的数据中,通过观察发现部分票价属性为空,或者有票价最小值为0、折扣率最小值为0、总飞行公里数却大于0的记录。票价为空值的数据可能是客户不存在乘机记录造成的,而其他的数据是客户乘坐0折机票或者积分兑换产生的。 如何处理这些数据,取决于其在总数据中占的比重有多大。 首先来查找每列属性观测值中空值个数、最大值、最小值等。代码如下:

1#对数据进行基本的探索 2#返回缺失值个数以及最大最小值 3import pandas as pd 4import numpy as np 5 6pd.set_option('display.width', 5000) 1datafile= './flight/air_data.csv' # 航空原始数据,第一行为属性标签 2resultfile = './flight/explore.csv' # 数据探索结果表 3 4data = pd.read_csv(datafile, encoding = 'utf-8') # 读取原始数据,指定UTF-8编码(需要用文本编辑器将数据装换为UTF-8编码) 1explore_num = data.describe(percentiles = [], include = [np.number]).T # 数值型数据描述 2# print(explore_num) # 过于冗余,就不打印了 1explore_obj = data.describe(percentiles = [], include = [np.object]).T # 分类数据描述 2print(explore_obj) count unique top freq FFP_DATE 62988 3068 2011/01/13 184 FIRST_FLIGHT_DATE 62988 3406 2013/02/16 96 GENDER 62985 2 男 48134 WORK_CITY 60719 3310 广州 9385 WORK_PROVINCE 59740 1185 广东 17507 WORK_COUNTRY 62962 118 CN 57748 LOAD_TIME 62988 1 2014/03/31 62988 LAST_FLIGHT_DATE 62988 731 2014/03/31 959 1explore = data.describe(percentiles=[], include = 'all').T 2explore['null'] = len(data)-explore['count'] # describe()函数自动计算非空值数,需要手动计算空值数 3explore = explore[['null', 'max', 'min']] # 切片其中 null max min 三行 4explore.columns = [u'空值数', u'最大值', u'最小值'] # 表头重命名 5print(explore) # 快速查看数据缺失值、最大值、最小值情况 空值数 最大值 最小值 MEMBER_NO 0 62988 1 FFP_DATE 0 NaN NaN FIRST_FLIGHT_DATE 0 NaN NaN GENDER 3 NaN NaN FFP_TIER 0 6 4 WORK_CITY 2269 NaN NaN WORK_PROVINCE 3248 NaN NaN WORK_COUNTRY 26 NaN NaN AGE 420 110 6 LOAD_TIME 0 NaN NaN FLIGHT_COUNT 0 213 2 BP_SUM 0 505308 0 EP_SUM_YR_1 0 0 0 EP_SUM_YR_2 0 74460 0 SUM_YR_1 551 239560 0 SUM_YR_2 138 234188 0 SEG_KM_SUM 0 580717 368 WEIGHTED_SEG_KM 0 558440 0 LAST_FLIGHT_DATE 0 NaN NaN AVG_FLIGHT_COUNT 0 26.625 0.25 AVG_BP_SUM 0 63163.5 0 BEGIN_TO_FIRST 0 729 0 LAST_TO_END 0 731 1 AVG_INTERVAL 0 728 0 MAX_INTERVAL 0 728 0 ADD_POINTS_SUM_YR_1 0 600000 0 ADD_POINTS_SUM_YR_2 0 728282 0 EXCHANGE_COUNT 0 46 0 avg_discount 0 1.5 0 P1Y_Flight_Count 0 118 0 L1Y_Flight_Count 0 111 0 P1Y_BP_SUM 0 246197 0 L1Y_BP_SUM 0 259111 0 EP_SUM 0 74460 0 ADD_Point_SUM 0 984938 0 Eli_Add_Point_Sum 0 984938 0 L1Y_ELi_Add_Points 0 728282 0 Points_Sum 0 985572 0 L1Y_Points_Sum 0 728282 0 Ration_L1Y_Flight_Count 0 1 0 Ration_P1Y_Flight_Count 0 1 0 Ration_P1Y_BPS 0 0.999989 0 Ration_L1Y_BPS 0 0.999993 0 Point_NotFlight 0 140 0 1''' 2这里只选取部分探索结果。 3describe()函数自动计算的字段有: 4count(非空值数)、unique(唯一值数)、top(频数最高者)、freq(最高频数)、 5mean(平均值)、std(方差)、min(最小值)、50%(中位数)、max(最大值) 6''' 7explore.to_csv(resultfile, encoding='utf-8-sig') # 导出结果 resultfile = './flight/explore.csv' # 数据探索结果表

根据上面的代码得到的探索结果如下表中数据:

数据预处理#

本案例主要采用数据清洗、属性规约与数据变换的预处理方法。

由于基于LRMFC模型来对客户进行分群,我们需要将这44个属性进行筛选变换规则,来组成我们需要的指标列表。 而对于数据中的空值,我们则需要对其进行数据清洗。

数据清洗#

通过上一小节中的数据探索分析,发现数据中确实存在缺失值,且票价最小值为0、折扣率最小值为0、总飞行公里数却大于0的记录。但通过观察发现,这部分数据所占比例较小,对于问题影响不大,因此对其进行丢弃处理。具体的处理方法如下:

1.丢弃票价为空的记录。

2.丢弃票价最小值为0、折扣率最小值为0、总飞行公里数却大于0的记录。

使用pandas对满足清洗条件的数据进行丢弃,即该行数据全部丢弃。添加代码如下:

1datafile= './flight/air_data.csv' # 航空原始数据,第一行为属性标签 2cleanedfile = './flight/data_cleaned.csv' # 数据清洗后保存的文件 1data = pd.read_csv(datafile,encoding='utf-8') #读取原始数据,指定UTF-8编码(需要用文本编辑器将数据装换为UTF-8编码) 2 3print('原始数据shape:\t', data.shape) 4### Start Code Here ### 5# 票价非空值才保留 6data = data.dropna(axis=0, subset=['SUM_YR_1', 'SUM_YR_2']) 7### End Code Here ### 8print('删除na后shape:\t', data.shape) 9 10#只保留票价非零的,或者平均折扣率与总飞行公里数同时为0的记录。 11index1 = data['SUM_YR_1'] != 0 # 第一年总票价!=0 12index2 = data['SUM_YR_2'] != 0 # 第二年总票价!=0 13index3 = (data['SEG_KM_SUM'] == 0) & (data['avg_discount'] == 0) # 总飞行里程=0 和 平均折扣率=0 (二者同时为0) 14data = data[index1 | index2 | index3] # 该规则是“或” 15print('删除0值后shape:\t', data.shape) 16 17data.to_csv(cleanedfile, encoding='utf-8-sig') #导出结果,由于excel读取csv文件使用ansi编码 原始数据shape: (62988, 44) 删除na后shape: (62299, 44) 删除0值后shape: (62044, 44)

对于处理后的数据,可以打开./fight/data_cleaned.csv文件查看,此时已将满足清洗条件的数据丢弃:

属性规约#

原始数据中属性太多,根据航空公司客户价值LRFMC模型,只需选择与LRMFC指标相关的6个属性:FFP_DATE、LOAD_TIME、FLIGHT_COUNT、AVG_DISCOUNT、SEG_KM_SUM、LAST_TO_END。即入会时间、观测窗口结束时间、观测窗口的飞行次数、平均折扣率、观测窗口的总飞行公里数、最后一次乘机时间至观测窗口末端时长。删除与其不相干、弱相关或冗余的属性。经过属性选择后的数据集。添加如下代码:

1outfile = './flight/data_stipu.csv' 2df = data[['FFP_DATE','LOAD_TIME','avg_discount','FLIGHT_COUNT','SEG_KM_SUM','LAST_TO_END']] 3df.to_csv(outfile, encoding='utf-8-sig')

规约后的数据格式如下:

数据变换#

数据变换是将数据转换成适当的格式。本实验数据依据LRFMC五个指标,对原始数据进行提取。 具体计算方式如下:

(1) L = LOAD_TIME - FFP_DATE

会员入会时间距观测窗口结束的月数 = 观测窗口的结束时间 - 入会时间 [单位:月]

(2) R = LAST_TO_END

客户最近一次乘坐公司飞机距观测窗口结束的月数 = 最后一次乘机时间至观测窗口末端时长 [单位:月]

(3) F = FLIGHT_COUNT

客户在观测窗口内乘坐公司飞机的次数 = 观测窗口的飞行次数 [单位:次]

(4) M = SEG_KM_SUM

客户在观测时间内在公司累计的飞行里程 = 观测窗口的总飞行公里数 [单位:公里]

(5) C = AVG_DISCOUNT

客户在观测时间内乘坐舱位所对应的折扣系数的平均值 = 平均折扣率 [单位:无]

将5个指标数据提取之后,对每个指标数据分布情况进行分析,可以观察到,5个指标的取值范围数据差异较大,为了消除数量级数据带来的影响,需要对数据进行标准化处理。 本实验我们采用标准差来对数据进行标准化处理,标准差标准化处理后,形成ZL,ZR,ZF,ZM,ZC5个属性的数据。

添加如下代码:

1datafile = './flight/data_stipu.csv' 2standrandfile = './flight/data_stand.csv' 3 4data = pd.read_csv(datafile) 5print('属性规约前\n', data.head()) 6 7#数据变换 8df = data[['LAST_TO_END','FLIGHT_COUNT','SEG_KM_SUM','avg_discount']].copy() # 数据副本的复制 9df['L'] = (pd.to_datetime(data['LOAD_TIME']) - pd.to_datetime(data['FFP_DATE'])).dt.days/30 # 计算日期差,单位为月 10df.rename(columns={'LAST_TO_END':'R','FLIGHT_COUNT':'F','SEG_KM_SUM':'M','avg_discount':'C'},inplace = True) # 列名重命名 11 12# 数据标准化 13df_norm = (df - df.mean()) / (df.std()) 14### End Code Here ### 15print('='*100) # 分割线 16print('属性规约后\n', df_norm.head()) 17 18df_norm.to_csv(standrandfile, encoding='utf-8-sig') 属性规约前 Unnamed: 0 FFP_DATE LOAD_TIME avg_discount FLIGHT_COUNT SEG_KM_SUM LAST_TO_END 0 0 2006/11/02 2014/03/31 0.961639 210 580717 1 1 1 2007/02/19 2014/03/31 1.252314 140 293678 7 2 2 2007/02/01 2014/03/31 1.254676 135 283712 11 3 3 2008/08/22 2014/03/31 1.090870 23 281336 97 4 4 2009/04/10 2014/03/31 0.970658 152 309928 5 ======================================================================================== 属性规约后 R F M C L 0 -0.944948 14.034016 26.761154 1.295540 1.435707 1 -0.911894 9.073213 13.126864 2.868176 1.307152 2 -0.889859 8.718869 12.653481 2.880950 1.328381 3 -0.416098 0.781585 12.540622 1.994714 0.658476 4 -0.922912 9.923636 13.898736 1.344335 0.386032

标准化后的数据格式如下:

模型构建——聚类#

对于客户价值分析模型构建主要分为两个部分:

1.根据LRFMC模型的5个指标的数据,对客户进行聚类分群。

2.结合业务对每个客户群进行特征分析,分析其客户价值,并对客户群进行价值排名。

客户聚类#

本实验采用K-means聚类算法对客户数据进行客户分群,聚类的个数需要结合具体业务来确定。在本实验中由于指标个数,将客户聚成5类。

K-Means算法使用sklearn库来实现。

添加如下代码:

1from sklearn.cluster import KMeans #导入K均值聚类算法 2import numpy as np 3 4np.set_printoptions(threshold=np.inf) 5 6inputfile = './flight/data_stand.csv' #待聚类的数据文件 7k = 5 #需要进行的聚类类别数 8 9#读取数据并进行聚类分析 10data = pd.read_csv(inputfile).drop(['Unnamed: 0'],axis=1) #读取数据 11print(data.head()) R F M C L 0 -0.944948 14.034016 26.761154 1.295540 1.435707 1 -0.911894 9.073213 13.126864 2.868176 1.307152 2 -0.889859 8.718869 12.653481 2.880950 1.328381 3 -0.416098 0.781585 12.540622 1.994714 0.658476 4 -0.922912 9.923636 13.898736 1.344335 0.386032 1# 调用k-means算法,进行聚类分析 2kmodel = KMeans(n_clusters=k, max_iter=300, tol=0.0001, init="random",random_state=127) 3#如果为空即插值。 4 5kmodel.fit(data) #训练模型 6 7print(kmodel.cluster_centers_) #查看聚类中心 [[-2.67731538e-04 -2.27077663e-01 -2.31248314e-01 2.19508044e+00 5.46691125e-02] [-7.99426446e-01 2.48288269e+00 2.42414127e+00 3.08700274e-01 4.83113696e-01] [-3.77245676e-01 -8.73024480e-02 -9.50486798e-02 -1.56073456e-01 1.16066319e+00] [-4.15372627e-01 -1.60892758e-01 -1.60813095e-01 -2.53912499e-01 -7.00241623e-01] [ 1.68527615e+00 -5.73955921e-01 -5.36785962e-01 -1.74231521e-01 -3.13974727e-01]]

运行后可以看到我们的聚类中心结果:

其列对应ZR、ZF、ZM、ZC、ZL指标。

我们可以看到通过使用聚类算法对客户进行聚类分群的结果。但由于K-Means聚类算法是随机选择类标号,故重复实验时得到的结果可能与上述结果有些出入。另外,由于算法的精度问题,重复实验得到的聚类中心也略有不同。

模型评价#

针对聚类结果,我们使用雷达图使得聚类结果可视化,更加直观的分析各个用户群的特征。

添加如下代码:

1%matplotlib inline 2import matplotlib.pyplot as plt 3 4labels = data.columns #标签 5k = 5 #数据个数 6 7plot_data = kmodel.cluster_centers_ 8color = ['b', 'g', 'r', 'c', 'y'] #指定颜色 1angles = np.linspace(0, 2*np.pi, k, endpoint=False) # 创建 k 个等间隔的 [0, 2π) 数值序列 2plot_data = np.concatenate((plot_data, plot_data[:,[0]]), axis=1) # 闭合 3print(' R', 'F', 'M', 'C', 'L', sep='\t\t') 4print(plot_data) 5angles = np.concatenate((angles, [angles[0]])) # 闭合 6print(angles) # 弧度制 1plt.figure(figsize=(10, 8)) 2fig = plt.figure() # 创建图形对象 3ax = fig.add_subplot(111, polar=True) # 111 为子图编号 ploar = True 使用极坐标 4 5for i in range(len(plot_data)): 6 ax.plot(angles, plot_data[i], 'o-', color = color[i], label = u'customer'+str(i+1), linewidth=2) # 'o-' 表示使用线和圆圈来连接数据点 7 8ax.set_thetagrids(angles * 180/np.pi, labels) # 在极坐标图中设置角度刻度线和标签 9# ax.set_rgrids(np.arange(-1, 2.51, 0.5), linewidth=2) # 设置径向刻度线 线与线之间的间隔 线上的刻度 10ax.set_rticks(np.arange(-1, 3.1, 0.5)) 11 12plt.legend(bbox_to_anchor=(1.05, 0), loc=3, borderaxespad=0) # 添加图例,并将图例放在图形外侧 13plt.show() # 由于上面聚类结果不稳定,所以不是每次运行所生成的雷达图都是完全一致的

1print(np.arange(0, 8, 1)) 2print(np.arange(-1, 2.51, 0.5)) [0 1 2 3 4 5 6 7] [-1. -0.5 0. 0.5 1. 1.5 2. 2.5]

接下来,我们针对可视化结果对数据特征进行分析。其中,客户群1在C上属性最大;客户群2在F、M属性上最大,在R属性上最小;客户群3在L属性上最大;客户群4在L、R属性上最小;客户群5在R上属性最大,在F、M上属性最小。结合业务分析,通过比较各个指标在群间的大小对某一个群的特征进行评价分析。

对于LRMFC模型,其L\M\F\C指标越大越好,R指标越小越好,我们根据聚类中心结果来对各个客户群进行特征划分。依此找出每个特征对应的最大值、最小值、次大值、次小值。

客户群编号优势特征劣势特征客户群1CRFM客户群2FMR-客户群3LFM-客户群4-LC客户群5-RFM

【注】正常体为最大值,加粗体为次大值,斜体为最小值,下划线为次小值。

由上述的特征分析图表说明每个客户群都有显著不同的表现特征,基于该特征描述,本实验案例中定义五个等级的客户类别:重要保持客户、重要发展客户、重要挽留客户、一般客户、低价值客户。其中每种客户类别的具体特征如下:

保持客户 这类客户的平均折扣率C较高,一般所乘坐的舱位等级较高,最近乘坐过本公司航班R低、乘坐的次数F或里程M较高。这些客户对于航空公司来说是高价值客户,相对来说所占的比例也偏小。航空公司应该优先将资源投放到他们呢身上,对他们进行差异化管理和一对一影响,提供这类用户的忠诚度与满意度,延长这类客户的高水平消费。

重要发展客户:这类客户的平均折扣率C较高,最近乘坐过本公司航班R低,但乘坐次数F或乘坐里程M较低。这类客户入会时间L短,他们是航空公司的潜在 价值客户。虽然这类客户目前的价值不是很高,但有很大的发展潜力。航空公司应努力促使这类客户增加在本公司的乘机消费和合作伙伴处的消费,增加客户的钱包份额。通过客户价值的提升,加强这类客户的满意度,提高他们转向竞争对手的转移成本,使他们逐渐称为公司的忠诚客户。

重要挽留客户:这类客户过去所乘航班的平均折扣率C、乘坐次数F或者里程数M较高,但已经较长时间没有乘坐本公司的航班R高或者使乘坐频率变小。他们的客户价值变化的不确定性很高。由于这些客户衰退的原因各不相同,所以掌握客户的最新信息、维持与客户的互动就显得尤为重要。航空公司应该根据这些客户的最近消费时间、消费次数的变化情况、推测客户消费的异动状况,并列出客户名单。对其采取一定的营销手段,延长客户的生命周期。

一般与低价值客户:这类客户所乘航班的平均折扣率C很低,较长时间没有乘坐过本公司航班R高,乘坐次数F或者里程M较低,入会时间L短。这些客户的价值较低,可能是在航空公司机票打折促销时,才会乘坐本公司航班。

根据特征定义我们可以将客户群分类:

客户群1,C值最大,R次大,FM为次小值。可见这类客户最近乘机次数少,但其折扣率较大,成绩次数和里程也偏小。故为重要发展客户。

客户群2,F,M为最大值,R为最小值。完全符合重要保持客户。

客户群3,L为最大值,F,M为次大值。这类客户入会时间长,乘机次数和总里程偏大,最近乘机时间并未表现明显增加。故为重要挽留客户。

客户群4,L,C为最小值,即入会时间短,且折扣率小。应归属到低价值客户。

客户群5,R为最大值,FM为最小值。可见这类客户最近乘机次数少,里程也较小。故为一般客户。

对客户进行特征划分后,针对不同类型的客户群提供不同的产品和服务,提升重要发展客户的价值、稳定和延长重要保持客户的高水平消费、防范重要挽留客户的流失并积极进行关系恢复。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3