【机器学习与数据挖掘实战】案例02:基于K-Means算法的航空公司客户价值分析

在这里插入图片描述

【作者主页】Francek Chen
【专栏介绍】 ⌈ ⌈ 机器学习与数据挖掘实战 ⌋ ⌋ 机器学习是人工智能的一个分支,专注于让计算机系统通过数据学习和改进。它利用统计和计算方法,使模型能够从数据中自动提取特征并做出预测或决策。数据挖掘则是从大型数据集中发现模式、关联和异常的过程,旨在提取有价值的信息和知识。机器学习为数据挖掘提供了强大的分析工具,而数据挖掘则是机器学习应用的重要领域,两者相辅相成,共同推动数据科学的发展。本专栏介绍机器学习与数据挖掘的相关实战案例。
【GitCode】专栏资源保存在我的GitCode仓库:https://gitcode.com/Morse_Chen/ML-DM_cases。

文章目录

    • 一、目标分析
      • (一)背景
      • (二)数据说明
      • (三)分析目标
    • 二、数据准备
      • (一)数据探索
      • (二)数据清洗
    • 三、特征工程
      • (一)特征构造
      • (二)特征选择
      • (三)特征变换
    • 四、模型训练
    • 五、性能度量
      • (一)结果分析
      • (二)客户价值分析
    • 小结


一、目标分析

(一)背景

目前,全球经济环境和市场环境正在悄然发生改变,企业的业务也在逐步由产品为主导向客户需求为主导转型。一种全新的“以客户为中心”的业务模式正在形成并被提升到前所未有的高度。随着中国社会经济的发展,我国民航已经从卖方市场转变为买方市场,再加上铁路提速和全国公路网日益完善,不同运输方式间的竞争日趋激烈,航空公司面临的压力越来越大。

航空公司属于典型的服务行业,其目的是获取更多的利润,然而当今航空公司产品同质化现象严重,并且竞争激烈,客户资源成为航空公司最为短缺的资源,谁拥有的客户资源多,谁的核心竞争力就强,获得的利润就会更多。

客户营销战略的倡导者Jay Curry& Adam Curry从国外数百家公司进行了客户营销实施的经验中提炼了如下经验。

  • 公司收入的80%来自顶端的20%的客户。
  • 20%的客户带来的利润率能够达到100%。
  • 90%以上的收入来自现有客户。
  • 大部分的营销预算经常被用在非现有客户上。
  • 5%至30%的客户在客户金字塔中具有升级潜力。
  • 客户金字塔中客户升级2%,意味着销售收入增加10%,利润增加50%。

虽然这些经验也许并不完全准确,但是客户作为航空公司的主要利润来源,要求航空公司不断地认识、发现、开发和满足客户的需求,与客户建立一种稳定的客户关系。这一现实情况揭示了新时代客户分化的趋势,而这种趋势说明了进行客户价值分析的必要性。目前各航空公司都已认识到这一关键因素,并且将客户价值分析作为公司发展战略之一。

本案例将在航空公司客户数据的基础上,建立合理的客户价值模型,对客户进行分群,分析比较不同客户群的客户价值,为企业提供更精准的策略依据,帮助企业制定更加符合市场行情和企业现状的营销策略,为企业带来更多的利润。

(二)数据说明

目前该航空公司已积累了大量的会员档案信息和其乘坐航班记录,以2014年3月31日为结束时间抽取两年内有乘机记录的所有客户的详细数据。数据包含会员卡号、入会时间、性别、年龄、会员卡级别、工作地城市、工作地所在省份、工作地所在国家、观测窗口结束时间、观测窗口乘机积分、飞行公里数、飞行次数、飞行时间、乘机时间间隔、平均折扣率等特征。

本案例所用数据集air_data.csv内容如下。

在这里插入图片描述

本案例所用数据特征名称及说明如下表所示。

特征名称特征说明
客户基本信息MEMBER_NO会员卡号
FFP_DATE入会时间
FIRST_FLIGHT_DATE第一次飞行日期
GENDER性别
FFP_TIER会员卡级别
WORK_CITY工作地城市
WORK_PROVINCE工作地所在省份
WORK_COUNTRY工作地所在国家
AGE年龄
乘机信息FLIGHT_COUNT观测窗口内的飞行次数
LOAD_TIME观测窗口的结束时间
LAST_TO_END最后一次乘机时间至观测窗口结束时长
avg_discount平均折扣率
SUM_YR观测窗口的票价收入
SEG_KM_SUM观测窗口的总飞行公里数
LAST_FLIGHT_DATE末次飞行日期
AVG_INTERVAL平均乘机时间间隔
MAX_INTERVAL最大乘机间隔
积分信息EXCHANGE_COUNT积分兑换次数
EP_SUM总精英积分
PROMOPTIVE_SUM促销积分
PARTNER_SUM合作伙伴积分
POINTS_SUM总累计积分
POINT_NOTFLIGHT非乘机的积分变动次数
BP_SUM总基本积分

