当前位置:   article > 正文

使用聚类(K-means)分析方法对骑手进行分类标签定义_聚类标签

聚类标签

什么是聚类分析

        聚类分析的目标就是在相似的基础上收集数据来分类,属于无监督学习。就是通过行为数据,通过算法将相似的人群聚集在一起,形成不带标签的人群簇。再人为的对人群簇进行分析,寻找特征标签。

一、数据构建

        根据骑手的行为数据,可以从 日均活跃时长、工作日/非工作日、高峰期/平峰期、白天/夜间、骑手年龄等 可能存在喜好偏差的行为数据,进行数据构建。

#基础包导入(有很多无关的,懒的删除了,哈哈哈

  1. from sklearn.datasets import load_iris
  2. import xgboost as xgb
  3. from xgboost import plot_importance
  4. from matplotlib import pyplot as plt
  5. from sklearn.model_selection import train_test_split
  6. import pandas as pd
  7. import numpy as np
  8. from sklearn.metrics import accuracy_score
  9. import seaborn as sns
  10. import matplotlib
  11. #指定默认字体
  12. matplotlib.rcParams['font.sans-serif'] = ['SimHei']
  13. matplotlib.rcParams['font.family']='sans-serif'
  14. #解决负号'-'显示为方块的问题
  15. matplotlib.rcParams['axes.unicode_minus'] = False
  16. from pyhive import hive
  17. import os
  18. def presto_read_sql_df(sql):
  19. conn=prestodb.dbapi.connect(
  20. host=os.environ['PRESTO_HOST'],
  21. port=os.environ['PRESTO_PORT'],
  22. user=os.environ['JUPYTER_HADOOP_USER'],
  23. password=os.environ['HADOOP_USER_PASSWORD'],
  24. catalog='hive')
  25. cur = conn.cursor()
  26. cur.execute(sql)
  27. query_result = cur.fetchall()
  28. colnames = [part[0] for part in cur.description]
  29. raw = pd.DataFrame(query_result, columns=colnames,dtype=np.float64)
  30. return raw
  31. def hive_read_sql_df(sql):
  32. conn = hive.connect(
  33. host=os.environ['PYHIVE_HOST'],
  34. port=os.environ['PYHIVE_PORT'],
  35. username=os.environ['JUPYTER_HADOOP_USER'],
  36. password=os.environ['HADOOP_USER_PASSWORD'],
  37. auth='LDAP',
  38. configuration={'mapreduce.job.queuename': os.environ['JUPYTER_HADOOP_QUEUE'],
  39. 'hive.resultset.use.unique.column.names':'false'})
  40. raw = pd.read_sql_query(sql,conn)
  41. return raw

#数据读取(可以用hive,也可以直接读取文件 

  1. df = hive_read_sql_df("""
  2. select
  3. *
  4. from XXX
  5. """)
  6. df.to_csv('XXXXX.csv',encoding='gbk',sep=',',index = False)

 #从文件读取数据

  1. # 路径调整
  2. # print(os.getcwd())
  3. # os.chdir('/home/')
  4. # print(os.getcwd())
  5. data = pd.read_csv('XXXXXX.csv',encoding='gbk')

 #可能会存在部分缺失值导致后续运行报错,先将缺失值进行剔除 

  1. df = data
  2. df.describe() #数据预览
  3. print(df.isnull().any()) #缺失值判断
  4. df.dropna(inplace=True) #删除缺失值
  5. print(df.isnull().any()) #缺失值判断
  6. df.describe() #数据预览
  7. # df = df.query("main_city_tsh_rate > 0.15") #数据筛选
  8. # df = df.drop('age',axis=1) #删除无关列
  9. _id = df['_id'] #先将dri_id单独存储,在分类后再加回去
  10. td = df.drop('_id',axis=1) #删除_id列

#数据标准化,避免数据的量纲对分类产生权重影响,对数据进行标准化 

        使用Z分数标准化数据:Z分数_百度百科

  1. #数据标准化处理——z分数: x = (x - x.mean()) /x.std()
  2. td.tsh_avg = (td.tsh_avg -td.tsh_avg.mean()) / td.tsh_avg.std()

二、超参数K值回归

        K,即K-means聚类产生的结果数,k-means不会自主决定聚类的结果数,需要人为的指定。人为指定通常存在一些误判,可通过手肘法、轮廓系数法进行回归计算,从而选择最优的超参数K。                

2.1手肘法

