航空公司客户价值分析

  1. 描述性统计分析
    通过对原始数据观察发现数据中存在票价为空值的记录,同时存在票价最小值为0、折扣率最小值为0但总飞行公里数大于0的记录。票价为空值的数据可能是客户不存在乘机记录造成的。查找每列属性观测值中空值个数、最大值、最小值,代码如下:
    import pandas as pd import percentiles as percentiles datafile = 'D:/a/air_data.csv' resultfile = 'D:/a/explore.csv' date = pd.read_csv(datafile,encoding='utf-8') data = date.describe(percentiles = [],include = 'all').T explore = data[['null','max','min']] explore.columns = [u'空值数',u'最大值',u'最小值'] explore.to_csv(resultfile)
  2. 分布分析
    (1)客户基本信息分布分析
    选取客户基本信息中的入会时间、性别、会员卡级别和年龄段字段进行探索分析,探索客户的基本信息分布情况
    import pandas as pd from datetime import datetime datafile = 'D:/a/air_data.csv' resultfile = 'D:/a/explore.csv' data = pd.read_csv(datafile,encoding='utf-8') ffp = data['FFP_DATE'].apply(lambda x:datetime.strptime(x,'%Y/%m/%d')) ffp_year = ffp.map(lambda x:x.year) import matplotlib.pyplot as plt fig = plt.figure(figsize=(8,5)) plt.rcParams['font.sans-serif']='SimHei' plt.rcParams['axes.unicode_minus'] = False plt.hist(ffp_year,bins='auto',color='#0504aa') plt.xlabel('年份') plt.ylabel('入会人数') plt.title('学号:3130') plt.show() plt.close() male = pd.value_counts(data['GENDER'])['男'] female = pd.value_counts(data['GENDER'])['女'] fig = plt.figure(figsize=(8,5)) plt.pie ([male,female],labels=['男','女'],colors=['lightskyblue','lightcoral'],autopct='%1.1f%%') plt.title('会员性别比例(学号3130)') plt.show() plt.close lv_four = pd.value_counts(data['FFP_TIER'])[4] lv_five = pd.value_counts(data['FFP_TIER'])[5] lv_six = pd.value_counts(data['FFP_TIER'])[6] fig = plt.figure(figsize=(8,5)) plt.bar(x=range(3), height=[lv_four,lv_five,lv_six],width=0.4,alpha=0.8,color='skyblue') plt.xticks([index for index in range(3)],['4','5','6']) plt.xlabel('会员等级') plt.ylabel('会员人数') plt.title('会员各级别人数(学号3130)') plt.show() plt.close()
    得到如下各年级会员入会人数直方图:

会员性别比例饼图:

会员各级别人数条形图:

(2)客户乘机信息分布分析
选取最后一次乘机至结束的时长、客户乘机信息中的飞行次数、总飞行公里数进行探索分析,探索客户的乘机信息分布情况
绘制最后乘机至结束时长箱型图
age = data['AGE'].dropna() age = age.astype('int64') fig = plt.figure(figsize=(5,8)) plt.boxplot(age, patch_artist=True, labels=['会员年龄'], boxprops={'facecolor':'lightblue'}) plt.title('会员年龄分布箱型图(学号3130)') plt.grid(axis='y') plt.show() plt.close()
得到会员年龄分布箱型图

绘制客户飞行次数箱型图
lte = data['LAST_TO_END'] fc = data['FLIGHT_COUNT'] sks = data['SEG_KM_SUM'] fig = plt.figure(figsize=(5,8)) plt.boxplot(lte, patch_artist=True, labels=['时长'], boxprops={'facecolor':'lightblue'}) plt.title('会员最后乘机至结束时长分布箱型图(学号3130)') plt.grid(axis='y') plt.show() plt.close()
得到:

绘制客户总飞行公里数箱型图
fig = plt.figure(figsize=(5,8)) plt.boxplot(fc, patch_artist=True, labels=['飞行次数'], boxprops={'facecolor':'lightblue'}) plt.title('会员飞行次数分布箱型图(学号3130)') plt.grid(axis='y') plt.show() plt.close()
fig = plt.figure(figsize=(5,8)) plt.boxplot(sks, patch_artist=True, labels=['总飞行公里数'], boxprops={'facecolor':'lightblue'}) plt.title('会员最后乘机至结束时长分布箱型图(学号3130)') plt.grid(axis='y') plt.show() plt.close()
得到:

