“ Python实现一个算法总是比你理解这个算法更简单,这也是Python如此流行的原因之一。”
在前面的文章中讲过数据离散化和KMeans算法的理论理解。
这篇文章来看看怎样用Python实现这个事。
01
—
目标
有下图所示的一系列数据,总共有900多条,这是《Python数据分析与挖掘实战》这本书第4章的案例数据。
从图中可见,测量值非常多,但实际上肝气郁结要么就是有要么就是没有,就两种情况;再细致一点,我们可能分成好、不太好、差、很差四类。当然,具体怎样分法需要这方面的专业人士来定。
反正,就拿过来这样一堆数据,根据这组数据情况呢把病人给分成四类。
也就是说,我们的目标就是将这900多条数据用K-Means算法给分成4类。
02
—
实现步骤
Step1,当然是把需要用到的第三方库给import进来
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
KMeans就是要用到第三行。
Step2,当然是把数据读到pandas的dataframe中
datafile = u'../data/discretization_data.xls'
data = pd.read_excel(datafile) #这个地方的data的类型是DataFrame
data = data[u'肝气郁结证型系数'] #这里的data已经是DataFrame的一列,变成了Series了
上面这个第三行是啥意思呢?因为我们待会要用到的KMeans的输入数据类型是ndarray的行向量,所以先在这里把data的一列拿出来。
Step3,创建KMeans的分类器并对Step2中的数据进行聚类。
请看代码:
k = 4
kmodel = KMeans(n_clusters = k, n_jobs = 2) #n_jobs是进程的数量,和cpu个数有关
kmodel.fit(data.values.reshape((len(data),1)))
c = pd.DataFrame(kmodel.cluster_centers_).sort_values(0) #对聚类中心排序
w1 = c.rolling(2).mean().iloc[1:]
w = [0] + list(w1[0]) + [data.max()]
d_result = pd.cut(data, w, labels = range(k))
就这么简单,就7行就搞定了这个事。在这里,我有必要把这几行代码简要说一下。
第1-3行,就是拿Step2中的数据用KMeans算法给聚类,不是会得到4个分类么?每个分类不是会有一个中心点么?如果忘记了,请回过头去看看这篇文章:数据离散化及其KMeans算法实现的理解。
拿这4个圆心也是存放在第2行创建的这个KMeans的对象kmodel中,确切说在它的cluster_centers_中。它的值是下面图这样的,然后再对它们从小到大排序给到c。
第4行,然后我们再把它转成DataFrame类型,再排一下序(就是代码第4行干的事)
第5行,是做窗口平均的,也就是说以rolling的输入2为窗口大小求平均值。更直白一点,就是第c的(第1个值+第2个值)/2作为新的第2个值,第1个值就没了,c经过rolling(2)窗口平均后的结果是这样的。
然后我们把上图中的第1个值NaN给切掉后再赋给w1。
第6行,是将0作为最小,将data中的最大值作为最大,加入到w1中,w就变成5个值了,c\w1\w分别如下图的左、中、右。
第7行,所有前面6行都是为这一行服务的,就是要把我们对data分类的5个分类的界限(值)确定下来之后,用cut函数将data分成5类。
Step4:把分类好后的结果给画出来。代码如下:
def cluster_plot(d, k):
plt.rcParams['font.sans-serif']=['SimHei'] #正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False #正常显示负号
plt.figure(figsize=(8,3))
for j in range(0,k):
plt.plot(data[d==j],[j for i in d[d==j]],'o')
plt.ylim(-0.5, k-0.5)
return plt
cluster_plot(d_result,k).show()
这里呢,定义了一个函数cluster_plot的函数,返回一个画好了cluster的pyplot。
绘制的结果见“03 效果分析”。
03
—
效果分析
下面这个图就是聚类完成的结果图。可以看出来,我们通过KMeans算法找到的几个分界点将900多个数据给很好的分成了4类。
在没聚类之前的原始数据是这样的:
上面那个图看着舒服多了。
在这篇文章中,我们用KMeans算法对数据进行聚类是非常简单、粗暴的。并没有指定距离的计算方法、初始的中心点、结束条件等,都是使用了sklearn.cluster中KMeans的默认值,如果需要更详细的了解需要去看看sklearn的官方文档。
04
—
小结
用Python做数据分析的感觉就是:做之前没头绪、做之后感觉挺简单。