前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python实现KMeans算法

Python实现KMeans算法

作者头像
讲编程的高老师
发布2020-08-14 10:04:40
8080
发布2020-08-14 10:04:40
举报
文章被收录于专栏:讲编程的高老师

Python实现一个算法总是比你理解这个算法更简单,这也是Python如此流行的原因之一。

在前面的文章中讲过数据离散化和KMeans算法的理论理解。

参见:数据离散化及其KMeans算法实现的理解

这篇文章来看看怎样用Python实现这个事。

01

目标

有下图所示的一系列数据,总共有900多条,这是《Python数据分析与挖掘实战》这本书第4章的案例数据。

从图中可见,测量值非常多,但实际上肝气郁结要么就是有要么就是没有,就两种情况;再细致一点,我们可能分成好、不太好、差、很差四类。当然,具体怎样分法需要这方面的专业人士来定。

反正,就拿过来这样一堆数据,根据这组数据情况呢把病人给分成四类。

也就是说,我们的目标就是将这900多条数据用K-Means算法给分成4类。

02

实现步骤

Step1,当然是把需要用到的第三方库给import进来

代码语言:javascript
复制
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans

KMeans就是要用到第三行。

Step2,当然是把数据读到pandas的dataframe中

代码语言:javascript
复制
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中的数据进行聚类。

请看代码:

代码语言:javascript
复制
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:把分类好后的结果给画出来。代码如下:

代码语言:javascript
复制
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做数据分析的感觉就是:做之前没头绪、做之后感觉挺简单。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-04-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 讲编程的高老师 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档