kmeans 聚类算法

            今天给大家介绍一个数据挖掘中的简单的聚类(Clustering)算法kmeans,什么是“聚类”?举个简单例子,比如说有一堆电商企业的用户数据,记录着用户的各种身份信息和交易信息,如姓名、性别、买东什么东西,用户标签等等。那么在这么多用户中,事实上存在一批相似的用户的,什么叫“相似”呢?其实这里的相似是自己定义的,比如我可以定义如果用户购买的东西相似,那么用户就相似。于是我们想把相似的用户都找出来,聚成若干个类(cluster),使得每个类中的用户尽量相似,每个类之间的用户尽量不相似。找出这些类有什么用呢?用处大了,比如我可以知道这羣人的购物习惯比较相似,那么推荐系统推荐商品的时候就可以参考。再比如有些搜索引擎有“查看相似网页”的功能,这个就可以用聚类来做,把网页就行聚类,在聚类的结果中,每一个类中的网页看成是相似的。

       下面来说说kmeans是怎么做Clustering的,kmeans有以下几个步骤:

(1) 设定聚类个数,选定类初始中心点。

        (2) 把每个点归类到离它最近的类中心点所属的类。

        (3) 重新计算新的类中心点。

        (4) 重复(2)直到收敛。

        是不是听着很抽象?我们来看一个简单例子。假设我们现在有6个数据点,每个数据点5维:

Pt1=(1,2,0,0,2)

Pt2=(2,1,3,4,2)

Pt3=(3,2,1,0,3)

Pt4=(1,3,0,0,3)

Pt5=(3,0,3,4,0)

Pt6=(1,2,2,4,0)

        kmeans算法要求指定聚类的个数及每个类的初始中心点,也就是说,你必须告诉它,你要把这堆数据聚成几类,kmeans这个名字中的k就是指类个数,并且在刚开始的时候,你要为每个类指定一个中心点来代表这个类。可能有人会问,我怎么能事先知道数据中大概有几类?以及初始中心点怎么选?这个问题问得很好,关于聚类个数的自动确定,以及初始中心点的自动选取,有专门的研究,这里不讨论这个问题,这里说的是最原始的kmeans~

        聚类个数的k:这个例子中,我们把k设为2。

        初始类中心点:我们选pt1,pt5分别作为cluster1,cluster2的类中心点,然后开始迭代:

        对于每个点,看它离哪个类中心点最近,这里有个问题,就是什么叫“最近”?这个要看你用什么来衡量,如果是做文本聚类,那么可以用Cosine相似度来衡量(不明白Cosine相似度?请看常用相似性、相关性度量指标),如果是做空间位置数据点的聚类,可以用欧式距离,总之就是选择合适的距离度量就好了。我们用的是Cosine相似度,因此相似度越大,距离就越近,相似度越小,距离就越远。下面,我们为每个点计算它到各个类中心点的距离,这里的距离用“1-Cosine相似度”来表示,由于Cosine相似度的聚会范围是0到1,因此距离最近是0,最远是1。

        各个点到各个类中心点的距离:

