zoukankan      html  css  js  c++  java
  • 【机器学习】k-means——航空用户聚类分析案例

      1 import pandas as pd
      2 import numpy as np
      3 from sklearn.cluster import KMeans
      4 import matplotlib.pyplot as plt
      5 
      6 
      7 def stand_sca(data):
      8     """
      9     标准差标准化
     10     :param data:原数据
     11     :return: 标准差之后的数据
     12     """
     13     data = (data - data.mean()) / data.std()
     14 
     15     return data
     16 
     17 
     18 def box_analysis(data):
     19     """
     20     箱线图分析去除异常值
     21     :param data: 原数据---series
     22     :return: bool数组
     23     """
     24     # 上四分位数
     25     qu = data.quantile(q=0.75)
     26     # 下四分位数
     27     ql = data.quantile(q=0.25)
     28     # 计算四分位间距
     29     iqr = qu - ql
     30 
     31     # 上限
     32     up = qu + 1.5 * iqr
     33     # 下限
     34     low = ql - 1.5 * iqr
     35 
     36     bool_index = (data < up) & (data > low)
     37 
     38     return bool_index
     39 
     40 
     41 # 1、了解航空公司现状以及 航空用户的价值
     42 # 6w+ 样本  44个特征 ----> LRFMC
     43 # 2、数据处理
     44 # (1)缺失值处理
     45 # 删除法
     46 #  (2) 筛选相关特征---构建最终的特征
     47 # LRFMC <----筛选出能够构建这5个特征的相关特征
     48 # (3)异常值处理
     49 # 3sigma 原则 或者 box_analysis
     50 # (4)标准化处理
     51 # 标准差标准化
     52 # 3、k-means实现航空用户的聚类
     53 # sklearn
     54 # 4、结果展示
     55 # 绘制雷达图
     56 # 5、输出结论
     57 # 营销策略
     58 
     59 def build_data():
     60     """
     61     构建原始数据
     62     :return: 原始数据
     63     """
     64     # 1、加载数据
     65     air_data = pd.read_csv("./air_data.csv", encoding="ansi")
     66     # print("air_data:
    ", air_data)
     67     # print("air_data 的列索引名称:
    ", air_data.columns)
     68 
     69     return air_data
     70 
     71 
     72 def deal_data(air_data):
     73     """
     74     数据处理
     75     :param air_data:原始数据
     76     :return: 数据处理之后的结果
     77     """
     78     # 2、数据清洗
     79     # 缺失值、异常值
     80     # 检测缺失值
     81     res_null = pd.isnull(air_data).sum()
     82     # print("缺失值检测结果:", res_null)
     83 
     84     # 处理缺失值
     85     # (1)丢弃票价为空的记录 # SUM_YR_1  SUM_YR_2两列
     86     # ----可以理解保留票价不为空
     87     bool_index_1 = air_data.loc[:, "SUM_YR_1"].notnull()
     88     bool_index_2 = air_data.loc[:, "SUM_YR_2"].notnull()
     89     # 个人认为 只有两列票价都不为空,票价才不为空
     90     bool_index = bool_index_1 & bool_index_2
     91     air_data = air_data.loc[bool_index, :]
     92     # (2)丢弃票价为0,折扣不为0,飞行里程 > 0 的数据--->丢弃航空公司没有盈利的数据
     93     # 保留盈利的数据
     94     # 保留票价 > 0,折扣 > 0,飞行里程 > 0
     95     # 个人认为只要有一列票价>0,票价就>0
     96     bool_id_1 = air_data.loc[:, "SUM_YR_1"] > 0
     97     bool_id_2 = air_data.loc[:, "SUM_YR_2"] > 0
     98 
     99     # 折扣> 0
    100     bool_id_3 = air_data.loc[:, "avg_discount"] > 0
    101 
    102     # 飞行里程>0
    103     bool_id_4 = air_data.loc[:, "SEG_KM_SUM"] > 0
    104 
    105     bool_id = (bool_id_1 | bool_id_2) & bool_id_3 & bool_id_4
    106 
    107     air_data = air_data.loc[bool_id, :]
    108 
    109     res_null = pd.isnull(air_data).sum()
    110     # print("缺失值检测结果:", res_null)
    111 
    112     # 先筛选特征
    113     # LRFMC
    114     # 筛选 入会时间、窗口结束时间、最后乘坐飞机距离窗口结束的时长,乘坐飞机次数、飞行里程、折扣系数
    115     air_data = air_data.loc[:, ["FFP_DATE", "LOAD_TIME", "LAST_TO_END", "FLIGHT_COUNT", "SEG_KM_SUM", "avg_discount"]]
    116 
    117     # 构建LRFMC五个特征
    118     air_data.loc[:, "FFP_DATE"] = pd.to_datetime(air_data.loc[:, "FFP_DATE"])
    119     air_data.loc[:, "LOAD_TIME"] = pd.to_datetime(air_data.loc[:, "LOAD_TIME"])
    120     # 获取时间差--单位是day
    121     air_data.loc[:, "L_days"] = air_data.loc[:, "LOAD_TIME"] - air_data.loc[:, "FFP_DATE"]
    122     # 获取相差天数 的数值
    123     air_data.loc[:, "L_days"] = [i.days for i in air_data.loc[:, "L_days"]]
    124     # 获取具体的月数--即L
    125     air_data.loc[:, "L"] = np.ceil(air_data.loc[:, "L_days"] / 30)
    126     # print(air_data.loc[:, "L"])
    127     # 构建R --- LAST_TO_END 这个时长应该是天数
    128     # print(air_data.loc[:, "LAST_TO_END"])
    129     air_data.loc[:, "R"] = np.ceil(air_data.loc[:, "LAST_TO_END"] / 30)
    130     # print("air_data.loc[:, "R"]:
    ",air_data.loc[:, "R"])
    131 
    132     air_data.loc[:, "F"] = air_data.loc[:, "FLIGHT_COUNT"]
    133 
    134     air_data.loc[:, "M"] = air_data.loc[:, "SEG_KM_SUM"]
    135 
    136     air_data.loc[:, "C"] = air_data.loc[:, "avg_discount"]
    137 
    138     air_data = air_data.iloc[:, -5:]
    139     # print("最终的数据:
    ", air_data)
    140 
    141     # 异常值处理
    142     for column in air_data.columns:
    143         bool_ = box_analysis(air_data.loc[:, column])
    144         air_data = air_data.loc[bool_, :]
    145 
    146     # 标准化数据
    147     air_data = stand_sca(air_data)
    148 
    149     print("标准化之后的数据:
    ", air_data)
    150 
    151     return air_data
    152 
    153 
    154 def km_fit(air_data, k):
    155     """
    156     k-means训练数据,并进行用户聚类
    157     :param air_data: 数据
    158     :param k: 聚类的类别数目
    159     :return:
    160     """
    161     # 1、创建算法实例
    162     km = KMeans(n_clusters=k)
    163     # 2、训练数据
    164     km.fit(air_data)
    165     # 3、预测
    166     y_predict = km.predict(air_data)
    167 
    168     # 获取聚类中心
    169     center = km.cluster_centers_
    170 
    171     return y_predict, center
    172 
    173 
    174 def show_res(center, feature_num):
    175     """
    176     绘制雷达图
    177     :param center:聚类中心
    178     :param feature_num: 特征的数量
    179     :return:
    180     """
    181     # 1、创建画布
    182     # 绘制雷达图 需要用到极坐标
    183     fig = plt.figure()
    184     # 修改RC参数,来让其支持中文
    185     plt.rcParams['font.sans-serif'] = 'SimHei'
    186     plt.rcParams['axes.unicode_minus'] = False
    187     # polar  开启极坐标
    188     fig.add_subplot(1, 1, 1, polar=True)
    189     # 2、绘图
    190     # 准备数据
    191     # 准备角度数据
    192     angle = np.linspace(start=0, stop=2 * np.pi, num=feature_num, endpoint=False)
    193     print(angle)
    194     # 闭合角度
    195     angle = np.concatenate((angle, [angle[0]]))
    196     # print(angle)
    197     for i in range(center.shape[0]):
    198         # print(center[i, 0])
    199         # 闭合数据
    200         data = np.concatenate((center[i, :],[center[i, 0]]))
    201         plt.polar(angle, data)
    202 
    203     # 设置刻度
    204     plt.xticks(angle[:-1],["L","R","F","M","C"])
    205 
    206     # 增加图例
    207     plt.legend(["第一类用户","第二类用户","第三类用户","第四类用户","第五类用户"])
    208     # 保存图片
    209     plt.savefig("./航空用户聚类分析结果雷达图展示.png")
    210     # 3、展示
    211     plt.show()
    212 
    213 
    214 def main():
    215     """
    216     主函数
    217     :return:
    218     """
    219     # 1、构建原始数据
    220     air_data = build_data()
    221     # 2、数据处理
    222     air_data = deal_data(air_data)
    223     # 3、构建聚类模型进行用户聚类
    224     # 确定聚类的类别数目
    225     k = 5
    226     y_predict, center = km_fit(air_data, k)
    227     print("预测值为:
    ", y_predict)
    228     print("聚类中心为:
    ", center)
    229 
    230     # 4、结果展示
    231     show_res(center, center.shape[1])
    232 
    233 
    234 if __name__ == '__main__':
    235     main()
  • 相关阅读:
    [BZOJ 2653]middle
    svn提交错误
    查看当前功能地址
    后台纯代码--短信验证
    图片验证码~~~之后台生成随机数
    小程序之~~登录后台代码
    小程序登录过程简介
    小程序之~微信登录后台代码
    小程序之~~基于微信登录,后台代码
    小程序之~~短信验证
  • 原文地址:https://www.cnblogs.com/Tree0108/p/12116168.html
Copyright © 2011-2022 走看看