(三)分析目标

结合目前航空公司的数据情况,可以实现以下目标。

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

本案例的总体流程主要包括以下4个步骤。

  1. 抽取航空公司2012年4月1日至2014年3月31日的数据。
  2. 对抽取的数据进行数据清洗、特征构建和标准化等操作。
  3. 基于RFM模型,使用K-Means算法进行客户分群。
  4. 针对模型结果得到不同价值的客户,采用不同的营销手段,提供定制化的服务。

航空公司客户价值分析总体流程如下图所示。

在这里插入图片描述

二、数据准备

国内某航空公司提供的原始数据尚未经过处理,数据质量可能尚未达到可以直接用于建模的程度,可能存在缺失值、异常值等问题,这些问题会导致建立的模型不够精确,为尽可能地排除干扰因素、保证模型的可靠性,需要进行必要的数据准备。

(一)数据探索

由于航空公司客户乘机记录信息数据量很大,因此在获取数据时,对原始数据进行截取,以2014年3月31日为结束时间,选取宽度为两年(2012年4月1日~2014年3月31日)的时间段作为分析观测窗口,抽取观测窗口内有乘机记录的所有客户的详细数据形成历史数据,总共62988条记录。

1. 描述性统计分析:查看属性字段的缺失值、最大值、最小值、平均值等情况,从宏观层面上了解数据。

import pandas as pdairline_data = pd.read_csv('../data/air_data.csv')look = airline_data.describe(percentiles=[], include='all').T  # 使用统计函数对数据进行统计分析
look['null'] = len(airline_data) - look['count']  # 计算空值数
# describe有很多统计子项,这里就取我们要用到的即可
look = look[['null', 'max', 'min', 'mean']]
look.columns = ['空值记录数', '最大值', '最小值', '平均值']look

在这里插入图片描述

截取数据后对数据进行探索,在数据探索过程中,发现数据中存在缺失值和异常值,具体表现为票价为空值、或票价为0、或折扣率为0、或总飞行公里数为0的记录。这些值的存在会对模型的建立产生不可忽视的影响,如模型的不确定性会变得更加显著,其蕴含的规律更难把握,甚至导致模型输出的结果不可靠,因此在数据清洗过程中要重点对这两类数据进行处理。

2. 数据的分布分析:寻找客户信息的分布规律,例如入会时间分布、年龄分布、性别分布、会员等级分布等等。

(1)入会时间分布图展示

import pandas as pd
from datetime import datetime
import matplotlib.pyplot as pltairline_data = pd.read_csv('../data/air_data.csv')ffp = airline_data['FFP_DATE'].apply(lambda x: datetime.strptime(x, '%Y/%m/%d'))
ffp_year = ffp.map(lambda x: x.year)plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
# 绘制各年份会员入会人数直方图
plt.hist(ffp_year, bins='auto')
plt.xlabel('年份')
plt.ylabel('入会人数')
plt.title('各年份会员入会人数')
plt.show()

在这里插入图片描述

(2)会员性别比例分布图

import matplotlib.pyplot as pltairline_data = pd.read_csv('../data/air_data.csv')
# 获取会员中不同的性别人数
male = pd.value_counts(airline_data['GENDER'])['男']
female = pd.value_counts(airline_data['GENDER'])['女']# 绘制会员分布饼状图
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
plt.pie([male, female], labels=['男', '女'], autopct='%1.1f%%')
plt.title('会员性别比例')
plt.show()

在这里插入图片描述

(3)会员年龄分布箱型图

import pandas as pd
from datetime import datetime
import matplotlib.pyplot as pltairline_data = pd.read_csv('../data/air_data.csv')
# 提取会员的年龄
age = airline_data['AGE'].dropna()
age = age.astype('int64')# 绘制会员年龄分布箱型图
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
plt.boxplot(age, patch_artist=True, labels=['会员年龄'])
plt.title('会员年龄分布箱型图')
plt.grid(axis='y')
plt.show()

在这里插入图片描述

