基于LRFMC模型的航空大数据客户价值分析

实验内容

会对数据进行预处理;了解K-Means聚类算法在客户价值分析时间中的作用;利用Pandas快速实现数据标准化以及用Scikit-Learn的聚类库实现K-Means聚类分析;会对数据进行可视化。

实验要求

(1)数据抽取

(2)数据探索性分析,对缺失值进行处理

(3)数据清洗

(4)属性规约

(5)数据变换

(6)数据标准化

(7)构建模型

(8)数据可视化

(9)对聚类结果进行分析

实验代码

###引入数据,查看基本数据情况
import pandas as pd #数据分析常用的库
import numpy as np
datafile = 'E:/desktopdocuments/air_data.csv' #文件路径
airline_data = pd.read_csv(datafile, encoding='utf-8') #先利用记事本将其转换为utf-8
print('数据形状:', airline_data.shape) #数据形状: (62988, 44)
print(airline_data.head())  #输出前五行

#查看空值的情况
look = airline_data.describe(percentiles=[], include='all').T #include all表示包含全部类型数据
look['null'] = len(airline_data) - look['count']
look = look[['null', 'max', 'min']]
look.columns = ['空值数', '最大值', '最小值']
print('查看空值的情况', look)

###客户特征分析
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = 'SimHei'  #设置正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  #设置正常显示负号

# 客户入会时间、入会人数统计
x1 = airline_data['FFP_DATE']
plt.figure(figsize=(6, 3))
plt.hist(sorted(x1), bins=10) #bins直方图的柱数 默认为10
plt.xlabel('入会年份')
plt.ylabel('入会人数')
plt.title('各年份客户入会人数直方图')
plt.show()

# 客户性别比例统计
x2 = airline_data['GENDER']
man = pd.value_counts(x2)['男']
woman = pd.value_counts(x2)['女']
plt.figure(figsize=(6, 3))
plt.pie([man, woman], labels=['男', '女'], autopct='%.1f%%')
plt.title('客户性别比例饼图')
plt.axis('equal')
plt.show()

# 各级别会员人数统计
x3 = airline_data['FFP_TIER']
h4 = pd.value_counts(x3)[4]
h5 = pd.value_counts(x3)[5]
h6 = pd.value_counts(x3)[6]
plt.figure(figsize=(6, 4))
plt.bar(x=range(3), height=[h4, h5, h6], width=0.4)
plt.xticks([0, 1, 2], ['4', '5', '6']) #给x轴的坐标添加对应的标签
plt.xlabel('会员等级')
plt.ylabel('会员人数')
plt.title('各级别会员人数条形图')
plt.show()

#客户乘机信息分布分析
x5 = airline_data[['LAST_TO_END', 'FLIGHT_COUNT', 'SEG_KM_SUM']]

u_time = x5['LAST_TO_END']
plt.figure(figsize=(6, 4))
plt.boxplot(u_time, labels=['时长'], patch_artist=True) #patch_artist填充箱体颜色
plt.grid(axis='y') #显示y坐标的底线
plt.title('客户最后乘机至观测窗口结束市场分布箱型图')
plt.show()

u_time = x5['FLIGHT_COUNT']
plt.figure(figsize=(6, 4))
plt.boxplot(u_time, labels=['飞行次数'], patch_artist=True) #patch_artist填充箱体颜色
plt.grid(axis='y') #显示y坐标的底线
plt.title('客户飞行次数分布箱型图')
plt.show()

u_time = x5['SEG_KM_SUM']
plt.figure(figsize=(6, 4))
plt.boxplot(u_time, labels=['飞行总公里数'], patch_artist=True) #patch_artist填充箱体颜色
plt.grid(axis='y') #显示y坐标的底线
plt.title('客户飞行总公里数分布箱型图')
plt.show()

#客户积分信息分布分析
x6 = airline_data[['EXCHANGE_COUNT', 'Points_Sum']]
u_count = x6['EXCHANGE_COUNT']
plt.figure(figsize=(6, 4))
plt.hist(sorted(u_count), bins=5)
plt.xlabel('兑换次数')
plt.ylabel('客户人数')
plt.title('客户积分兑换次数直方图')
plt.show()

u_points = x6['Points_Sum']
plt.figure(figsize=(6, 4))
plt.boxplot(u_points, labels=['总累计积分'], patch_artist=True)
plt.grid(axis='y')
plt.title('客户总累计积分分布箱型图')
plt.show()


