python中实现k-means聚类算法详解

作者:mrbean 时间:2021-07-18 21:42:49 

算法优缺点:

优点:容易实现
缺点:可能收敛到局部最小值,在大规模数据集上收敛较慢
使用数据类型:数值型数据

算法思想

k-means算法实际上就是通过计算不同样本间的距离来判断他们的相近关系的,相近的就会放到同一个类别中去。

1.首先我们需要选择一个k值,也就是我们希望把数据分成多少类,这里k值的选择对结果的影响很大,Ng的课说的选择方法有两种一种是elbow method,简单的说就是根据聚类的结果和k的函数关系判断k为多少的时候效果最好。另一种则是根据具体的需求确定,比如说进行衬衫尺寸的聚类你可能就会考虑分成三类(L,M,S)等

2.然后我们需要选择最初的聚类点(或者叫质心),这里的选择一般是随机选择的,代码中的是在数据范围内随机选择,另一种是随机选择数据中的点。这些点的选择会很大程度上影响到最终的结果,也就是说运气不好的话就到局部最小值去了。这里有两种处理方法,一种是多次取均值,另一种则是后面的改进算法(bisecting K-means)

3.终于我们开始进入正题了,接下来我们会把数据集中所有的点都计算下与这些质心的距离,把它们分到离它们质心最近的那一类中去。完成后我们则需要将每个簇算出平均值,用这个点作为新的质心。反复重复这两步,直到收敛我们就得到了最终的结果。

函数

loadDataSet(fileName)

从文件中读取数据集

distEclud(vecA, vecB)

计算距离,这里用的是欧氏距离,当然其他合理的距离都是可以的

randCent(dataSet, k)

随机生成初始的质心,这里是虽具选取数据范围内的点

kMeans(dataSet, k, distMeas=distEclud, createCent=randCent)

kmeans算法,输入数据和k值。后面两个事可选的距离计算方式和初始质心的选择方式

show(dataSet, k, centroids, clusterAssment)

可视化结果


#coding=utf-8
from numpy import *
def loadDataSet(fileName):
dataMat = []
fr = open(fileName)
for line in fr.readlines():
curLine = line.strip().split('\t')
fltLine = map(float, curLine)
dataMat.append(fltLine)
return dataMat
#计算两个向量的距离,用的是欧几里得距离
def distEclud(vecA, vecB):
return sqrt(sum(power(vecA - vecB, 2)))
#随机生成初始的质心(ng的课说的初始方式是随机选K个点)
def randCent(dataSet, k):
n = shape(dataSet)[1]
centroids = mat(zeros((k,n)))
for j in range(n):
minJ = min(dataSet[:,j])
rangeJ = float(max(array(dataSet)[:,j]) - minJ)
centroids[:,j] = minJ + rangeJ * random.rand(k,1)
return centroids
def kMeans(dataSet, k, distMeas=distEclud, createCent=randCent):
m = shape(dataSet)[0]
clusterAssment = mat(zeros((m,2)))#create mat to assign data points
    #to a centroid, also holds SE of each point
centroids = createCent(dataSet, k)
clusterChanged = True
while clusterChanged:
clusterChanged = False
for i in range(m):#for each data point assign it to the closest centroid
 minDist = inf
 minIndex = -1
 for j in range(k):
 distJI = distMeas(centroids[j,:],dataSet[i,:])
 if distJI < minDist:
  minDist = distJI; minIndex = j
 if clusterAssment[i,0] != minIndex:
 clusterChanged = True
 clusterAssment[i,:] = minIndex,minDist**2
print centroids
for cent in range(k):#recalculate centroids
 ptsInClust = dataSet[nonzero(clusterAssment[:,0].A==cent)[0]]#get all the point in this cluster
 centroids[cent,:] = mean(ptsInClust, axis=0) #assign centroid to mean
return centroids, clusterAssment
def show(dataSet, k, centroids, clusterAssment):
from matplotlib import pyplot as plt
numSamples, dim = dataSet.shape
mark = ['or', 'ob', 'og', 'ok', '^r', '+r', 'sr', 'dr', '<r', 'pr']
for i in xrange(numSamples):
markIndex = int(clusterAssment[i, 0])
plt.plot(dataSet[i, 0], dataSet[i, 1], mark[markIndex])
mark = ['Dr', 'Db', 'Dg', 'Dk', '^b', '+b', 'sb', 'db', '<b', 'pb']
for i in range(k):
plt.plot(centroids[i, 0], centroids[i, 1], mark[i], markersize = 12)
plt.show()
def main():
dataMat = mat(loadDataSet('testSet.txt'))
myCentroids, clustAssing= kMeans(dataMat,4)
print myCentroids
show(dataMat, 4, myCentroids, clustAssing)

if __name__ == '__main__':
main()

这里是聚类结果,还是很不错的啦

python中实现k-means聚类算法详解

但是有时候也会收敛到局部最小值,就像下面这样,就是不幸收敛到局部最优了

python中实现k-means聚类算法详解

总结

Python内存管理方式和垃圾回收算法解析

Python数据结构与算法之列表(链表,linked list)简单实现

Python算法之求n个节点不同二叉树个数

有什么问题可以随时留言,小编会及时回复大家的。感谢朋友们对本站的支持!

来源:http://www.cnblogs.com/MrLJC/p/4127553.html

标签:python,kmeans聚类,算法
0
投稿

猜你喜欢

  • Python中使用haystack实现django全文检索搜索引擎功能

    2023-06-30 07:21:03
  • Django框架静态文件使用/中间件/禁用ip功能实例详解

    2023-06-12 02:48:38
  • javascript设计模式交流(二) Prototype Pattern

    2007-11-29 14:01:00
  • 使用批处理实现mysql的数据库备份与上传

    2012-01-05 19:30:23
  • 浅谈Python基础之I/O模型

    2021-11-17 18:38:03
  • JS实现仿Windows经典风格的选项卡Tab切换代码

    2023-08-25 05:33:54
  • python字典setdefault方法和get方法使用实例

    2023-11-23 21:13:15
  • sqlserver 查询数据库大小的方法

    2012-08-21 10:22:10
  • php获取referer防非法访问

    2023-08-20 11:30:58
  • python基础教程之分支、循环简单用法

    2021-05-30 08:51:48
  • Python中的pygal安装和绘制直方图代码分享

    2021-11-18 15:09:50
  • CSS的另类拼图___减少HTTP请求

    2009-05-28 19:05:00
  • 使用组件来保护你的ASP代码

    2008-06-03 13:47:00
  • python日期相关操作实例小结

    2021-07-14 18:39:13
  • 图片滤镜效果[IE Only]

    2009-06-14 19:49:00
  • Asp.net实现简单的文字水印

    2007-08-24 09:28:00
  • 解析Javascript中中括号“[]”的多义性

    2023-09-03 09:59:35
  • 关于JS中变量的显式声明和隐式声明

    2008-10-06 13:22:00
  • python递归下载文件夹下所有文件

    2023-08-07 07:21:55
  • Django使用HTTP协议向服务器传参方式小结

    2023-03-08 11:31:20
  • asp之家 网络编程 m.aspxhome.com