3. 数据属性之间的相关性分析:这对特征的选择来说非常有用,通过分析属性之间的关联性,可以确定选择哪些属性作为特征值,哪些则是可以忽略的。

# 相关性分析
import pandas as pd
from datetime import datetime# 读取数据
airline_data = pd.read_csv('../data/air_data.csv')
# 创建相关性计算的数据框
data_corr = airline_data[['FFP_TIER', 'FLIGHT_COUNT', 'LAST_TO_END', 'SEG_KM_SUM', 'EXCHANGE_COUNT', 'Points_Sum']].copy()
# 填充AGE的缺失值并转换为整数
age_1 = airline_data['AGE'].fillna(0)
data_corr.loc[:, 'AGE'] = age_1.astype('int64')  # 使用 .loc 来修改列# 处理FFP_DATE并提取年份
ffp = airline_data['FFP_DATE'].apply(lambda x: datetime.strptime(x, '%Y/%m/%d'))
ffp_year = ffp.map(lambda x: x.year)
data_corr.loc[:, 'ffp_year'] = ffp_year  # 使用 .loc 来修改列
# 计算相关性矩阵
dt_corr = data_corr.corr(method='pearson')
print(dt_corr)

在这里插入图片描述

从上面的图可以看出,有些属性的相关性较强,有些则较弱。例如ffp_yearFFP_TIER的相关性就弱,已经是负相关了。而FLIGHTFFP_TIER的相关性就稍微强一些。属性之间的相关性关系,也是在做特征降维的一个重要参考量,有时候特征较多会严重增加建模的时间,为了提高效率,需要对特征进行降维,构建有代表性的特征进行建模。

(二)数据清洗

在数据清洗过程中,因为原始数据量大,缺失值和异常值在数据集中占比较小,所以需要对缺失值和异常值均进行删除处理,即丢弃票价为0,或平均折扣率为0,或总飞行公里数为0的记录。

相关代码如下。

# 数据清洗
import pandas as pdairline_data = pd.read_csv('../data/air_data.csv')
print('原始数据的形状为:', airline_data.shape)
# 去除票价为空的记录
index_not_na1 = airline_data['SUM_YR_1'].notnull() 
index_not_na2 = airline_data['SUM_YR_2'].notnull()
index_not_na = index_not_na1 & index_not_na2
airline_notnull = airline_data.loc[index_not_na, :]
print('删除缺失记录后数据的形状为:', airline_notnull.shape)# 丢弃票价为0,或平均折扣率为0,或总飞行公里数为0的记录 
index1 = airline_notnull['SUM_YR_1'] == 0
index2 = airline_notnull['SUM_YR_2'] == 0
index3 = (airline_notnull['SEG_KM_SUM']== 0) | (airline_notnull['avg_discount'] == 0)  
index_drop = airline_notnull.index[(index1 & index2) | index3]
airline = airline_notnull.drop(index_drop, axis=0)
airline.to_csv('../tmp/air_data_clean.csv')
print('删除异常记录后数据的形状为:', airline.shape)

在这里插入图片描述

三、特征工程

在建模之前需要对原始数据特征进行处理,筛选出更好的特征,才能获取更好的训练数据,让建立的模型能够得到更加精确的结果。特征构造是指从原始数据中人工的构建一些具有实际意义的特征,本案例借助RFM模型进行特征构造。

(一)特征构造

1. RFM模型

RFM模型是识别客户价值应用较为广泛的模型,RFM模型具体的含义如下。

(1)R(Recency)

R(Recency)指的是最近一次消费时间与截止时间的间隔,简称时间间隔。通常情况下,最近一次消费时间与截止时间的间隔越短,对即时提供的商品或是服务也最有可能感兴趣。这也是消费时间间隔0至6个月的顾客收到的沟通信息多于1年以上的顾客的原因。

最近一次消费时间与截止时间的间隔不仅能够为确定促销客户群体提供依据,还能够从中得出企业发展的趋势。如果分析报告显示最近一次消费时间很近的客户在增加,则表示该公司是个稳步上升的公司。反之,最近一次消费时间很近的客户越来越少,则说明该公司需要找到问题所在,及时调整营销策略。

(2)F(Frequency)

F(Frequency)指顾客在某段时间内所消费的次数,简称消费频率。可以说消费频率越高的顾客,也是满意度越高的顾客,其忠诚度也就越高,顾客价值也就越大。增加顾客购买的次数意味着从竞争对手处争取市场占有率,赚取营业额。商家需要做的是通过各种营销方式,去不断地刺激顾客消费,提高他们的消费频率,提升顾客的复购率。