###数据清洗
##去除票价为空的记录  可能是由于客户不存在乘机记录造成的
exp1 = airline_data["SUM_YR_1"].notnull() #保留票价1窗口中不为空的数据  551
exp2 = airline_data["SUM_YR_2"].notnull() #保留票价2窗口中不为空的数据  138
exp = exp1 & exp2 #合并,同时取非空数据
airline_notnull = airline_data.loc[exp, :] #数据定义为airline_notnull
print('删除缺失记录数据的形状为:', airline_notnull.shape) #(62299, 44)

##保留票价非零 或者 平均折扣率与总飞行公里数均为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)
airline = airline_notnull[index1 | index2 | index3]
print('删除异常记录后的数据形状:', airline.shape) #(62044, 44)


###建模LRFMC
# R最近一次消费时间与截止时间的间隔
# F消费次数
# M消费金额

## 选取需求特征
airline_selection = airline[["FFP_DATE", "LOAD_TIME", "LAST_TO_END", "FLIGHT_COUNT", "SEG_KM_SUM", "avg_discount"]]
# FFP_DATE、LOAD_TIME用于计算L:会员入会时间距观测窗口结束的月数

# LAST_TO_END用于表示R:客户最近一次乘坐飞机距离观测窗口结束的月数

# FLIGHT_COUNT用于表示F:客户在观测窗口内乘坐飞行次数

# SEG_KM_SUM用于表示M:客户在观测窗口内累计的飞行里程
# avg_discount用于表示C:客户在观测窗口内乘坐舱位对应的折扣系数的平均值

##构建L特征
L = pd.to_datetime(airline_selection["LOAD_TIME"]) - pd.to_datetime(airline_selection["FFP_DATE"])
print(L[:5]) #查看前五行 显示天数 2706 days
L = L.astype("str").str.split().str[0] #转化为字符串把前面的数字部分提取出来
L = L.astype("int")/30 #转化为月数 此处粗略/30
print(L[:5]) #查看前五行 显示月数

##合并特征
airline_features = pd.concat([L, airline_selection.iloc[:, 2:]], axis=1) #concat用于拼接 1左右拼接 0上下拼接
airline_features.columns = ['L', 'R', 'F', 'M', 'C']

print('构建的LRFMC特征前五行: \n', airline_features.head())
print('构建的LRFMC特征最大值: \n', airline_features.max())
print('构建的LRFMC特征最小值: \n', airline_features.min())


###数据标准化处理  取值范围差异较大。可能会导致某些特征在模型中占据过大的权重,从而影响结果的准确性
from sklearn.preprocessing import StandardScaler
airline_scale = StandardScaler().fit_transform(airline_features) #直接利用库的标准化方法 拟合+应用
print('标准化后五个特征为: \n', airline_scale) #标准化后的数据
# data = pd.DataFrame(airline_scale)
# data.to_excel('airline_scale.xlsx')


### 利用K-means聚类算法构建模型
# K-means聚类算法是一种基于质心的划分方法,输入聚类个数k,以及包含n个数据对象的数据库,输出满足误差平方和最小标准的k个聚类。
# 算法步骤如下:
# (1)从n个样本数据中随机选取k个对象作为初始的聚类中心。
# (2)分别计算每个样本到各个聚类质心的距离,将样本分配到距离最近的那个聚类中心类别中。
# (3)所有样本分配完成后,重新计算k个聚类的中心。
# (4)与前一次计算得到的k个聚类中心比较,如果聚类中心发生变化,转(2),否则转(5)。
# (5)当质心不发生变化时停止并输出聚类结果。
from sklearn.cluster import KMeans
k = 5 #确定聚类中心数(5行数据)
kmeans_model = KMeans(n_clusters=k, random_state=123) #确定聚类个数,确定随机准则(使每次生成的序列是一定的) 生成规则kmeans_model
fit_kmeans = kmeans_model.fit(airline_scale) #模型训练 fit_kmeans为训练结果
centers = kmeans_model.cluster_centers_ #查看聚类中心
print('聚类中心: \n', centers)

kmeans_model.labels_ #查看样本的类别标签
r1 = pd.Series(kmeans_model.labels_).value_counts()  #把每个类别进行频数统计,并转换为序列格式
print('最终每个类别的数目为:\n', r1)

