Python实现K-means聚类算法

因为自己对python也有一定的了解,之前也用R做过一些数据分析,又恰好看到几篇文章介绍python实现算法的,觉得挺有意思,所以参考了一些书籍来自己实现一个K-means的聚类算法。《Python数据分析基础教程:NumPy学习指南(第2版)》和 《 Matplotlib手册》是做数据分析的挺不错的两个入门级教材,推荐给大家。

链接:http://pan.baidu.com/s/1FSheY 密码:ulsa

数据聚类是对于静态数据分析的一门技术,在许多领域内都被广泛地应用,包括机器学习数据挖掘模式识别图像分析、信息检索以及生物信息等。聚类是把相似的对象通过静态分类的方法分成不同的组别或者更多的子集,这样让在同一个子集中的成员对象都有相似的一些属性,常见的包括在坐标系中更加短的空间距离等。

一、K-means算法的简单介绍

K-means算法是很典型的基于距离的聚类算法,采用距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度就越大。该算法认为簇是由距离靠近的对象组成的,因此把得到紧凑且独立的簇作为最终目标。

用一个简单的例子来说明K-means算法的原理。如下图所展示,将n个样本点随机的分布在二维图表中,从点的聚集和松散程度可以大致将点分为三个簇,分别用不同的颜色表示出来。

K-menas算法首先选择K个初始质心,其中K是用户指定的参数,即所期望的簇的个数。这样做的前提是我们已经知道数据集中包含多少个簇,但很多情况下,我们并不知道数据的分布情况,所以只能假设有K个簇,然后做进一步的迭代求平方和来判断各聚类(簇)是否为最优。

K-means算法是一个基于距离的迭代算法,下面是K-means的代价函数:

式中的J函数表示每个样本点到其质心的距离平方和,μc(i)表示第i个聚类的均值,只需对所有类所得到的误差平方求和,即可验证分为k个类时,各聚类是否是最优的。其实这里只需将J函数开方就得到了欧氏距离,更加的直观的想到J函数的值越小,各类内的样本越相似。

下面是K-means算法的求解过程:

1、随机选取 k个聚类质心点

2、重复下面过程直到收敛  {

对于每一个样例 i,计算其应该属于的类:

对于每一个类 j,重新计算该类的质心:

}

这其实就是一个多次迭代的过程:

(1)在所有的样本点中随机抽取出k个聚类中心点

(2)遍历其他的观测点到聚类中心点的最近距离,得到这个点,将其加入到该聚类中

(3)计算每个聚类的平均值,并作为新的中心点

(4)重复(2)-(3),直到这k个中心点不再变化(收敛了)

下图展示了对n个样本点进行K-means聚类的效果,这里k取2。

二、代码实现K-means算法

1、创建K个观测点作为聚类的中心点

2、计算质心到观测点的距离

3、将观测点分配到最近的簇

4、对每一个簇,计算簇中所有点的均值,并将均值作为质心

下面的代码用到了Python中的两个库Numpy和Matplotlib

 1 from numpy import *
 2 import time
 3 import matplotlib.pyplot as plt
 4
 5
 6 # 判读两点之间的距离
 7 def euclDistance(x1, x2):
 8     return sqrt(sum(power(x2 - x1, 2)))
 9