(3)M(Monetary)

M(Monetary)指顾客在某段时间内所消费的金额,简称消费金额。消费金额越大的顾客,他们的消费能力自然也就越大,这就是所谓“20%的顾客贡献了80%的销售额”的二八法则。而这批顾客也必然是商家在进行营销活动时需要特别照顾的群体,尤其是在商家前期资源不足的时候。不过需要注意一点,不论采用哪种营销方式,以不对顾客造成骚扰为大前提,否则营销只会产生负面效果。

在RFM模型理论中,时间间隔、消费频率、消费金额是判别客户价值最重要的特征,这3个特征对营销活动的具有十分重要的意义,其中,时间间隔是最有力的特征。

2. RFM模型解读

RFM模型包括3个特征,无法用平面坐标图来展示,所以这里使用三维坐标系进行展示,X轴表示Recency,Y轴表示Frequency,Z轴表示Monetary,每个轴一般会分成5级表示程度,1为最小,5为最大。需要特别说明的是,R特征,在X轴上R值越大代表该类客户最近一次消费与截止时间的消费间隔越短,客户R维度上的质量越好。X轴表示R特征,Y轴表示F特征,Z轴表示M指标,每个轴上划分5等级,等价于将客户划分为5×5×5=125。这里划分为5级并不是严格的要求,一般是根据实际研究需求和顾客的总量进行划分,对于是否等分的问题取决于该维度上客户的分布规律。

通过下图可以看出,左上角方框的客户RFM特征取值为155。消费的近度R值是比较小的,说明该类客户最近都没有来店消费,原因可能是因为最近比较忙或对现有的产品或服务不满意,或是找到了更好的商家。R特征数值变小需要企业管理人员引起重视,说明该类客户可能流失,对企业造成损失。消费频率F很高,说明客户很活跃,经常到商家消费。消费金额M值很高,说明该类客户是具备一定的消费能力,为店里贡献了很多的营业额。这类型客户总体分析比较优质,但是R特征时间近度值较小,其往往是需要针对进行营销优化的客户群体。

在这里插入图片描述
同理,若客户RFM特征取值为555。则可以判定该客户为最优质客户,即该类客户最近有到商家消费,消费频率很高,消费金额很大,该类客户往往是企业利益的主要贡献者,是需要重点关注与维护的客户。

3. 特征构造

在RFM模型中,消费金额表示客户在一段时间内购买该企业产品金额的总和。然而航空票价受到多种因素(如距离、舱位等级)的影响,因此消费同样金额的不同客户对航空公司的价值可能是不同的,如一位购买长航线,低等级舱位票的旅客与一位购买短航线,高等级舱位票的旅客相比,后者对于航空公司而言价值可能更高。因此RFM模型中的消费金额这一特征并不适用于航空公司客户价值分析。

本案例在RFM模型的基础上,选择客户在一定时间内累积的飞行里程M、客户在一定时间内乘坐舱位所对应的折扣系数的平均值C。同时,因为航空公司会员入会时间的长短在一定程度上能够影响客户价值,所以在模型中增加客户关系长度L,作为区分客户的另一特征。

(二)特征选择

本案例选择客户关系长度L、时间间隔R、消费频率F、飞行里程M和折扣系数的平均值C作为航空公司识别客户价值的特征,记为LRFMC模型。

LRFMC
会员入会时间距观测窗口结束的月数客户最近一次乘坐公司飞机距观测窗口结束的月数客户在观测窗口内乘坐公司飞机的次数客户在观测窗口内累计的飞行里程客户在观测窗口内乘坐舱位所对应的折扣系数的平均值

根据航空公司客户价值LRFMC模型,选择与LRFMC特征相关的6个特征:FFP_DATE、LOAD_TIME、FLIGHT_COUNT、avg_discount、SEG_KM_SUM、LAST_TO_END。

LOAD_TIMEFFP_DATELAST_TO_ENDFLIGHT_COUNTSEG_K_M_SUMAVG_DISCOUNT
2014/3/312013/3/1623141268501.02
2014/3/312012/6/266651847300.76
2014/3/312009/12/8233603871.27
2014/3/312009/12/101236622591.02
2014/3/312011/8/251422547301.36
2014/3/312012/9/262326500241.29
2014/3/312010/12/27775611600.94
2014/3/312009/10/21674489281.05
2014/3/312010/4/151125434991.33
2014/3/312007/1/262236687600.88

相关代码如下。

