本文是基于《Python数据分析与挖掘实战》的实战部分的第七章的数据——《航空公司客户价值分析》做的分析。

旨在补充原文中的细节代码,并给出文中涉及到的内容的完整代码。

1)在数据预处理部分增加了属性规约、数据变换的代码

2)在模型构建的部分增加了一个画出雷达图的函数代码

1 背景与目标分析

此项目旨在根据航空公司提供的数据,对其客户进行分类,并且比较不同类别客户的价值,为能够更好的为客户提供个性化服务做参考。

2 数据探索性分析

2.1 数据质量分析

#对数据进行基本的探索
#返回缺失值个数以及最大最小值
import pandas as pddatafile = 'air_data.csv'#航空公司原始数据,第一行是属性名
result = 'explore.xlsx'data = pd.read_csv(datafile, encoding='utf-8')
explore = data.describe( percentiles = [],include = 'all').Texplore['null'] = len(data)-explore['count']explore1 = explore[['null','max','min']]
explore1.columns = [u'空值数',u'最大值',u'最小值']#重命名列名explore1.to_excel(result)

探索结果:

3 数据预处理

3.1 数据清洗

datafile = 'air_data.csv'#航空公司原始数据,第一行是属性名
data = pd.read_csv(datafile, encoding='utf-8')
# 丢弃掉票价为0的记录;丢弃票价为0、平均折扣不为零、总飞行公里大于0的记录cleanedfile = 'cleaned.xlsx'data1 = data[data['SUM_YR_1'].notnull()*data['SUM_YR_2'].notnull()] #票价非空值才保留,去掉空值#只保留票价非零的,或者平均折扣率与总飞行公里数同时为零的记录
index1 = data1['SUM_YR_1'] != 0
index2 = data1['SUM_YR_2'] != 0
index3 = (data1['SEG_KM_SUM'] == 0) & (data1['avg_discount'] == 0)
data1 = data1[index1 | index2 | index3] #或关系data1.to_excel(cleanedfile)
data2 = data1[['LOAD_TIME','FFP_DATE','LAST_TO_END','FLIGHT_COUNT','SEG_KM_SUM','avg_discount']]
data2.to_excel('datadecrese.xlsx')

3.2 数据规约及属性构造

import numpy as np
data = pd.read_excel('datadecrese.xlsx')data['L1'] = pd.to_datetime(data['LOAD_TIME']) - pd.to_datetime(data['FFP_DATE'])# 以纳秒为单位
# data['L3'] = data['L1'].astype('int64')/10**10/8640/30 # 此方法假定每个月是30天,这方法不准确
data['L3'] = data['L1']/np.timedelta64(1, 'M') # 将间隔时间转成月份为单位,注意,此处必须加一个中间变量 (****)
# 将表中的浮点类型保留至小数点后四为
# f = lambda x:'%.2f' % x
# data[['L3']]  = data[['L3']].applymap(f) # or data['L3'] = data['L3'].apply(f)
# data[['L3']]  = data[['L3']].astype('float64')# 注意:使用apply或applymap后,数据类型变成Object,若后续有需要需要在此进行类型转换data["L3"] = data["L3"].round(2) # 等价于上面三句话,数据类型不变
data['LAST_TO_END'] = (data['LAST_TO_END']/30).round(2) # 此方法假定每个月是30天,这方法不够准确
data['avg_discount'] = data['avg_discount'].round(2)data.drop('L1', axis=1, inplace =True) # 删除中间变量
data.drop(data.columns[:3], axis=1, inplace =True) # 去掉不需要的u'LOAD_TIME', u'FFP_DATE'
data.rename(columns={'LAST_TO_END':'R','FLIGHT_COUNT':'F','SEG_KM_SUM':'M','avg_discount':'C','L3':'L'},inplace=True)
data.to_excel('sxgz.xlsx',index=False)

def f(x):return Series([x.min(),x.max()], index=['min','max'])
d = data.apply(f)
d.to_excel('summary_data.xlsx')

3.3 数据标准化