10 # 初始化质心与随机样本点
11 def initCentroids(data, k):12     len_line, dim = data.shape  #读取矩阵的长度,返回一个(len_line,dim)的元组
13     shuzu = zeros((k, dim))  #创建k行dim列的数组
14     for i in range(k):
15         index = int(random.uniform(0, len_line)) #uniform()方法将随机生成下一个实数,它在[x,y]范围内。
16         shuzu[i, :] = data[index, :]
17     return shuzu
18
19 # k-means cluster
20 def kmeans(data, k):
21     len_line = data.shape[0]  #读取数组第一行的长度
22
23
24     clusterAssment = mat(zeros((len_line, 2)))
25     clusterChanged = True
26
27     ## step 1: init centroids
28     centroids = initCentroids(data, k)
29
30     while clusterChanged:
31         clusterChanged = False
32         ## for each sample
33         for i in xrange(len_line):
34             minDist  = 100000.0
35             minIndex = 0
36             ## for each centroid
37             ## step 2: find the centroid who is closest
38             for j in range(k):
39                 distance = euclDistance(centroids[j, :], data[i, :])
40                 if distance < minDist:
41                     minDist  = distance
42                     minIndex = j
43
44             ## step 3: update its cluster
45             if clusterAssment[i, 0] != minIndex:
46                 clusterChanged = True
47                 clusterAssment[i, :] = minIndex, minDist**2
48
49         ## step 4: update centroids
50         for j in range(k):
51             pointsInCluster = data[nonzero(clusterAssment[:, 0].A == j)[0]]
52             centroids[j, :] = mean(pointsInCluster, axis = 0)
53
54     print ‘Congratulations, cluster complete!‘
55     return centroids, clusterAssment
56
57 # show your cluster only available with 2-D data
58 def showCluster(data, k, centroids, clusterAssment):
59     len_line, dim = data.shape
60     if dim != 2:
61         print "Sorry! I can not draw because the dimension of your data is not 2!"
62         return 1
63
64     mark = [‘or‘, ‘ob‘, ‘og‘, ‘ok‘, ‘^r‘, ‘+r‘, ‘sr‘, ‘dr‘, ‘<r‘, ‘pr‘]
65     if k > len(mark):
66         print "Sorry! Your k is too large! please contact Zouxy"
67         return 1
68
69     # draw all samples
70     for i in xrange(len_line):
71         markIndex = int(clusterAssment[i, 0])
72         plt.plot(data[i, 0], data[i, 1], mark[markIndex])
73
74     mark = [‘Dr‘, ‘Db‘, ‘Dg‘, ‘Dk‘, ‘^b‘, ‘+b‘, ‘sb‘, ‘db‘, ‘<b‘, ‘pb‘]
75     # draw the centroids
76     for i in range(k):
77         plt.plot(centroids[i, 0], centroids[i, 1], mark[i], markersize = 12)
78
79     plt.show()

三、测试结果

下面是80个样本,分成4个类

    1.658985    4.285136
    -3.453687   3.424321
    4.838138    -1.151539
    -5.379713   -3.362104
    0.972564    2.924086
    -3.567919   1.531611
    0.450614    -3.302219
    -3.487105   -1.724432
    2.668759    1.594842
    -3.156485   3.191137
    3.165506    -3.999838
    -2.786837   -3.099354
    4.208187    2.984927
    -2.123337   2.943366
    0.704199    -0.479481
    -0.392370   -3.963704
    2.831667    1.574018
    -0.790153   3.343144
    2.943496    -3.357075
    -3.195883   -2.283926
    2.336445    2.875106
    -1.786345   2.554248
    2.190101    -1.906020
    -3.403367   -2.778288
    1.778124    3.880832
    -1.688346   2.230267
    2.592976    -2.054368
    -4.007257   -3.207066
    2.257734    3.387564
    -2.679011   0.785119
    0.939512    -4.023563
    -3.674424   -2.261084
    2.046259    2.735279
    -3.189470   1.780269
    4.372646    -0.822248
    -2.579316   -3.497576
    1.889034    5.190400
    -0.798747   2.185588
    2.836520    -2.658556
    -3.837877   -3.253815
    2.096701    3.886007
    -2.709034   2.923887
    3.367037    -3.184789
    -2.121479   -4.232586
    2.329546    3.179764
    -3.284816   3.273099
    3.091414    -3.815232
    -3.762093   -2.432191
    3.542056    2.778832
    -1.736822   4.241041
    2.127073    -2.983680
    -4.323818   -3.938116
    3.792121    5.135768
    -4.786473   3.358547
    2.624081    -3.260715
    -4.009299   -2.978115
    2.493525    1.963710
    -2.513661   2.642162
    1.864375    -3.176309
    -3.171184   -3.572452
    2.894220    2.489128
    -2.562539   2.884438
    3.491078    -3.947487
    -2.565729   -2.012114
    3.332948    3.983102
    -1.616805   3.573188
    2.280615    -2.559444
    -2.651229   -3.103198
    2.321395    3.154987
    -1.685703   2.939697
    3.031012    -3.620252
    -4.599622   -2.185829
    4.196223    1.126677
    -2.133863   3.093686
    4.668892    -2.562705
    -2.793241   -2.149706
    2.884105    3.043438
    -2.967647   2.848696
    4.479332    -1.764772
    -4.905566   -2.911070