(3)
客户积分信息分布分析
选取积分兑换次数、总累计积分进行探索分析,探索客户的积分信息分布情况
ec = data['EXCHANGE_COUNT'] fig = plt.figure(figsize=(8,5)) plt.hist(ec,bins=5,color='#0504aa') plt.xlabel('兑换次数') plt.ylabel('会员人数') plt.title('会员兑换积分次数分布直方图(3130)') plt.show() plt.close()
得到客户积分兑换次数直方图和总累计积分分布箱型图

  1. 相关性分析
    客户信息属性之间存在相关性,选取入会时间、会员卡级别、客户年龄、飞行次数、总飞行公里数、最近一次乘机至结束时长、积分兑换次数、总累计积分属性,通过相关稀疏矩阵与热力图分析各属性的相关性
    data_corr = data[['FFP_TIER','FLIGHT_COUNT','LAST_TO_END','SEG_KM_SUM','EXCHANGE_COUNT','Points_Sum']] age1 = data['AGE'].fillna(0) data_corr['AGE'] = age1.astype('int64') data_corr['ffp_year'] = ffp_year data_corr = data_corr.corr(method='pearson') print('相关性矩阵:\n',data_corr)
    import seaborn as sns plt.subplots(figsize=(10,10)) sns.heatmap(data_corr,annot=True,vmax=1,square=True,cmap='Blues') plt.title('热力图(3130)') plt.show() plt.close()
    得到相关矩阵:

    热力图:

数据预处理

  1. 数据清洗
    使用pandas对满足清洗条件的数据进行丢弃,处理方法为满足清洗条件的一行数据全部丢弃。
    对空值和异常值进行清洗:
    import numpy as np import pandas as pd datafile = 'D:/a/air_data.csv' cleanedfile = 'D:/a/data_cleaned.csv'#保存 airline_data = pd.read_csv(datafile,encoding='utf-8') print('原始数据的形状:',airline_data.shape) airline_notnull = airline_data.loc[airline_data['SUM_YR_1'].notnull()&airline_data['SUM_YR_2'].notnull(),:] print('删除缺失记录后的数据形状:',airline_notnull.shape) 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) index4 = airline_notnull['AGE']>100 airline=airline_notnull[(index1 | index2)& index3 & ~index4] print('数据清洗后的形状:',airline.shape) airline.to_csv(cleanedfile)

  2. 属性归约
    删除与其不相关、弱相关或冗余的属性。
    airline = pd.read_csv(cleanedfile,encoding='utf-8') airline_selection = airline[['FFP_DATE','LOAD_TIME','LAST_TO_END','FLIGHT_COUNT','SEG_KM_SUM','avg_discount']] print('筛选的属性前5行为:\n',airline_selection.head())

  3. 数据交换
    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_features = pd.concat([L,airline_selection.iloc[:,2:]],axis=1) print('构建的LRFMC属性的前5行为:\n',airline_features.head()) from sklearn.preprocessing import StandardScaler data = StandardScaler().fit_transform(airline_features) np.savez('D:/python123/airline_scale.npz',data) print('标准化后LRFMC的5个属性为:\n',data[:5,:])

  4. 客户聚类
    from sklearn.cluster import KMeans airline_scale = np.load('D:/python123/airline_scale.npz')['arr_0'] k = 5 kmeans_model = KMeans(n_clusters=k,n_init=4,random_state=123) fit_kmeans = kmeans_model.fit(airline_scale) kmeans_cc = kmeans_model.cluster_centers_ print('各类聚类中心为:\n',kmeans_cc) kmeans_labels = kmeans_model.labels_ print('各样本的类别标签为:\n',kmeans_labels) r1 = pd.Series(kmeans_model.labels_).value_counts() print('最终每个类别的数目为:\n',r1) cluster_center = pd.DataFrame(kmeans_model.cluster_centers_,\ columns=['ZL','ZR','ZF','ZM','ZC']) cluster_center.index = pd.DataFrame(kmeans_model.labels_).\ drop_duplicates().iloc[:,0] print(cluster_center)

  5. 客户价值分析
    绘制客户分群雷达图
    `%matplotlib inline
    labels = ['ZL','ZR','ZF','ZM','ZC']
    legen = ['客户群' + str(i + 1) for i in cluster_center.index]
    lstype = ['-','--',(0,(3,5,1,5,1,5)),':','-.']
    kinds = list(cluster_center.iloc[:,0])
    cluster_center = pd.concat([cluster_center,cluster_center[['ZL']]],axis=1)
    centers = np.array(cluster_center.iloc[:,0:])

n = len(labels)
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)
for i in range(len(kinds)):
ax.plot(angle,centers[i],linestyle=lstype[i],linewidth=2,label=kinds[i])
ax.set_thetagrids(angle[:-1] * 180 / np.pi,labels)
plt.title('客户特征分析雷达图3130')
plt.legend(legen)
plt.show()
plt.close()`