(由于我的数据量比较大,且有倾向性的希望结果在6-14之间,所以K的范围选择6-14,也可根据自己的需求定义范围) 

  1. # '利用SSE选择k' 选择斜率最小的点作为K
  2. from sklearn.cluster import KMeans
  3. from sklearn.metrics import silhouette_score
  4. # '利用SSE选择k'
  5. SSE = [] # 存放每次结果的误差平方和
  6. for k in range(6, 15):
  7. estimator = KMeans(n_clusters = k,max_iter = 10000,random_state = 10)
  8. estimator = estimator.fit(x)
  9. SSE.append(estimator.inertia_)
  10. print(k)
  11. X = range(6, 15)
  12. plt.xlabel('k')
  13. plt.ylabel('SSE')
  14. plt.plot(X, SSE, 'o-')
  15. plt.show()

K=10,拐点不是非常显著,但基于我的业务需求,倾向将K定义为10 

2.2轮廓系数法:

  1. # 选择最高点作为K
  2. Scores = [] # 存放轮廓系数
  3. from sklearn.cluster import KMeans
  4. from sklearn.metrics import silhouette_score
  5. for k in range(6, 15):
  6. estimator = KMeans(n_clusters = k,max_iter = 10000,random_state = 10)
  7. estimator = estimator.fit(x)
  8. Scores.append(silhouette_score(x, estimator.labels_, metric='euclidean'))
  9. print(k )
  10. X = range(6, 15)
  11. plt.xlabel('k')
  12. plt.ylabel('轮廓系数')
  13. plt.plot(X, Scores, 'o-')

 这个方法数据量大时巨慢,结果没跑出来(大家可以自己尝试下,选择方法可以参考下图,选择K=3,即轮廓系数最大值,理论可参考原文

 

2.3Gap Statistic 法:

具体可大家再深入,我内网环境没安装成功

  1. from gap_statistic import OptimalK
  2. def gap_statistic_K(data, range_K, pro_num):
  3. K = np.arange(1, range_K)
  4. optimalK = OptimalK(n_jobs=1, parallel_backend='joblib')
  5. n_clusters = optimalK(data, cluster_array=K)
  6. # Gap values plot
  7. plt.plot(optimalK.gap_df.n_clusters, optimalK.gap_df.gap_value, linewidth=3)
  8. plt.scatter(optimalK.gap_df[optimalK.gap_df.n_clusters == n_clusters].n_clusters,
  9. optimalK.gap_df[optimalK.gap_df.n_clusters == n_clusters].gap_value, s=250, c='r')
  10. plt.grid(True)
  11. plt.xlabel('Cluster Count')
  12. plt.ylabel('Gap Value')
  13. plt.title('Gap Values by Cluster Count')
  14. plt.savefig(f'/Users/cecilia/Desktop/K_图片/{pro_num}_gap_values_K.jpg')
  15. plt.cla()
  16. # plt.show()
  17. return n_clusters

三、聚类方法——K-means 

n_clusters = 10 ,即结果为10类

  1. from sklearn.cluster import KMeans
  2. kmeans = KMeans(n_clusters = 10,max_iter = 10000,random_state = 10) #构建模型
  3. y = kmeans.fit(td)
  4. # y = kmeans.fit(x)
  5. label_pred = y.labels_#获取聚类标签
  6. df['_type'] = label_pred
  7. df.to_csv('result_v4.csv',encoding='gbk',sep=',',index = False) ##先将结果保存下来
  8. dri_type_cnt = df.groupby('_type').count()._id
  9. # 画图,plt.bar()可以画柱状图
  10. for i in range(len(dri_type_cnt)):
  11. plt.bar(i, dri_type_cnt[i])
  12. # 设置图片名称
  13. plt.title("各簇人数")
  14. # 设置x轴标签名
  15. plt.xlabel("簇标签")
  16. # 设置y轴标签名
  17. plt.ylabel("人数")
  18. # 显示
  19. plt.show()
  20. dri_type_mean = df.groupby('dri_type').mean()
  21. dri_type_mean.to_csv('group_mean_v5.csv',encoding='gbk',sep=',',index = False) ##根据均值寻找人群簇特征

 k-means会将人群分为10类,根据每个特征值,可以对人群进行标签定义 

四、聚类结果白盒化

        因为算法实现的可解释性较差理解成本高,且容易受特征波动有较大变化;基于用户显著性特征对类群进行白盒规则化。

        即根据人群的特征,将人群标签的定义规则进行明确,根据明确的规则,对人群进行直接的标签划分,便于数据的产出和标签的稳定。(此处可根据人群簇的特征值作为参考,也可结合业务的体感进行判断,或者数据分布进行去尾、去头等,无绝对准确的规则,更多的是业务体感)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/129012
推荐阅读
相关标签
  

闽ICP备14008679号