""" 了解航空现状 了解 40个特征--每个特征的含义 观察窗口---2012-04-01 ----2014-03-31,我们给定的数据 就是观察窗口内的数据 # 丢弃票价为空的记录-----保留票价不为空的记录 # 丢弃票价为0 ,折扣不为0,飞行里程大于0 的数据 -----没花钱,而且还乘坐飞机了 # ===》保留票价>0 ,折扣不为0 ,飞行里程大于0 的数据 ---真真正正花钱坐飞机 # 筛选特征的时候---去 筛选出能够与LRFMC 相关的特征出来 # 构建特征的时候 需要构建 ---LRFMC五个特征 # 进行异常值处理 ---箱线图分析/3sigma #标准化数据 --->自定义的 也可以用sklearn 的 # 数据已经就位 # km聚类---聚为5类,聚类中心可以拿到了 # 常规的 散点图不适合这类结果 # 结果展示---雷达图 # 分析--给出建议 """ import pandas as pd from sklearn.preprocessing import StandardScaler import matplotlib.pyplot as plt from sklearn.cluster import KMeans import numpy as np def box_analysis(data): """ 进行箱线图分析,剔除异常值 :param data: series :return: bool数组 """ qu = data.quantile(0.75) # print(qu) ql = data.quantile(0.25) # print(ql) iqr = qu - ql # 上限 up = qu + 1.5 * iqr # 下限 low = ql - 1.5 * iqr # 进行比较运算 bool_id_1 = data <= up bool_id_2 = data >= low bool_num = bool_id_1 & bool_id_2 return bool_num # 1、加载数据 air_data = pd.read_csv("./air_data.csv", encoding='ansi') print("air_data: ", air_data) print("air_data 的形状: ", air_data.shape) print("air_data 列索引: ", air_data.columns) # 2、缺失值处理 # 丢弃票价为空的记录-----保留票价不为空的记录 bool_id_1 = air_data.loc[:, 'SUM_YR_1'].notnull() # 不为空的 为T,空的为F bool_id_2 = air_data.loc[:, 'SUM_YR_2'].notnull() bool_id = bool_id_1 & bool_id_2 air_data = air_data.loc[bool_id, :] print("*" * 80) print("丢弃票价为空的记录之后的结果: ", air_data.shape) # 丢弃票价为0 ,折扣不为0,飞行里程大于0 的数据 -----没花钱,而且还乘坐飞机了 # ===》保留票价>0 ,折扣不为0 ,飞行里程大于0 的数据 ---真真正正花钱坐飞机 bool_num_1 = air_data.loc[:, 'SUM_YR_1'] > 0 bool_num_2 = air_data.loc[:, 'SUM_YR_2'] > 0 bool_num_3 = air_data.loc[:, 'avg_discount'] > 0 bool_num_4 = air_data.loc[:, 'SEG_KM_SUM'] > 0 bool_num = (bool_num_1 | bool_num_2) & bool_num_3 & bool_num_4 air_data = air_data.loc[bool_num, :] print("*" * 80) print("丢弃票价为0 ,折扣不为0,飞行里程大于0 的数据之后的结果: ", air_data.shape) # 3、筛选特征 air_data = air_data.loc[:, ['FFP_DATE', 'LOAD_TIME', 'LAST_TO_END', 'FLIGHT_COUNT', 'SEG_KM_SUM', 'avg_discount']] print("*" * 80) print("筛选出有效特征之后的结果: ", air_data) # 4、构建LRFMC五个特征 # 先将数据转化为pandas默认支持的时间序列数据 # 构建L air_data.loc[:, 'LOAD_TIME'] = pd.to_datetime(air_data.loc[:, 'LOAD_TIME']) air_data.loc[:, 'FFP_DATE'] = pd.to_datetime(air_data.loc[:, 'FFP_DATE']) air_data.loc[:, 'L_days'] = air_data.loc[:, 'LOAD_TIME'] - air_data.loc[:, 'FFP_DATE'] print("*" * 80) air_data.loc[:, 'L_days'] = [i.days for i in air_data.loc[:, 'L_days']] air_data.loc[:, 'L'] = air_data.loc[:, 'L_days'] / 30 # print("计算出的L_days结果: ", air_data.loc[:, 'L_days']) # print("*" * 80) # print("计算出的L结果: ", air_data.loc[:, 'L']) # 构建R print("*" * 80) # 先将数据转化为pandas默认支持的时间序列数据 air_data.loc[:, 'R'] = air_data.loc[:, 'LAST_TO_END'] / 30 # 构建F air_data.loc[:, 'F'] = air_data.loc[:, 'FLIGHT_COUNT'] # 构建 M air_data.loc[:, 'M'] = air_data.loc[:, 'SEG_KM_SUM'] # 构建C air_data.loc[:, 'C'] = air_data.loc[:, 'avg_discount'] # 取出LRFMC data = air_data.iloc[:, -5:] print("构建好特征之后的data: ", data.shape) print("*" * 80) # 5进行异常值处理 for i in range(len(data.columns)): bool_index = box_analysis(data.iloc[:, i]) data = data.loc[bool_index, :] print("处理完异常值之后的结果: ", data.shape) # 6、标准化处理 stand = StandardScaler() x = stand.fit_transform(data) print("*" * 80) print("标准化之后的结果: ", x) # 7、进行聚类 k = 5 # 创建实例 km = KMeans(n_clusters=k) # 训练数据 km.fit(x) # 预测类别 y_predict = km.predict(x) # 获取聚类中心 center = km.cluster_centers_ print("*" * 80) print("聚类中心: ", center) print("预测标签值: ", y_predict) # 1、创建画布 plt.figure() # 默认不支持中文,需要配置RC 参数 plt.rcParams['font.sans-serif']='SimHei' # 设置字体之后不支持负号,需要去设置RC参数更改编码 plt.rcParams['axes.unicode_minus']=False # 创建子图 polar=开启极坐标 plt.subplot(111, polar=True) # 2、绘图 # 设计角度 datalength = 5 angle = np.linspace(0, 2 * np.pi, num=datalength,endpoint=False) # 闭合角度 angle = np.concatenate((angle,[angle[0]]),axis=0) # 循环闭合数据 并进行绘图 for i in range(k): # 循环进行闭合数据 data = np.concatenate((center[i,:],[center[i,0]])) # 每闭合一次数据,就进行绘制一次图形 plt.polar(angle,data) print(angle) # 设置刻度 labels = ["L","R","F","M","C"] plt.xticks(angle,labels) # 增加标题 plt.title("航空用户聚类分析") #设置图例 plt.legend(["用户群体一","用户群体二","用户群体三","用户群体四","用户群体五"]) # 保存图片 plt.savefig("./航空用户聚类分析.png") # 3、展示 plt.show()