# 3> 数据标准化
#标准差标准化
d1 = pd.read_excel('sxgz.xlsx')
d1=d1.astype('float64')
d2 = (d1-d1.mean())/d1.std()
d1 =d2.iloc[:,[4,0,1,2,3]]
d1.columns = ['Z'+i for i in d1.columns]#表头重命名
d1.to_excel('sjbzh.xlsx',index=False)

4.模型建立

4.1 k-means

#使用K-means聚类算法分类并分析每类的特征
import pandas as pd
from pandas import DataFrame,Series
from sklearn.cluster import KMeans #导入K均值聚类算法
k = 5 # 聚为5类
d3 = pd.read_excel('sjbzh.xlsx')#调用k-means算法,进行聚类分析
kmodel = KMeans(n_clusters=k, n_jobs=4)# n_job是并行数,一般等于CPU数较好
kmodel.fit(d3)labels = kmodel.labels_#查看各样本类别
demo = DataFrame(labels,columns=['numbers'])
demo1= DataFrame(kmodel.cluster_centers_, columns=d3.columns) # 保存聚类中心
demo2= demo['numbers'].value_counts() # 确定各个类的数目
demo2

demo4 = pd.concat([demo2,demo1],axis=1)
demo4.index.name='labels'
demo4.to_excel('kmeansresults.xlsx')

4.2 雷达图

#画雷达图 客户群特征分析图
subset = demo1.copy()
subset = subset.round(3)
subset.to_excel('testradar.xlsx')
data = subset.as_matrix() # 将表格数据转成数组from radar1 import drawRader  # 从已经编写好的画雷达图的函数中导入
title = 'RadarPicture'
rgrids = [0.5, 1, 1.5, 2, 2.5]
itemnames = ['ZL','ZR','ZF','ZM','ZC']
labels = list('abcde')
drawRader(itemnames=itemnames,data=data,title=title,labels=labels, saveas = '2.jpg',rgrids=rgrids)


radar1:

import numpy as npimport matplotlib.pyplot as plt
from matplotlib.path import Path
from matplotlib.spines import Spine
from matplotlib.projections.polar import PolarAxes
from matplotlib.projections import register_projectiondef radar_factory(num_vars, frame='circle'):"""Create a radar chart with `num_vars` axes.This function creates a RadarAxes projection and registers it.Parameters----------num_vars : intNumber of variables for radar chart.frame : {'circle' | 'polygon'}Shape of frame surrounding axes."""# calculate evenly-spaced axis anglestheta = np.linspace(0, 2*np.pi, num_vars, endpoint=False)# rotate theta such that the first axis is at the toptheta += np.pi/2def draw_poly_patch(self):verts = unit_poly_verts(theta)return plt.Polygon(verts, closed=True, edgecolor='k')def draw_circle_patch(self):# unit circle centered on (0.5, 0.5)return plt.Circle((0.5, 0.5), 0.5)patch_dict = {'polygon': draw_poly_patch, 'circle': draw_circle_patch}if frame not in patch_dict:raise ValueError('unknown value for `frame`: %s' % frame)class RadarAxes(PolarAxes):name = 'radar'# use 1 line segment to connect specified pointsRESOLUTION = 1# define draw_frame methoddraw_patch = patch_dict[frame]def fill(self, *args, **kwargs):"""Override fill so that line is closed by default"""closed = kwargs.pop('closed', True)return super(RadarAxes, self).fill(closed=closed, *args, **kwargs)def plot(self, *args, **kwargs):"""Override plot so that line is closed by default"""lines = super(RadarAxes, self).plot(*args, **kwargs)for line in lines:self._close_line(line)def _close_line(self, line):x, y = line.get_data()# FIXME: markers at x[0], y[0] get doubled-upif x[0] != x[-1]:x = np.concatenate((x, [x[0]]))y = np.concatenate((y, [y[0]]))line.set_data(x, y)def set_varlabels(self, labels):self.set_thetagrids(np.degrees(theta), labels)def _gen_axes_patch(self):return self.draw_patch()def _gen_axes_spines(self):if frame == 'circle':return PolarAxes._gen_axes_spines(self)# The following is a hack to get the spines (i.e. the axes frame)# to draw correctly for a polygon frame.# spine_type must be 'left', 'right', 'top', 'bottom', or `circle`.spine_type = 'circle'verts = unit_poly_verts(theta)# close off polygon by repeating first vertexverts.append(verts[0])path = Path(verts)spine = Spine(self, spine_type, path)spine.set_transform(self.transAxes)return {'polar': spine}register_projection(RadarAxes)return thetadef unit_poly_verts(theta):"""Return vertices of polygon for subplot axes.This polygon is circumscribed by a unit circle centered at (0.5, 0.5)"""x0, y0, r = [0.5] * 3verts = [(r*np.cos(t) + x0, r*np.sin(t) + y0) for t in theta]return vertsdef example_data():# The following data is from the Denver Aerodata1 = [['ZL','ZR','ZF','ZM','ZC'],('R',[[0.063,-0.0040000000000000001, -0.22600000000000001,-0.22900000000000001,2.1949999999999998],[1.161, -0.377, -0.086999999999999994, -0.095000000000000001, -0.159],[0.48299999999999998,-0.79900000000000004,2.4830000000000001,2.4249999999999998,0.308],[-0.314,1.6859999999999999,-0.57399999999999995,-0.53700000000000003,-0.17299999999999999],[-0.69999999999999996, -0.41499999999999998, -0.161, -0.161, -0.253]])]return data1if __name__ == '__main__':N = 5theta = radar_factory(N, frame='polygon')data = example_data()spoke_labels = data.pop(0)fig, axes = plt.subplots(figsize=(9, 9), nrows=2, ncols=2,subplot_kw=dict(projection='radar'))fig.subplots_adjust(wspace=0.25, hspace=0.20, top=0.85, bottom=0.05)colors = ['b', 'r', 'g', 'm', 'y']# Plot the four cases from the example data on separate axesfor ax, (title, case_data) in zip(axes.flatten(), data):ax.set_rgrids([0.5, 1, 1.5,2,2.5])ax.set_title(title, weight='bold', size='medium', position=(0.5, 1.1),horizontalalignment='center', verticalalignment='center')for d, color in zip(case_data, colors):ax.plot(theta, d, color=color)ax.fill(theta, d, facecolor=color, alpha=0.25)ax.set_varlabels(spoke_labels)# add legend relative to top-left plotax = axes[0, 0]plt.rcParams['font.sans-serif'] = ['SimHei']plt.rcParams['axes.unicode_minus'] = Falselabels = (list('abcde'))legend = ax.legend(labels, loc=(0.9, .95),labelspacing=0.1, fontsize='small')fig.text(0.5, 0.965, '5-Factor Solution Profiles Across Four Scenarios',horizontalalignment='center', color='black', weight='bold',size='large')plt.show()

虽然以前刚开始接触数据分析做过一遍这个项目,第二遍浏览下来感觉比第一次轻松许多。
参考大佬的文章:https://blog.csdn.net/u012063773/article/details/79297670