import pandas as pd
import numpy as npairline = pd.read_csv('../data/air_data.csv')
# 选取需求特征
airline_selection = airline[['FFP_DATE', 'LOAD_TIME', 'FLIGHT_COUNT', 'LAST_TO_END', 'avg_discount', 'SEG_KM_SUM']]
# 构建L特征
L = pd.to_datetime(airline_selection['LOAD_TIME']) - pd.to_datetime(airline_selection['FFP_DATE'])
L = L.astype('str').str.split().str[0]
L = L.astype('int') / 30
# 合并特征
airline_features1 = pd.concat([L, airline_selection.iloc[:, 2:]], axis = 1)
airline_features1.columns = ['L', 'F', 'R', 'C', 'M']
airline_features = pd.DataFrame(np.zeros([len(airline_features1), 5]), columns = ['L', 'R', 'F', 'M', 'C'])
for i in range(len(airline_features.columns)):airline_features.loc[:, airline_features.columns[i]] = list(airline_features1.loc[:, airline_features.columns[i]])print('构建的L、R、F、M、C特征前5行为:\n', airline_features.head())

在这里插入图片描述

(三)特征变换

由于选取的L、R、F、M、C特征在原始数据中并没有直接给出,因此需要根据原始数据特征进行特征变换得到需要的特征。

  • L = 观测窗口的结束时间 - 入会时间 = LOAD_TIME-FFP_DATE
  • R = 最后一次乘机时间至观察窗口末端时长 = LAST_TO_END
  • F = 观测窗口的飞行次数 = FLIGHT_COUNT
  • M = 观测窗口总飞行公里数 = SEG_KM_SUM
  • C = 平均折扣率 = avg_discount

相关代码如下。

# 查看特征取值范围
explore = airline_features.describe(percentiles = [], include = 'all')
explore = explore.loc[['min', 'max'], :]
print('L、R、F、M、C 5个特征取值范围:\n', explore )

在这里插入图片描述

# 数据标准化
from sklearn.preprocessing import StandardScaler
air_scale = StandardScaler().fit_transform(airline_features)
np.savez('../tmp/airline_scale.npz', air_scale)
print('标准化后L、R、F、M、C 5个特征为:\n', air_scale[:5, :])

在这里插入图片描述

四、模型训练

采用K-Means聚类算法对航空公司客户进行分群,K-Means聚类需要预先给出k值,即需要事先指定聚类数目,本案例根据对业务的理解与分析结合Calinski-Harabasz指数确定聚类数目k,Calinski-Harabasz指数越大表示聚类效果越好,在建模过程中k取Calinski-Harabasz指数最大值对应的聚类数。

相关代码如下。

from sklearn.cluster import KMeans  # 导入KMeans算法
import matplotlib.pyplot as plt  # 导入画图库
from sklearn import metrics  # 导入计算Calinski-Harabasz指数的库
import pandas as pd
import numpy as npairline_scale = np.load('../tmp/airline_scale.npz')['arr_0']
# 利用Calinski-Harabasz指数确定聚类数目
CH = []
for i in range(3, 6):model = KMeans(n_clusters = i, n_jobs=4, random_state =123).fit(airline_scale)labels = model.labels_CH.append(metrics.calinski_harabasz_score(airline_scale, labels))
k = CH.index(max(CH)) + 3  # 确定聚类中心数
print('最佳聚类数目', k)# 绘制不同聚类数目与对应的Calinski-Harabasz指数折线图
x = range(3, 6)  # x为折线图中的横坐标
plt.plot(x, CH, '-xr')
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号 
plt.title('不同聚类数目对应的Calinski-Harabasz指数')
plt.show()# 构建模型
kmeans_model = KMeans(n_clusters = k, n_jobs=4, random_state=123)
fit_kmeans = kmeans_model.fit(airline_scale)  # 模型训练
# 查看聚类中心
print('聚类中心为:\n', kmeans_model.cluster_centers_)
print('保留小数点后4位后聚类中心为:\n', np.round(kmeans_model.cluster_centers_, 4))print('样本类别标签为', kmeans_model.labels_)  # 查看样本的类别标签# 统计不同类别样本的数目
count_class = pd.Series(kmeans_model.labels_).value_counts()
print('最终每个类别的数目为:\n', count_class)cluster_centers = pd.DataFrame(kmeans_model.cluster_centers_)
cluster_centers.to_csv('../tmp/cluster_centers.csv', index=False)  # 保存聚类中心labels = pd.DataFrame(kmeans_model.labels_)
labels.to_csv('../tmp/labels.csv', index=False)  # 保存聚类类别标签

