聚类分析常用于用户细分、市场细分等领域。
现有一份航空公司的客户数据,具体信息如下:

数据源链接:https://pan.baidu.com/s/1UyNSCmpqai-Jw4Xdj4H2ZQ
一、数据导入
import pandas as pd
#首先导入数据,注意文件路径为反斜杠
data=pd.read_csv('C:/Users/86138/Desktop/Python数据分析与挖掘实战/chapter7/demo/data/air_data.csv')
#查看数据的一些基本信息
print(data.head())
print(data.info())
print(data.describe())
二、数据处理
第1、选取聚类字段
客户细分主要有R(recency,时间间隔),F(frequency,频率或次数),M(monetary,金额)三个指标,即RFM,我们依据这三个数据进行聚类。
1、时间间隔
用当前时间减去最后一次乘机时间,得到时间间隔。
#计算距今天数
from datetime import datetime
data.replace('2014/2/29 0:00:00','2014/3/1',inplace=True)
data['LAST_FLIGHT_DATE']=pd.to_datetime(data['LAST_FLIGHT_DATE'])
data['DATEDIFF']=datetime.now()-data['LAST_FLIGHT_DATE']
data['DATEDIFF']=data['DATEDIFF'].dt.days #提取天数
因为之前运行pd.to_datetime时报错(时间列里2014/2/29 0:00:00这个时间错误,2014年并不是闰年2月并没有29天),所以把2014/2/29 0:00:00修改为2014/3/1。
运行pd.to_datetime报错可调用参数errors='ignore'或errors='coerce',ignore为直接忽略错误,coerce将非日期的字符串记为nat(not a time)。
2、乘机次数
F为FLIGHT_COUNT,乘机次数。
3、金额总额
#计算金额总额
data['SUM_YR']=data['SUM_YR_1']+data['SUM_YR_2']
第2、缺失值处理
在进行数据标准化之前进行缺失值处理,过滤掉那三个数据中的缺失值。
#缺失值处理
print(data['DATEDIFF'].isnull().sum())
print(data['FLIGHT_COUNT'].isnull().sum())
print(data['SUM_YR'].isnull().sum())
data=data[data['SUM_YR'].notnull()] #筛选出非空值
运行发现SUM_YR列有689个缺失值,把它舍弃。
第3、数据标准化
确定聚类字段后,发现这三种数据不是同种单位,所以需要将数据标准化。
数据的标准化(normalization)是将数据按比例缩放,使之落入一个小的特定区间。在某些比较和评价的指标处理中经常会用到,去除数据的单位限制,将其转化为无量纲的纯数值,便于不同单位或量级的指标能够进行比较和加权。其中最典型的就是数据的归一化处理,即将数据统一映射到[0,1]区间上。

Z标准化即减去均值,再除以标准差。
#数据标准化
data['R']=(data['DATEDIFF']-data['DATEDIFF'].mean())/(data['DATEDIFF'].std())
data['F']=(data['FLIGHT_COUNT']-data['FLIGHT_COUNT'].mean())/(data['FLIGHT_COUNT'].std())
data['M']=(data['SUM_YR']-data['SUM_YR'].mean())/(data['SUM_YR'].std())
三、模型构建
根据业务的需要,将客户分为5类:重要保持客户,重要发展客户,重要挽留客户,一般价值用户与低价值用户。
1、重要保持客户:RFM都很好,时间间隔小,乘坐次数多,金额大。这类客户价值大,对航空公司贡献最大,是公司的重要客户,公司要花精力维护好这类客户。
2、重要发展客户:最近乘坐过,但次数或金额较低。这类客户最近有乘机需求,公司要刺激这类客户再次消费,提高他们的消费水平。
3、重要挽留客户:有段时间没坐,但之前经常坐或消费金额高。说明这类客户消费能力不错,只是近期无消费,公司要促进这类客户的再次消费。
4、一般价值用户:各项表现一般,价值不大。
5、低价值用户:各项表现差,价值低。
#模型构建
data2=data[['R','F','M']] #筛选出进行聚类的字段
from sklearn.cluster import KMeans #导入KMeans聚类模型
kmodel=KMeans(n_clusters=4,n_jobs=4) #n_clusters为分类数,n_jobs为并行数,一般等于CPU数较好
kmodel.fit(data2) #带入数据训练模型
print(kmodel.cluster_centers_) #查看聚类中心
print(kmodel.labels_) #查看各样本对应的类别
导入sklearn库出错原因:sklearn依赖包numpy,pandas,matplotlib,scipy,但是之前安装好的numpy并没有mkl,所以我们需要下载numpy+mkl,下载链接:https://www.lfd.uci.edu/~gohlke/pythonlibs/#numpy
注意:建模的数据不能包含空值或无限值,否则会报错