《Python数据分析与挖掘实战》第7章——航空公司客户价值分析(kmeans)相关推荐

  1. python数据分析与挖掘实战-第六章拓展偷漏税用户识别

    第六章分别使用了LM神经网络和CART 决策树构建了 电力窃漏电用户自动识别模型,章末提出了拓展思考–偷漏税用户识别. 第六章及拓展思考完整代码 https://github.com/dengsiyi ...

  2. Python数据分析与挖掘实战——第三章

    第三章 数据探索 目录 第三章 数据探索 一.数据探索 二.数据质量分析 1. 主要任务: 2. 缺失值分析 3. 异常值分析 4. 一致性分析 三.数据特征分析 1. 分布分析 2. 对比分析 3. ...

  3. 《Python数据分析与挖掘实战》一第1章 数据挖掘基础1.1 某知名连锁餐饮企业的困惑...

    本节书摘来自华章出版社<Python数据分析与挖掘实战>一书中的第1章,第1.1节,作者 张良均 王路 谭立云 苏剑林,更多章节内容可以访问云栖社区"华章计算机"公众号 ...

  4. 《Python数据分析与挖掘实战》第7章-聚类+绘制雷达图

    本文是基于<Python数据分析与挖掘实战>的第七章的数据--<航空公司客户价值分析>做的分析对部分代码,做出补充,对原文中的雷达图进行了实现. 1. 背景与目标分析 此项目旨 ...

  5. 《Python数据分析与挖掘实战》第10章(下)——DNN2 筛选得“候选洗浴事件”3 构建模型

    本文是基于<Python数据分析与挖掘实战>的实战部分的第10章的数据--<家用电器用户行为分析与事件识别> 做的分析. 接着前一篇文章的内容,本篇博文重点是处理用水事件中的属 ...

  6. 《Python数据分析与挖掘实战》第11章——应用系统负载分析与磁盘容量预测(时间序列)

    文章目录 1.背景与目标分析 2.2 数据探索 2.1 查看数据信息 2.2 数据平稳性分析 3 数据预处理 3.1 数据清洗 3.2 数据变换--属性构造 4 模型构建 4.1 确定模型-- ARM ...

  7. 《Python数据分析与挖掘实战》第14章——基于基站定位数据的商圈分析(层次聚类)

    本文是基于<Python数据分析与挖掘实战>的实战第14章<基于基站定位数据的商圈分析>做的分析. 1 挖掘背景及目标 从某通信运营商提供的特定接口解析得到用户的定位数据.利用 ...

  8. 《Python数据分析与挖掘实战》第12章(中)——协同推荐

    本文是基于<Python数据分析与挖掘实战>的实战部分的第12章的数据--<电子商务网站用户行为分析及服务推荐>做的分析. 由于此章内容很多,因此,分为三个部分进行分享--数据 ...

  9. 《Python数据分析与挖掘实战》第15章 ——电商产品评论数据情感分析(LED)

    文章目录 1.挖掘背景与目标 2.2 数据探索与预处理 2.1 数据筛选 2.2 数据去重 2.3 删除前缀评分 2.4 jieba分词 3 基于LDA 模型的主题分析 4.权重 5.如何在主题空间比 ...

最新文章

  1. HttpRequest 与HttpWebRequest 有什么区别
  2. 支持向量机—核函数源码分析(2)
  3. LVM的创建与快照和SSM存储管理器的使用
  4. 网易云信-新增自定义消息(iOS版)
  5. Maven私服Nexus搭建
  6. Spring 源码解析 -- SpringWeb过滤器Filter解析
  7. OSS内文件如何设置为无时间限制的下载链接
  8. ImmunityDebugger 学习
  9. oracle空值问题
  10. 卸载symantec endpoint protection
  11. 推荐几款好用的文本编辑器
  12. 短视频APP测试要点
  13. 视频教程-思科CCNP专题系列⑤:路由策略路由-思科认证
  14. SimpleDateFormat 使用TimeZone
  15. 基于深度学习的色情视频鉴定
  16. 运动数据采集,医疗数据采集
  17. Python相关文章索引(13)
  18. 雷神笔记本关闭触摸板
  19. Python实现“已知三角形两个直角边,求斜边”
  20. 社区说|浅谈量子计算机和 Cirq

热门文章

  1. Cent OS 8解决开机网卡未启动
  2. (附源码)计算机毕业设计SSM中小型医院综合管理系统
  3. 【KNN以及KD树】
  4. 【Scheme】Scheme 编程学习 (二) —— 基础
  5. 【SICP练习】98 练习2.73
  6. GreenDao之一基本使用(ToOne,ToMany都附源代码)
  7. Ant Design 圣诞节的踩蛋!
  8. linux反汇编工具包,动态反汇编工具(HDasm64)
  9. 《人力资源数字化转型的Tech Leadership模型》主题分享
  10. 3D建模自学能学会吗?