在这里插入图片描述

五、性能度量

本案例中K-Means模型采用历史数据进行建模,随着时间的变化,分析数据的观测窗口在变化,航空公司客户的数据信息也在变化。因此,考虑业务的实际情况,建议每个月运行一次该模型,通过聚类判断新增加的客户所属的客户群,同时分析新增客户特征的价值。如果新增加客户数据的实际情况与判断结果差异较大,那么需要业务部门重点关注,查看出现差异的原因并确认模型的稳定性,如果模型稳定性变化较大,那么需要重新训练聚类模型。

(一)结果分析

客户分群聚类结果如表所示。

聚类类别聚类个数聚类中心
ZLZRZFZMZC
客户群155630.4793-0.7962.43842.38320.3819
客户群212939-0.30921.659-0.5721-0.5359-0.0183
客户群3172531.1388-0.3667-0.0957-0.10490.0957
客户群426288-0.6961-0.4085-0.1696-0.1698-0.1343

根据聚类结果绘制雷达图,如图所示。相关代码如下。

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np# 客户分群雷达图
cluster_center = pd.read_csv('../tmp/cluster_centers.csv')
labels = pd.read_csv('../tmp/labels.csv')
cluster_center.columns = ['ZL', 'ZR', 'ZF', 'ZM', 'ZC']  # 将聚类中心放在数据框中
cluster_center.index = labels.drop_duplicates().iloc[:, 0]  # 将样本类别作为数据框索引
label = ['ZL', 'ZR', 'ZF', 'ZM', 'ZC']
lstype = ['-','--',':','-.']
legen = ['客户群' + str(i + 1) for i in cluster_center.index]  # 客户群命名,作为雷达图的图例
kinds = list(cluster_center.iloc[:, 0])# 由于雷达图要保证数据闭合,因此再添加ZL列 ,并转换为 np.ndarray
cluster_center = pd.concat([cluster_center, cluster_center[['ZL']]], axis=1)
centers = np.array(cluster_center.iloc[:, 0:])
# 分割圆周长,并让其闭合
n = len(label)
angle = np.linspace(0, 2 * np.pi, n, endpoint = False)
angle = np.concatenate((angle, [angle[0]]))# 绘图
fig = plt.figure(figsize = (8, 6))
ax = fig.add_subplot(111, polar = True)  # 以极坐标的形式绘制图形
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号 # 画线
for i in range(len(kinds)):ax.plot(angle, centers[i], linestyle=lstype[i], linewidth=2, label=kinds[i])
# 添加属性标签
ax.set_thetagrids(angle * 180 / np.pi, label)
plt.title('客户特征分析雷达图')
plt.legend(legen)
plt.savefig('客户特征分析雷达图.jpg', dpi=2080) #指定分辨率保存
plt.show()

在这里插入图片描述

客户群1在特征F、M处的值最大,在特征R处的值最小,说明客户群1消费频率和累积飞行里程较大,消费时间间隔较小,这类客户需要航空公司重点关注并保持良好关系,称F、M、R特征为客户群1的优势特征。

客户群2在L、C特征处的值最小,说明客户群2入会时间较短、享受的平均折扣系数较小。

客户群3在R特征处的值最大,在F、M特征处的值最小,说明客户群3消费频率和累积飞行里程较小,消费时间间隔较大,这类客户可能只有在机票打折的时候才会乘坐航空公司航班,称F、M、R特征为客户群3的弱势特征。

客户群4在特征L处的值最大,说明客户群4入会时间较长。

每个客户群的优势特征和弱势特征总结如表所示,其中正常字体表示最大值,加粗字体表示次大值,斜体字体表示最小值。

群类别优势特征弱势特征
客户群1FMR
客户群2LC
客户群3FMR
客户群4LFM

(二)客户价值分析

  • 重要保持客户:平均折扣系数C较高,时间间隔R较低,消费频率(乘机次数)F或累积飞行里程M较高。这类客户是航空公司最理想的客户,他们为航空公司带来了大部分的利润,但是这类客户占的比例比较小,航空公司应该优先考虑将营销资源投入到这类客户,尽量使这类客户能够保持在公司的高质量消费。

  • 重要挽留客户:在过去的时间里平均折扣系数C,消费频率(乘机次数)F或飞行里程M较高,但是时间间隔R较大或消费频率(乘机次数)F逐渐变小。这类客户存在较高的不确定性因素,航空公司应该提高警惕,采取一定的营销手段,延长客户在航空公司的消费周期,否则,这些不确定因素可能导致这类客户的流失。

  • 一般与低价值客户:平均折扣系数C较低,时间间隔R较高,消费频率(乘机次数)F或飞行里程M较低,会员入会时间L较低。对于这类客户,航空公司不需要过多地关注,因为他们可能只有在机票打折的时候才会乘坐航空公司航班。