第二部分:电信客户流失分析预测

  1. 读取并简单分析数据
    plt.rc("font",family="SimHei",size="12") #解决中文无法显示的问题 data = pd.read_csv('D:/JupyterLab-Portable-3.1.0-3.9/新建文件夹/WA_Fn-UseC_-Telco-Customer-Churn.csv') # 导入数据 data.shape # 查看数据大小 (7043, 21) data.head()

5 rows × 21 columns data.describe() #描述性统计信息

  1. 客户流失数据分析
    data['Churn'].value_counts() #查找缺失值 No 5174 Yes 1869 Name: Churn, dtype: int64 数据集中有5174名用户没流失,有1869名客户流失,数据集不均衡。 data.dtypes #查看数据类型

TotalCharges表示总费用,这里为对象类型,需要转换为float类型 data['TotalCharges']=data['TotalCharges'].apply(pd.to_numeric, errors="ignore") data['TotalCharges'].describe() 数据归一化处理 对Churn列中的YES和No分别用1和0替换,方便后续处理 data['Churn'].replace(to_replace='Yes',value=1,inplace=True) data['Churn'].replace(to_replace='No',value=0,inplace=True) data['Churn'].describe()

data.info() #数据预览

  1. 绘制电信客户性别饼图和绘制客户流失情况饼图
    plt.rcParams['font.sans-serif']='SimHei' plt.rcParams['axes.unicode_minus']='False' 提取会员不同性别人数 male=pd.value_counts(data['gender'])['Female'] female=pd.value_counts(data['gender'])['Male'] 绘制会员性别比例饼图 fig=plt.figure(figsize=(10,6)) plt.pie([male,female],labels=['男','女'],colors=['lightskyblue','lightcoral'],autopct='%1.1f%%') plt.title('电信用户性别比例3130',fontsize=15) plt.show() plt.close() churnvalue=data[ "Churn" ].value_counts() labels=data["Churn"].value_counts().index plt.figure(figsize=(6,6)) plt.pie(churnvalue,labels=labels,colors=["blue","yellow"],explode=(0.1,0),autopct='%1.1f', shadow=True) plt.title('客户流失情况饼图3125',fontsize=15) plt.show()

  2. 客户流失影响直方图
    性别、老年人、配偶、亲属对流客户流失率的影响 plt.figure(figsize=(10,10)) plt.subplot(2,2,1) gender=sns.countplot(x='gender',hue='Churn',data=data,palette='Set2') #palette参数表示设置颜色,设置为主颜色paste12 plt.xlabel('性别') plt.title('不同性别客户流失直方图3130',fontsize=15) plt.subplot(2,2,2) seniorcitizen=sns.countplot(x='SeniorCitizen',hue='Churn',data=data,palette='Set2') plt.xlabel('老年人') plt.title('老年人客户流失直方图3130',fontsize=15) plt.subplot(2,2,3) partner=sns.countplot(x='Partner',hue='Churn',data=data,palette='Set2') plt.xlabel('配偶') plt.title('是否有配偶客户流失直方图3130',fontsize=15) plt.subplot(2,2,4) dependents=sns.countplot(x='Dependents',hue='Churn',data=data,palette='Set2') plt.xlabel('亲属') plt.title('亲属客户流失直方图3125',fontsize=15) plt.show()

可以看出,男性与女性用户之间的流失情况基本没有差异,而在老年用户中流失占比明显比非老年用户更高,
在所有数据中未婚与已婚人数基本持平,但未婚中流失人数比已婚中的流失人数高出了快一倍,
从经济独立情况来看,经济未独立的用户流失率要远远高于经济独立的用户。

  1. 特征值
    提取特征 charges=data.iloc[:,1:20] 对特征进行编码 corrdf=charges.apply(lambda x:pd.factorize(x)[0]) corrdf.head()

构建相关矩阵
corr = corrdf.corr() corr


6. 热力图
''' heatmap 使用热力图展示系数矩阵情况 linewidths 热力图矩阵之间的间隔大小 annot 设定是否显示每个色块系数值 ''' plt.figure(figsize=(30,20)) ax=sns.heatmap(corr,xticklabels=corr.columns,yticklabels=corr.columns,linewidths=0.2,cmap='YlGnBu',annot=True) plt.title('相关系数热力图3130',fontsize=15) plt.show()

posted @   仰望半月的夜  阅读(224)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示