运行结果如下:

可以看出,第一和第四行聚类中心表现最差,频率和金额最低,时间间隔大,为一般价值用户与低价值用户。
第三行聚类中心表现最好,时间间隔最小,乘机次数最多,金额最大,为类别2,这一类客户价值最高,是航空公司重点维护的客户。
第五行聚类中心频率和金额较大,但有段时间没乘坐过,是航空公司的重要挽留客户。
第二行聚类中心近段时间乘坐过,但频率或金额较低,是航空公司的重要发展客户。
四、导出数据
导出数据,更好地查看各个客户对应的类别,然后根据不同的类别制定不同的政策。
#导出数据,数据最后一列为各样本对应的类别
data['LABELS']=kmodel.labels_
data.to_csv('C:/Users/86138/Desktop/Python数据分析与挖掘实战/chapter7/fenlei.csv')
print(data['LABELS'].value_counts) #查看每类有多少个
print(data[data['LABELS']==0]) #筛选出类别0的数据
一些政策如积分兑换,会员升级,促销活动,免费兑换,发行联名卡等。
最后
完整的代码如下:
import pandas as pd
#首先导入数据,注意文件路径为反斜杠,补全文件路径
data=pd.read_csv('C:/Users/86138/Desktop/Python数据分析与挖掘实战/chapter7/demo/data/air_data.csv')
#查看数据的一些基本信息
print(data.head())
print(data.info())
print(data.describe())
#计算距今天数
from datetime import datetime
data.replace('2014/2/29 0:00:00','2014/3/1',inplace=True)
data['LAST_FLIGHT_DATE']=pd.to_datetime(data['LAST_FLIGHT_DATE'])
data['DATEDIFF']=datetime.now()-data['LAST_FLIGHT_DATE']
data['DATEDIFF']=data['DATEDIFF'].dt.days #提取天数
#计算金额总额
data['SUM_YR']=data['SUM_YR_1']+data['SUM_YR_2']
#缺失值处理
print(data['DATEDIFF'].isnull().sum())
print(data['FLIGHT_COUNT'].isnull().sum())
print(data['SUM_YR'].isnull().sum())
data=data[data['SUM_YR'].notnull()] #筛选出非空值
#数据标准化
data['R']=(data['DATEDIFF']-data['DATEDIFF'].mean())/(data['DATEDIFF'].std())
data['F']=(data['FLIGHT_COUNT']-data['FLIGHT_COUNT'].mean())/(data['FLIGHT_COUNT'].std())
data['M']=(data['SUM_YR']-data['SUM_YR'].mean())/(data['SUM_YR'].std())
#模型构建
data2=data[['R','F','M']] #筛选出进行聚类的字段
from sklearn.cluster import KMeans #导入KMeans聚类模型
kmodel=KMeans(n_clusters=5,n_jobs=4) #n_clusters为分类数,n_jobs为并行数,一般等于CPU数较好
kmodel.fit(data2) #带入数据训练模型
print(kmodel.cluster_centers_) #查看聚类中心
print(kmodel.labels_) #查看各样本对应的类别
#导出数据,数据最后一列为各样本对应的类别
data['LABELS']=kmodel.labels_
data.to_csv('C:/Users/86138/Desktop/Python数据分析与挖掘实战/chapter7/fenlei.csv')
print(data['LABELS'].value_counts) #查看每类有多少个
print(data[data['LABELS']==0]) #筛选出类别0的数据