根据客户类别特征描述,对模型得出的客户群进行客户价值排名,如表所示。针对不同类别的客户群航空公司应该采取不同的营销策略,对不同类型的客户群提供不同的产品和服务,稳定和延长重要保持客户的高水平消费,防范重要挽留客户的流失。

客户群排名排名含义
客户群11重要保持客户
客户群23一般客户
客户群32重要挽留用户
客户群44低价值客户

小结

本案例结合航空公司客户的会员乘机记录信息,重点介绍了K-Means聚类算法在客户价值分析中的应用。

首先对原始数据进行探索,寻找数据特点,对原始数据进行清洗,处理缺失值和异常值。然后对RFM模型进行改进,构造LRFMC模型,进而构建特征集合。最后根据对业务的理解和分析结合Calinski-Harabasz指数确定最佳聚类数目,利用K-Means聚类算法对航空公司客户分群,对聚类得出的客户群进行特征分析,划分客户类别,并给出一定的策略建议。

:以上文中的数据集及相关资源下载地址:
链接:https://pan.quark.cn/s/3fdf442547c7
提取码:13nH

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/491107.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JPG 转 PDF:免费好用的在线图片转 PDF 工具

JPG 转 PDF:免费好用的在线图片转 PDF 工具 在日常工作和生活中,我们经常需要将图片转换为 PDF 格式。无论是制作电子文档、准备演示材料,还是整理照片集,将图片转换为 PDF 都是一个常见的需求。今天为大家介绍一款完全免费、无需…

STM32F103单片机HAL库串口通信卡死问题解决方法

在上篇文章 STM32F103单片机使用STM32CubeMX创建IAR串口工程 中分享了使用cubeMX直接生成串口代码的方法,在测试的过程中无意间发现,串口会出现卡死的问题。 当串口一次性发送十几个数据的时候,串口感觉像卡死了一样,不再接收数据…

Linux 中 sftp 命令基本使用

参考链接 sftp 命令_sftp命令-CSDN博客 登录服务器【必须】 # sftp userNamehost # 例如 sftp root8.138.86.224 上传文件到服务器 使用 sftp 命令可以将本地文件上传到远程主机 # put local_file remote_file # 例如: put E://1.mp4 /root/1.mp4 下载文件 使…

采用qL-MPC技术进行小型固定翼无人机的路径跟随控制

来自论文"Predictive Path-Following Control for Fixed-Wing UAVs Using the qLMPC Framework in the Presence of Wind Disturbances" 控制架构 采用的是 ULTRA-Extra无人机,相关参数如下: 这里用于guidance law的无人机运动学模型为&#…

跟着AI 学 AI, 开发一个ChatBot, 集成 Json 数据和查询

按照规律,使用AI生成一个架构图 直接上代码,为了方便学习,直接按照如下方式,复制到你的开发环境即可调试,运行代码。做学习参考。 代码注释多次说明这里,不在赘述。 "type": "carousel&qu…

校园交友app/校园资源共享小程序/校园圈子集合二手物品交易论坛、交友等综合型生活服务社交论坛

多客校园社交圈子系统搭建 校园交友多功能系统源码: 1、更改学校为独立的模块。整体UI改为绿色,青春色,更贴近校园风格。2、圈子归纳到学校去进行运营。每个学校可建立多个圈子。和其他学校圈子互不干扰。3、增加用户绑定学校,以后进入将默认…

游戏引擎学习第50天

仓库: https://gitee.com/mrxiao_com/2d_game Minkowski 这个算法有点懵逼 回顾 基本上,现在我们所处的阶段是,回顾最初的代码,我们正在讨论我们希望在引擎中实现的所有功能。我们正在做的版本是初步的、粗略的版本,涵盖我们认…

多模态-故障诊断 | 大核卷积开启视觉新纪元!

往期精彩内容: Python-凯斯西储大学(CWRU)轴承数据解读与分类处理 基于FFT CNN - BiGRU-Attention 时域、频域特征注意力融合的轴承故障识别模型-CSDN博客 基于FFT CNN - Transformer 时域、频域特征融合的轴承故障识别模型-CSDN博客 P…

30. Three.js案例-绘制并渲染圆弧

