本文共 8656 字,大约阅读时间需要 28 分钟。
背景与挖掘目标
详情数据见数据集内容中的air_data.csv和客户信息属性说明。
import pandas as pd datafile= r'/home/kesci/input/date27730/air_data.csv' #航空原始数据,第一行为属性标签 resultfile = r'/home/kesci/work/test.xls' #数据探索结果表 data = pd.read_csv(datafile, encoding = 'utf-8') #读取原始数据,指定UTF-8编码(需要用文本编辑器将数据装换为UTF-8编码) explore = data.describe(percentiles = [], include = 'all').T #包括对数据的基本描述,percentiles参数是指定计算多少的分位数表(如1/4分位数、中位数等);T是转置,转置后更方便查阅 print(explore) explore['null'] = len(data)-explore['count'] #describe()函数自动计算非空值数,需要手动计算空值数 explore = explore[['null', 'max', 'min']] explore.columns = [u'空值数', u'最大值', u'最小值'] #表头重命名 print('-----------------------------------------------------------------以下是处理后数据') print(explore) '''这里只选取部分探索结果。 describe()函数自动计算的字段有count(非空值数)、unique(唯一值数)、top(频数最高者)、freq(最高频数)、mean(平均值)、std(方差)、min(最小值)、50%(中位数)、max(最大值)'''
-----------------------------------------------------------------以下是处理前数据 count unique top freq mean std MEMBER_NO 62988 NaN NaN NaN 31494.5 18183.2 FFP_DATE 62988 3068 2011/01/13 184 NaN NaN FIRST_FLIGHT_DATE 62988 3406 2013/02/16 96 NaN NaN GENDER 62985 2 男 48134 NaN NaN FFP_TIER 62988 NaN NaN NaN 4.10216 0.373856 WORK_CITY 60719 3310 广州 9385 NaN NaN WORK_PROVINCE 59740 1185 广东 17507 NaN NaN WORK_COUNTRY 62962 118 CN 57748 NaN NaN ...
-----------------------------------------------------------------以下是处理后数据 空值数 最大值 最小值 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 ...
import pandas as pd datafile= '/home/kesci/input/date27730/air_data.csv' #航空原始数据,第一行为属性标签 cleanedfile = '' #数据清洗后保存的文件 data = pd.read_csv(datafile,encoding='utf-8') #读取原始数据,指定UTF-8编码(需要用文本编辑器将数据装换为UTF-8编码) data = data[data['SUM_YR_1'].notnull() & data['SUM_YR_2'].notnull()] #票价非空值才保留 #只保留票价非零的,或者平均折扣率与总飞行公里数同时为0的记录。 index1 = data['SUM_YR_1'] != 0 index2 = data['SUM_YR_2'] != 0 index3 = (data['SEG_KM_SUM'] == 0) & (data['avg_discount'] == 0) #该规则是“与”,书上给的代码无法正常运行,修改'*'为'&' data = data[index1 | index2 | index3] #该规则是“或” print(data) # data.to_excel(cleanedfile) #导出结果
————————————————————以下是处理后数据———————— MEMBER_NO FFP_DATE FIRST_FLIGHT_DATE GENDER FFP_TIER \ 0 54993 2006/11/02 2008/12/24 男 6 1 28065 2007/02/19 2007/08/03 男 6 2 55106 2007/02/01 2007/08/30 男 6 3 21189 2008/08/22 2008/08/23 男 5 4 39546 2009/04/10 2009/04/15 男 6 5 56972 2008/02/10 2009/09/29 男 6 6 44924 2006/03/22 2006/03/29 男 6 7 22631 2010/04/09 2010/04/09 女 6 8 32197 2011/06/07 2011/07/01 男 5 9 31645 2010/07/05 2010/07/05 女 6
def reduction_data(data): data = data[['LOAD_TIME', 'FFP_DATE', 'LAST_TO_END', 'FLIGHT_COUNT', 'SEG_KM_SUM', 'avg_discount']] # data['L']=pd.datetime(data['LOAD_TIME'])-pd.datetime(data['FFP_DATE']) # data['L']=int(((parse(data['LOAD_TIME'])-parse(data['FFP_ADTE'])).days)/30) d_ffp = pd.to_datetime(data['FFP_DATE']) d_load = pd.to_datetime(data['LOAD_TIME']) res = d_load - d_ffp data2=data.copy() data2['L'] = res.map(lambda x: x / np.timedelta64(30 * 24 * 60, 'm')) data2['R'] = data['LAST_TO_END'] data2['F'] = data['FLIGHT_COUNT'] data2['M'] = data['SEG_KM_SUM'] data2['C'] = data['avg_discount'] data3 = data2[['L', 'R', 'F', 'M', 'C']] return data3 data3=reduction_data(data) print(data3)
————————————以下是以上代码处理后数据———————————— L R F M C 0 90.200000 1 210 580717 0.961639 1 86.566667 7 140 293678 1.252314 2 87.166667 11 135 283712 1.254676 3 68.233333 97 23 281336 1.090870 4 60.533333 5 152 309928 0.970658 5 74.700000 79 92 294585 0.967692 6 97.700000 1 101 287042 0.965347 7 48.400000 3 73 287230 0.962070 8 34.266667 6 56 321489 0.828478
def zscore_data(data): data = (data - data.mean(axis=0)) / data.std(axis=0) data.columns = ['Z' + i for i in data.columns] return data data4 = zscore_data(data3) data4
————————————以下是以上代码处理后数据———————————— ZL ZR ZF ZM ZC 0 1.435707 -0.944948 14.034016 26.761154 1.295540 1 1.307152 -0.911894 9.073213 13.126864 2.868176 2 1.328381 -0.889859 8.718869 12.653481 2.880950 3 0.658476 -0.416098 0.781585 12.540622 1.994714 4 0.386032 -0.922912 9.923636 13.898736 1.344335 5 0.887281 -0.515257 5.671519 13.169947 1.328291
利用K-Means聚类算法对客户数据进行客户分群,聚成五类(根据业务理解和需要,分析与讨论后,确定客户类别数量)。
代码如下:
inputfile = r'/home/kesci/input/date27730/zscoreddata.xls' #待聚类的数据文件 k = 5 #需要进行的聚类类别数 #读取数据并进行聚类分析 data = pd.read_excel(inputfile) #读取数据 #调用k-means算法,进行聚类分析 kmodel = KMeans(n_clusters = k, n_jobs = 4) #n_jobs是并行数,一般等于CPU数较好 kmodel.fit(data) #训练模型 r1 = pd.Series(kmodel.labels_).value_counts() r2 = pd.DataFrame(kmodel.cluster_centers_) r = pd.concat([r2, r1], axis=1) r.columns = list(data.columns) + ['类别数目'] # print(r) # r.to_excel(classoutfile,index=False) r = pd.concat([data, pd.Series(kmodel.labels_, index=data.index)], axis=1) r.columns = list(data.columns) + ['聚类类别'] print(kmodel.cluster_centers_) print(kmodel.labels_) r
[[-0.70078704 -0.41513666 -0.1607619 -0.16049688 -0.25665898] [-0.31411607 1.68662534 -0.57386257 -0.53661609 -0.17243195] [ 0.48347647 -0.79941777 2.48236495 2.42356419 0.30943042] [ 1.16033496 -0.37744106 -0.0870043 -0.09499704 -0.15836889] [ 0.05165705 -0.00258448 -0.23089344 -0.23513858 2.17775056]] [3 3 3 ... 3 3 3] ZL ZR ZF ZM ZC 聚类类别 0 1.689882 0.140299 -0.635788 0.068794 -0.337186 3 1 1.689882 -0.322442 0.852453 0.843848 -0.553613 3 2 1.681743 -0.487707 -0.210576 0.158569 -1.094680 3 3 1.534185 -0.785184 0.002030 0.273091 -1.148787 3 4 0.890167 -0.426559 -0.635788 -0.685170 1.231909 4 5 -0.232618 -0.690983 -0.635788 -0.603898 -0.391293 0 6 -0.496949 1.996225 -0.706656 -0.661752 -1.311107 1
就剩下最后一步,画图:
def density_plot(data): plt.rcParams['font.sans-serif']=['SimHei'] plt.rcParams['axes.unicode_minus']=False p=data.plot(kind='kde',linewidth=2,subplots=True,sharex=False) [p[i].set_ylabel('密度') for i in range(5)] [p[i].set_title('客户群%d' %i) for i in range(5)] plt.legend() plt.show() return plt density_plot(data4)
clu = kmodel.cluster_centers_
x = [1,2,3,4,5]
colors = ['red','green','yellow','blue','black']
for i in range(5):
plt.plot(x,clu[i],label='clustre '+str(i),linewidth=6-i,color=colors[i],marker='o')
plt.xlabel('L R F M C')
plt.ylabel('values')
plt.show()
客户关系长度L,消费时间间隔R,消费频率F,飞行里程M,折扣系数的平均值C。
横坐标上,总共有五个节点,按顺序对应LRFMC。
对应节点上的客户群的属性值,代表该客户群的该属性的程度。
我们重点关注的是L,F,M,从图中可以看到:
4. 交叉销售
通过发行联名卡与非航空公司各做,使得企业在其他企业消费过程中获得本公司的积分,增强与本公司联系,提高忠诚度。
5. 管理模式
本文,结合航空公司客户价值案例的分析,重点介绍了数据挖掘算法中K-Means聚类算法的应用。 针对,传统RFM模型的不足,结合案例进行改造,设定了五个指标的LRFMC模型。最后通过聚类的结果,选出客户价值排行,并且制定相应策略。
转载地址:http://uamjm.baihongyu.com/