#简单打印结果
s = pd.Series(['客户群1', '客户群2', '客户群3', '客户群4', '客户群5'], index=[0, 1, 2, 3, 4])
r1 = pd.Series(kmeans_model.labels_).value_counts()  #把每个类别进行频数统计,并转换为序列格式
r2 = pd.DataFrame(kmeans_model.cluster_centers_) #找出聚类中心
r = pd.concat([s, r1, r2], axis=1) #1为左右拼接,得到聚类中心对应的类别下的数目
r.columns = [u'聚类名称'] + [u'聚类个数'] + [u'L'] + [u'R'] + [u'F'] + [u'M'] + [u'C'] #重命名表头 u表示字符串类型
print(r)


### 可视化结果呈现 绘制雷达图
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = 'SimHei'  #设置正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  #设置正常显示负号

#设置基本参数
labels = np.array([u'ZL', u'ZR', u'ZF', u'ZM', u'ZC']) #标签 Z表示标准化后的数据
k = 5 #数据个数
plot_data = kmeans_model.cluster_centers_ #聚类中心 作为绘图数据
color = ['b', 'g', 'r', 'c', 'y'] #5类客户群对应不同颜色
angles = np.linspace(0, 2*np.pi, k, endpoint=False) #对旋转的角度进行等分 0-2pi 分成k等分 endpoint表示终止值是否被包含

#闭合
plot_data = np.concatenate((plot_data, plot_data[:, [0]]), axis=1) #数值闭合 将L值再拼接到C后面 concatenate也是拼接函数
# plot_data = np.array(plot_data.Se) #转换为序列
angles = np.concatenate((angles, [angles[0]])) #角度闭合
print('plot_data: \n', plot_data)
print('angles: \n', angles)

#绘图
fig = plt.figure(figsize=(9, 6), dpi=80) #设置画布fig,高宽,像素80
ax = fig.add_subplot(111, polar=True) #设置坐标为极坐标polar 111表示子图ax位置(其实就是一幅图)

#画若干个五边形框框 五边形范围必须包含所有数据范围
floor = np.floor(plot_data.min()) #下限小于最小值
ceil = np.ceil(plot_data.max()) #上限大于最大值
n = len(labels) #n = 5

for i in np.arange(floor, ceil + 0.5, 0.5):  #下限到上限,步长0.5  [floor,ceil]=[floor,ceil+0.5)
    ax.plot(angles, [i] * (n + 1), '-.', lw=0.5, color='black') #在ax子图上利用plot函数进行绘制 lw表示线粗
# plt.show()

#画不同客户群的分割线
for i in range(len(plot_data)): #len就是行数,遍历每一个客户群
    ax.plot(angles, plot_data[i], '-.', lw=2, color=color[i], label='客户群'+str(i+1)) #label加1是因为前面从0开始设置

ax.set_rgrids(np.arange(0, 2.5, 0.5))
ang = angles * 180 / np.pi #弧度转化为角度
ax.set_thetagrids(ang[:-1], labels) #设置显示的角度 set_thetagrids设置顺时针还是逆时针 :-1表示逆时针
plt.legend(loc='lower right', bbox_to_anchor=(1.3, 0.5)) #绘制图例,位置在画布外右下角 bbox_to_anchor(左右,上下)

ax.set_theta_zero_location('N') #设置极坐标起点为正北方(0°)
ax.spines['polar'].set_visible(False) #不显示极坐标的最外圈 不好看
ax.grid(False) #不显示默认分割线 不然有一堆圈
plt.savefig('航空客户价值评价雷达图.png')
plt.show()

注意

先打开数据集文件,查看是否存在文字乱码(建议用wps打开),如果不乱码,再执行代码看是否成功导入数据库。若报错显示无法解码,尝试使用以下办法,将其转化为utf-8编码:Windows10 Excel 如.csv文件编码问题转为 UTF-8 编码方法,解决中文乱码问题(如MongoDB导入 CSV 文件中文乱码问题)、解决科学计数显示问题_excel修改编码格式为utf8-CSDN博客

 参考资料

第七章 航空公司客户价值分析-1_哔哩哔哩_bilibili

第七章 航空公司客户价值分析-2_哔哩哔哩_bilibili

这两个视频思路和代码讲解得非常清楚,会解释每行代码都在干什么,为什么设这些参数等等。以上实验代码主要也是跟着视频写的。在其基础上可以根据个人需要拓展一些对于客户特征的统计分析。

实验报告

基于LRFMC模型的航空大数据客户价值分析资源-CSDN文库

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值