30. Three.js案例-绘制并渲染圆弧 实现效果 知识点 WebGLRenderer WebGLRenderer 是 Three.js 中用于渲染 3D 场景的核心类。它利用 WebGL 技术在浏览器中渲染 3D 图形。 构造器 new THREE.WebGLRenderer(parameters) 参数类型描述parametersObject可选参数对象&#xff…

【从零开始入门unity游戏开发之——C#篇03】变量和常量

文章目录 一、变量1、什么是变量?2、申明变量的固定写法3、变量的类型值和引用类型的区别无符号和有符号位——表示变量所占用的内存空间的大小范围——表示变量的取值范围取值范围和存储单位的关系为什么byte的范围是 0 到 255?为什么 sbyte 的范围是 -…

无人机推流直播平台EasyDSS视频技术如何助力冬季森林防火

冬季天干物燥,大风天气频繁,是森林火灾的高发期。相比传统的人力巡查,无人机具有更高的灵敏度和准确性,尤其在夜间或浓雾天气中,依然能有效地监测潜在火源。 无人机可以提供高空视角和实时图像传输,帮助巡…

Jenkins参数化构建详解(This project is parameterized)

本文详细介绍了Jenkins中不同类型的参数化构建方法,包括字符串、选项、多行文本、布尔值和git分支参数的配置,以及如何使用ActiveChoiceParameter实现动态获取参数选项。通过示例展示了传统方法和声明式pipeline的语法 文章目录 1. Jenkins的参数化构建1…

卓易通:鸿蒙Next系统的蜜糖还是毒药?

哈喽,我是老刘 最近很多人都在问鸿蒙next系统新上线的卓易通和出境易两款应用。 老刘分析了一下这个软件的一些细节,觉得还是蛮有意思的,我觉得可以从使用体验、底层原理和对鸿蒙生态的影响这三个角度来分析一下。 使用体验 性能 看到了一些测…

规则引擎drools(一)-技术要点

本文是规则引擎的第一篇,首先介绍规则引擎的技术要点,系列后续文章以本文为大纲,详细分析各个技术要点 1. 事实 事实是规则的依据,来源于业务,或是业务实体,或是多个业务实体的汇集; 2. 项目 描…

HarmonyOS学习 --- Mac电脑获取手机UDID

一,手机打开开发者选项 1,打开“设置 > 关于本机”,连续点击7次版本号,打开开发者选项。 2,打开“USB调试”。 二,配置环境变量 获取OpenHarmony SDK 安装路径 /Users/admin/Library/OpenHarmony/Sdk/10…

从 Router 到 Navigation:HarmonyOS 路由框架的全面升级与迁移指南

在本教程中,我们深入探讨了 Router 和 Navigation 在 HarmonyOS 中的用法差异及如何从 Router 切换到 Navigation 的方法。重点涵盖了页面跳转、转场动画、生命周期管理以及跨包路由的实现。 页面结构对比 Router 页面结构 每个页面需要使用 Entry 注解。 页面需要…

项目二十三:电阻测量(需要简单的外围检测电路,将电阻转换为电压)测量100,1k,4.7k,10k,20k的电阻阻值,由数码管显示。要求测试误差 <10%

资料查找: 01 方案选择 使用单片机测量电阻有多种方法,以下是一些常见的方法及其原理: 串联分压法(ADC) 原理:根据串联电路的分压原理,通过测量已知电阻和待测电阻上的电压,计算出…

C++ ——— const 修饰的对象如何正确调用函数

目录 前言 const 修饰的对象调用函数 const 修饰的对象如何正确调用函数 前言 在上一章完善了日期类函数 C ——— 完善日期类-CSDN博客 接下来要讲解的 const 修饰对象就拿日期类举例 const 修饰的对象调用函数 代码演示: const Data d1(2024, 12, 15);Dat…

nacos 配置动态更新-笔记

本文属于b站图灵课堂springcloud笔记系列。讲得好还不要钱,值得推荐。 官方解释:nacos配置中心实时刷新的原理是什么? | Nacos 官网 专家官方解答 : Nacos配置中心实时刷新的原理基于以下几个核心步骤与机制,这些信息…

第100+33步 ChatGPT学习:时间序列EMD-ARIMA-LSTM模型

基于Python 3.9版本演示 一、写在前面 上一节,我们学了经验模态分解(Empirical Mode Decomposition,EMD)。 如同结尾所说,“那么,做这些分解有什么作用呢?有大佬基于这些分解出来的序列分别作…