测试代码:

#################################################
# kmeans: k-means cluster
# Author : zouxy
# Date   : 2013-12-25
# HomePage : http://blog.csdn.net/zouxy09
# Email  : zouxy09@qq.com
#################################################  

from numpy import *
import time
import matplotlib.pyplot as plt  

## step 1: load data
print "step 1: load data..."
dataSet = []
fileIn = open(‘E:/Python/Machine Learning in Action/testSet.txt‘)
for line in fileIn.readlines():
    lineArr = line.strip().split(‘\t‘)
    dataSet.append([float(lineArr[0]), float(lineArr[1])])  

## step 2: clustering...
print "step 2: clustering..."
dataSet = mat(dataSet)
k = 4
centroids, clusterAssment = kmeans(dataSet, k)  

## step 3: show the result
print "step 3: show the result..."
showCluster(dataSet, k, centroids, clusterAssment) 

运行的前后结果是:

不同的类用不同的颜色来表示,其中的大菱形是对应类的均值质心点。

时间: 2024-08-26 08:58:12

Python实现K-means聚类算法的相关文章

k-均值聚类算法;二分k均值聚类算法

根据<机器学习实战>一书第十章学习k均值聚类算法和二分k均值聚类算法,自己把代码边敲边理解了一下,修正了一些原书中代码的细微差错.目前代码有时会出现如下4种报错信息,这有待继续探究和完善. 报错信息: Warning (from warnings module): File "F:\Python2.7.6\lib\site-packages\numpy\core\_methods.py", line 55 warnings.warn("Mean of empty

机器学习经典算法具体解释及Python实现--K近邻(KNN)算法

(一)KNN依旧是一种监督学习算法 KNN(K Nearest Neighbors,K近邻 )算法是机器学习全部算法中理论最简单.最好理解的.KNN是一种基于实例的学习,通过计算新数据与训练数据特征值之间的距离,然后选取K(K>=1)个距离近期的邻居进行分类推断(投票法)或者回归.假设K=1.那么新数据被简单分配给其近邻的类.KNN算法算是监督学习还是无监督学习呢?首先来看一下监督学习和无监督学习的定义.对于监督学习.数据都有明白的label(分类针对离散分布,回归针对连续分布),依据机器学习产

机器学习实战笔记-利用K均值聚类算法对未标注数据分组

聚类是一种无监督的学习,它将相似的对象归到同一个簇中.它有点像全自动分类.聚类方法几乎可以应用于所有对象,簇内的对象越相似,聚类的效果越好 簇识别给出聚类结果的含义.假定有一些数据,现在将相似数据归到一起,簇识别会告诉我们这些簇到底都是些什么.聚类与分类的最大不同在于,分类的目标事先巳知,而聚类则不一样.因为其产生的结果与分类相同,而只是类别没有预先定义,聚类有时也被称为无监督分类(unsupervised classification ). 聚类分析试图将相似对象归人同一簇,将不相似对象归到不

K均值聚类算法

k均值聚类算法(k-means clustering algorithm)是一种迭代求解的聚类分析算法,其步骤是随机选取K个对象作为初始的聚类中心,然后计算每个对象与各个种子聚类中心之间的距离,把每个对象分配给距离它最近的聚类中心.聚类中心以及分配给它们的对象就代表一个聚类.每分配一个样本,聚类的聚类中心会根据聚类中现有的对象被重新计算.这个过程将不断重复直到满足某个终止条件.终止条件可以是没有(或最小数目)对象被重新分配给不同的聚类,没有(或最小数目)聚类中心再发生变化,误差平方和局部最小.

机器学习经典算法详解及Python实现--K近邻(KNN)算法

(一)KNN依然是一种监督学习算法 KNN(K Nearest Neighbors,K近邻 )算法是机器学习所有算法中理论最简单,最好理解的.KNN是一种基于实例的学习,通过计算新数据与训练数据特征值之间的距离,然后选取K(K>=1)个距离最近的邻居进行分类判断(投票法)或者回归.如果K=1,那么新数据被简单分配给其近邻的类.KNN算法算是监督学习还是无监督学习呢?首先来看一下监督学习和无监督学习的定义.对于监督学习,数据都有明确的label(分类针对离散分布,回归针对连续分布),根据机器学习产

基于改进人工蜂群算法的K均值聚类算法(附MATLAB版源代码)

其实一直以来也没有准备在园子里发这样的文章,相对来说,算法改进放在园子里还是会稍稍显得格格不入.但是最近邮箱收到的几封邮件让我觉得有必要通过我的博客把过去做过的东西分享出去更给更多需要的人.从论文刊登后,陆陆续续收到本科生.研究生还有博士生的来信和短信微信等,表示了对论文的兴趣以及寻求算法的效果和实现细节,所以,我也就通过邮件或者短信微信来回信,但是有时候也会忘记回复. 另外一个原因也是时间久了,我对于论文以及改进的算法的记忆也越来越模糊,或者那天无意间把代码遗失在哪个角落,真的很难想象我还会全

K均值聚类算法的MATLAB实现

1.K-均值聚类法的概述 之前在参加数学建模的过程中用到过这种聚类方法,但是当时只是简单知道了在matlab中如何调用工具箱进行聚类,并不是特别清楚它的原理.最近因为在学模式识别,又重新接触了这种聚类算法,所以便仔细地研究了一下它的原理.弄懂了之后就自己手工用matlab编程实现了,最后的结果还不错,嘿嘿~~~ 简单来说,K-均值聚类就是在给定了一组样本(x1, x2, ...xn) (xi, i = 1, 2, ... n均是向量) 之后,假设要将其聚为 m(<n) 类,可以按照如下的步骤实现

k means聚类过程

k-means是一种非监督 (从下图0 当中我们可以看到训练数据并没有标签标注类别)的聚类算法 0.initial 1.select centroids randomly 2.assign points 3.update centroids 4.reassign points 5.update centroids 6.reassign points 7.iteration reference: https://www.naftaliharris.com/blog/visualizing-k-me

吴裕雄 python 机器学习——K均值聚类KMeans模型

import numpy as np import matplotlib.pyplot as plt from sklearn import cluster from sklearn.metrics import adjusted_rand_score from sklearn.datasets.samples_generator import make_blobs def create_data(centers,num=100,std=0.7): X, labels_true = make_b

机器学习经典算法详解及Python实现--聚类及K均值、二分K-均值聚类算法

摘要 聚类是一种无监督的学习(无监督学习不依赖预先定义的类或带类标记的训练实例),它将相似的对象归到同一个簇中,它是观察式学习,而非示例式的学习,有点像全自动分类.说白了,聚类(clustering)是完全可以按字面意思来理解的--将相同.相似.相近.相关的对象实例聚成一类的过程.机器学习中常见的聚类算法包括 k-Means算法.期望最大化算法(Expectation Maximization,EM,参考"EM算法原理").谱聚类算法(参考机器学习算法复习-谱聚类)以及人工神经网络算法