《kmeans 聚类算法》

       然后把各个点归到离它最近的类中心点所属的那个类,得到:

       Cluster1={Pt1, Pt3, Pt4}, Cluster2={Pt2, Pt5, Pt6

       下一步就是重新计算各类的类中心点,计算方法就是把类中的数据点的对应维座标加起来,然后平均一下,得:

       Cluster1的中心点:(1.667, 2.333, 0.333, 0, 2.667)

       Cluster2的中心点:(2, 1, 2.667, 4, 0.667)

       再次计算各个点到各个类中心点的距离:

《kmeans 聚类算法》

        像刚才一样,把各个点归到离它最近的类中心点所属的那个类,得到:

        Cluster1={Pt1, Pt3, Pt4}, Cluster2={Pt2, Pt5, Pt6} 

        注意看,这时算出来各类中的数据点,和刚才的一样,这时就是所谓的“收敛”了,如果再继续算下去,结果也是一样的。因为这个例子比较简单,因此一下子就能收敛了,对于海量的高维数据,也许会迭代很多次后才能收敛,有时在时间上是无法忍受的,因为数据量比较大,迭代一次的时间也很久,迭代到收敛的时间就更久,所以在这种情况下,通常是让kmeans迭代一定的次数后就停止,比如迭代1W次。

       下面举个实际例子,我从网上找了6段文本,为了方便演示,故意让前三段文本相似,后三段文本相似:  

       Text1=“Nexus 9将于10月17日接受预定,11月13日正式上市发售。16GB版售价399美元,32GB LTE版售价499美元。由于Android L仍在完善之中,因此预定和上市日期可能会有所调整。该知情人士还称,与传闻基本一致,Nexus 9将采用8.9英寸屏幕,分辨率为2048×1440。配备64位双核处理器、Nvidia KeplerGPU、800万像素后置摄像头和300万像素前置摄像头,重480克。


       Text2=“Nexus 9将于本周三发布。麦格雷戈援引接近于谷歌的知情人士的消息称,Nexus 9(开发代号“HTC Volantis”)将于10月15日发布,届时Nexus 9将成为首款运行Android L平台的设备。该消息称,谷歌原计划为Nexus 9举办一场隆重的官方发布会。但由于Android L系统尚不完善,仍在进一步优化之中,因此决定放弃“高调”发布这款平板电脑。


       Text3=“随着谷歌新一代Nexus 9平板真机的谍照曝光,这款由HTC代工的新机将以怎样的价格何时开卖,自然也成了大家关心的话题。日前,来自国外媒体的消息为我们提前揭晓了答案。根据Bright Side of News的报道称,Nexus 9平板电脑计划于本月15日开始接受预定,售价为399美元(约合人民币2446元左右),将于11月3日正式上市。


       Text4=“小米手机4于2014年7月22日下午2点,在北京发布。搭载高通骁龙801(V3)2.5GHz处理器,3GB RAM及16/64GB ROM,后置摄像头为1300万的Sony IMX214,800万前置摄像头,屏幕为5英寸1080p,由夏普和JDI提供;16GB版本售价仍为1999元。


       Text5=“小米 M4(移动4G)搭载高通骁龙801(V3)2.5GHz处理器,3GB RAM及16/64GB ROM,后置摄像头为1300万的Sony IMX214,800万前置摄像头,屏幕为5英寸1080p,由夏普和JDI提供;软件方面,现搭载基于Android4.4的MIUI V5系统,将后续升级到最新版本的MIUI 6。目前该款产品在商家“新机地3C手机专卖”处有现货出售,促销价仅为1999元,有兴趣的朋友不妨关注一下。
 
       Text6=“小米手机4正面采用一块由JDI提供的5英寸电容式触控屏,分辨率为1920X1080像素的FHD级别,并且采用OGS全贴合工艺。此外在覈心方面内置一颗主频2.5GHz骁龙801 MSM8974AC处理器,以及3GB RAM+16GB/64GB ROM的内存组合,即将升级基于Android 4.4系统的全新MIUI6版本。而在机身背部则设有一枚1300万像素索尼新款堆栈式摄像头,包含LED补光灯,及其对应的800万像素前置镜头,拍照实力大增。

       先把每段Text转换成特征向量,也就是特征提取啦,这里用最简单的方法,就是TF。首先对Text进行分词,简单的分词方法可以参考:分词算法:正向最大匹配分词,逆向最大匹配分词。做为例子,这里分词分得比较简单,也没有做filtering,分词结果:

       Text1=[N, ex, u, s,  , 9, 将于, 10月17日, 接受, 预定, ,, 11月13日, 正式, 上市, 发售, 。, 1, 6G, B版, 售价, 3, 99, 美元, ,, 32, G, B,  , LTE, 版, 售价, 499, 美元, 。, 由于, A, n, d, ro, id,  , L, 仍, 在, 完善, 之, 中, ,, 因此, 预定, 和, 上市日期, 可能, 会, 有, 所, 调整, 。, 该, 知情, 人士, 还, 称, ,, 与, 传闻, 基本, 一致, ,, N, ex, u, s,  , 9, 将, 采用, 8.9, 英寸, 屏幕, ,, 分辨率, 为, 20, 48, ×, 14, 40, 。, 配备, 64位, 双核处理器, 、, N, v, idi, a,  , Kepler,  , G, PU, 、, 800, 万, 像素, 后置, 摄像头, 和, 300, 万, 像素, 前置, 摄像头, ,, 重, 480, 克, 。]
       Text2=[N, ex, u, s,  , 9, 将于, 本, 周三, 发布, 。, 麦格雷戈, 援引, 接, 近于, 谷, 歌, 的, 知情, 人士, 的, 消息, 称, ,, N, ex, u, s,  , 9, (, 开发, 代号, “, HT, C V, o, lantis, ”, ), 将于, 10月15日, 发布, ,, 届时, N, ex, u, s,  , 9, 将, 成为, 首款, 运行, A, n, d, ro, id,  , L, 平台, 的, 设备, 。, 该, 消息, 称, ,, 谷, 歌, 原, 计划, 为, N, ex, u, s,  , 9, 举办, 一场, 隆重, 的, 官方, 发布, 会, 。, 但, 由于, A, n, d, ro, id,  , L系统, 尚, 不, 完善, ,, 仍, 在, 进一步, 优化, 之, 中, ,, 因此, 决定放弃, “, 高调, ”, 发布, 这, 款, 平板电脑, 。]
       Text3=[随着, 谷, 歌, 新一代, N, ex, u, s,  , 9, 平板, 真机, 的, 谍照, 曝光, ,, 这, 款, 由, H, TC, 代工, 的, 新机, 将, 以, 怎样, 的, 价格, 何时, 开, 卖, ,, 自然, 也, 成, 了, 大家, 关, 心, 的, 话题, 。, 日前, ,, 来自, 国外, 媒体, 的, 消息, 为, 我们, 提前, 揭, 晓了, 答案, 。, 根据, B, r, i, g, h, t,  , S, i, de,  , of,  , N, e, ws, 的, 报道, 称, ,, N, ex, u, s,  , 9, 平板电脑, 计划, 于, 本月, 15, 日, 开始, 接受, 预定, ,, 售价, 为, 3, 99, 美元, (, 约, 合, 人民币, 24, 46, 元, 左右, ), ,, 将于, 11月3日, 正式, 上市, 。]
       Text4=[小米手机, 4, 于, 2014年, 7月22日, 下午, 2, 点, ,, 在, 北京发布, 。, 搭载, 高, 通, 骁龙, 8, 01, (, V, 3, ), 2, ., 5, GHz, 处理, 器, ,, 3, G, B,  , R, A, M, 及, 16, /, 6, 4G, B,  , ROM, ,, 后置, 摄像头, 为, 1, 300, 万, 的, S, on, y,  , I, MX, 2, 14, ,, 800, 万, 前置, 摄像头, ,, 屏幕, 为, 5, 英寸, 10, 80, p, ,, 由, 夏普, 和, JDI, 提供, ;, 1, 6G, B, 版本, 售价, 仍, 为, 1999, 元, 。]
       Text5=[小米,  , M4, (, 移动, 4G, ), 搭载, 高, 通, 骁龙, 8, 01, (, V, 3, ), 2, ., 5, GHz, 处理, 器, ,, 3, G, B,  , R, A, M, 及, 16, /, 6, 4G, B,  , ROM, ,, 后置, 摄像头, 为, 1, 300, 万, 的, S, on, y,  , I, MX, 2, 14, ,, 800, 万, 前置, 摄像头, ,, 屏幕, 为, 5, 英寸, 10, 80, p, ,, 由, 夏普, 和, JDI, 提供, ;, 软件, 方面, ,, 现, 搭载, 基于, A, n, d, ro, id,  , 4, ., 4, 的, MIUI,  , V, 5, 系统, ,, 将, 后续, 升级, 到, 最, 新, 版本, 的, MIUI,  , 6, 。, 目前, 该, 款, 产品, 在, 商家, “, 新机, 地, 3C手机, 专卖, ”, 处, 有, 现货, 出售, ,, 促销价, 仅, 为, 1999, 元, ,, 有, 兴趣, 的, 朋友, 不妨, 关注, 一下, 。]
       Text6=[小米手机, 4, 正面, 采用, 一块, 由, JDI, 提供, 的, 5, 英寸, 电容式触控屏, ,, 分辨率, 为, 19, 20, X, 10, 80, 像素, 的, FHD, 级别, ,, 并且, 采用, O, GS, 全, 贴合, 工艺, 。, 此, 外在, 核心, 方面, 内, 置, 一, 颗, 主频, 2, ., 5, GHz, 骁龙, 8, 01,  , MS, M8, 97, 4A, C, 处理, 器, ,, 以及, 3, G, B,  , R, A, M, +1, 6G, B, /, 6, 4G, B,  , ROM, 的, 内存, 组合, ,, 即将, 升级, 基于, A, n, d, ro, id,  , 4, ., 4, 系统, 的, 全新, MIUI, 6, 版本, 。, 而, 在, 机身, 背部, 则, 设, 有, 一, 枚, 1, 300, 万, 像素, 索尼, 新, 款, 堆栈, 式, 摄像头, ,, 包含, LED补光灯, ,, 及, 其, 对应, 的, 800, 万, 像素, 前置, 镜头, ,, 拍照, 实力, 大, 增, 。]

         然后计算TF特征向量得:

vector1=[3,2,2,2,6,2,1,1,1,2,7,1,1,1,1,5,1,1,1,2,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,2,2,1,2,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
vector2=[4,4,4,4,6,4,2,0,0,0,5,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,2,2,2,2,1,1,1,1,1,1,1,0,0,0,1,0,0,0,1,1,1,0,2,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,4,1,1,1,1,2,2,4,2,1,1,1,2,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
vector3=[3,2,2,2,5,2,1,0,1,1,6,0,1,1,0,3,0,0,0,1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,6,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
vector4=[0,0,0,0,3,0,0,0,0,0,6,0,0,0,0,2,2,1,0,1,2,0,0,0,1,3,0,0,0,0,1,0,0,0,0,0,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,2,0,1,2,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
vector5=[0,0,0,0,7,0,0,0,0,0,9,0,0,0,0,2,1,0,0,0,2,0,0,0,1,2,0,0,0,0,2,1,1,1,1,0,0,1,0,0,0,0,1,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,1,0,3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,2,0,1,2,1,1,0,0,0,0,0,0,0,0,0,0,0,0,4,0,2,0,0,1,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,2,0,0,0,2,0,0,2,1,1,1,1,1,2,2,3,1,1,1,1,1,1,1,1,2,2,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
vector6=[0,0,0,0,4,0,0,0,0,0,7,0,0,0,0,3,1,1,0,0,1,0,0,0,1,3,0,0,0,0,2,1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,0,0,0,1,0,0,0,0,0,1,1,1,0,2,2,1,1,1,1,1,1,0,1,2,1,1,0,0,0,0,1,1,0,0,1,1,0,1,0,0,0,0,0,0,1,0,1,1,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]

        然后设置聚类个数k=2,选取类初始中心点为vector1和vector3所代表的点,聚类结果为把Text1,Text2,Text3聚到一类,把Text4,Text5,Text6聚到另一类,是符合预期的。这里再说明一下,选取聚类个数和初始中心点是有专门的方法的,这里不展开了,挺复杂的,上面的例子是手动选了。

点赞