问题背景:
某业务有以下几个考核城市的指标, (如出车率,这里不详细介绍)
现在要对全国所有的城市按照上述指标进行分类, 比如表现好的,表现差的,那么问题来了,
我应该分为几类呢, 是分3类还是分7类?
谁是好的那一类, 谁是差的那一类呢?
土豪回答: 拍脑袋决定个目标值, 都达到就是好的那一类, 至于分几类,就好中坏吧!
作者说: 其实也可以,但是我们还可以使用聚类分析的方式, 评估分为几类,以及如何分类更合适。
第一步:数据预处理
数据集: df(pandas.dataframe)
我们先看看各指标之间的离散程度如何:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
fig,axs=plt.subplots(2,3,figsize=(12,6),sharey=True)
axs[0,0].scatter(weiwen_community,changgui_peixun,c='red')
axs[0,1].scatter(weiwen_community,score_low)
axs[0,2].scatter(weiwen_community,sj_tgl)
axs[1,0].scatter(weiwen_community,chuche_lv,c='red')
axs[1,1].scatter(weiwen_community,chengxin_chenei,c='red')
axs[1,2].scatter(weiwen_community,chengxin_chewai,c='red')
fig.suptitle('the dispersion degree between weiwen_community and others')
plt.show()
上图中, 我们把离散程度较好的维度标记成红色,一般而言,就是点散的越开,离散程度越好。
同上,我们把所有的维度之间的离散程度画出来。
看score_low那张图, x轴比较聚集,y轴比较分散, 这里可以考虑把x轴score_low系数化处理(比如ln),把数据打散。这里不详细介绍了.
这里我踩了一个坑,这个指标是越低越好,提前忘了处理了.....遇到负向指标,别忘记用1减一下。
sj_tgl 没有带来很好的区分效果,可以舍弃
我们看到chengxin_chenei, chengxin_chewai给数据集带来的区分效果较好
接下来是聚类数据的准备,这里要去除null值,如果觉得很复杂,可以在原来的excel里面操作
df2=df[['weiwen_community','changgui_peixun', 'score_low', 'chuche_lv','chengxin_chenei', 'chengxin_chewai']]
df2.fillna('0')
df2.dropna(inplace=True)
np.isnan(df2).any()
打印结果如下, 看到每一列都没有null值了
接下来开始聚类, 第一个问题, 咱们的这些城市分为几类比较合适。
from sklearn.cluster import KMeans
from sklearn import metrics
dict={}
for i in range(6):
j=i+2
km=KMeans(n_clusters=j).fit(df2)
df2['label']=km.labels_
cluster_center_4=df2.groupby('label').mean().reset_index()
#print(cluster_center_4)
labels=km.labels_
score=metrics.silhouette_score(df2,labels)
dict[j]=score
print(dict)
输出的结果如下:
我们看到分的类别越多, 区分效果越好, 从实际的业务出发,肯定是分的越少越好,所以咱们可以把所有的城市分为4类。
接下来,我们把分好类的城市绘制散点图, 描述分类的效果。
from sklearn.cluster import KMeans
from sklearn import metrics
from pandas import plotting
km=KMeans(n_clusters=4).fit(df2)
df2['label']=km.labels_
cluster_center_4=df2.groupby('label').mean().reset_index()
print(cluster_center_4)
labels=km.labels_
score=metrics.silhouette_score(df2,labels)
colors=np.array(['red','blue','yellow','black'])
plotting.scatter_matrix(df2,s=100,alpha=1,c=colors[df2['label']],figsize=(18,12))
plt.show()
plt.savefig('result.jpg')
df2.to_csv('result.csv')
我们看下这个图片。
分成的0,12,3四类,我们用['red','blue','yellow','black'] 四个颜色表示,看到红色更多出现的原点附近,那估计是比较差的, 蓝色都比较接近右上角,可以说是优秀了。
也可以通过cluser_center_4那个参数打印的均值看一下
看到1的mean值最高,0的mean值最低。
于是我们给出下面的解释
如何验证分类结果有业务含义, 我们可以通过各个指标的总和简单的判断一下(要求指标都是正向指标,且在0-1之间)
因为数据涉密,不展示每个城市的排名和得分,但是作者看到有个城市总分倒数第一,尽然给了中等的划分, 这个城市就是石家庄,看来果真kmeans聚类比算指标的总分靠谱啊。