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


Posted in Python onNovember 11, 2017

算法优缺点:

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

算法思想

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中实现k-means聚类算法详解的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站:

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

Python 相关文章推荐
python实现获取序列中最小的几个元素
Sep 25 Python
python获取Linux下文件版本信息、公司名和产品名的方法
Oct 05 Python
基于python编写的微博应用
Oct 17 Python
Python中如何获取类属性的列表
Dec 26 Python
python:socket传输大文件示例
Jan 18 Python
Python实现网站注册验证码生成类
Jun 08 Python
kali中python版本的切换方法
Jul 11 Python
Python进阶之使用selenium爬取淘宝商品信息功能示例
Sep 16 Python
利用4行Python代码监测每一行程序的运行时间和空间消耗
Apr 22 Python
用python进行视频剪辑
Nov 02 Python
python通过opencv调用摄像头操作实例分析
Jun 07 Python
python​格式化字符串
Apr 20 Python
Python编程之基于概率论的分类方法:朴素贝叶斯
Nov 11 #Python
Python内存管理方式和垃圾回收算法解析
Nov 11 #Python
Python实现的人工神经网络算法示例【基于反向传播算法】
Nov 11 #Python
python中使用正则表达式的后向搜索肯定模式(推荐)
Nov 11 #Python
python基础练习之几个简单的游戏
Nov 10 #Python
Python实现购物车功能的方法分析
Nov 10 #Python
Python实现的单向循环链表功能示例
Nov 10 #Python
You might like
php防注入,表单提交值转义的实现详解
2013/06/10 PHP
3种php生成唯一id的方法
2015/11/23 PHP
PHP消息队列实现及应用详解【队列处理订单系统和配送系统】
2019/05/20 PHP
laravel入门知识点整理
2020/09/15 PHP
JQUERY操作JSON实例代码
2010/02/09 Javascript
Jquery实现由下向上展开效果的例子
2014/12/08 Javascript
js使用split函数按照多个字符对字符串进行分割的方法
2015/03/20 Javascript
JS遍历ul下的li点击弹出li的索引的实现方法
2016/09/19 Javascript
jquery.Jcrop结合JAVA后台实现图片裁剪上传实例
2016/11/05 Javascript
JavaScript实现前端实时搜索功能
2020/03/26 Javascript
Vue.js实现数据响应的方法
2018/08/13 Javascript
Nodejs中获取当前函数被调用的行数及文件名详解
2018/12/12 NodeJs
Vue.js实现可排序的表格组件功能示例
2019/02/19 Javascript
微信小程序实现的一键连接wifi功能示例
2019/04/24 Javascript
JS简单数组排序操作示例【sort方法】
2019/05/17 Javascript
[01:50]2014DOTA2西雅图邀请赛 专访欢乐周宝龙
2014/07/08 DOTA
python中 ? : 三元表达式的使用介绍
2013/10/09 Python
python命令行参数sys.argv使用示例
2014/01/28 Python
python求素数示例分享
2014/02/16 Python
深入理解python函数递归和生成器
2016/06/06 Python
Python实现的根据IP地址计算子网掩码位数功能示例
2018/05/23 Python
django的ORM操作 增加和查询
2019/07/26 Python
基于Python词云分析政府工作报告关键词
2020/06/02 Python
python安装cx_Oracle和wxPython的方法
2020/09/14 Python
html5调用摄像头功能的实现代码
2018/05/07 HTML / CSS
ECCO爱步美国官网:来自丹麦的鞋履品牌
2016/11/23 全球购物
优秀教师获奖感言
2014/01/31 职场文书
乱丢垃圾袋检讨书
2014/10/08 职场文书
离婚协议书范本(通用篇)
2014/11/30 职场文书
毕业生班级鉴定评语
2015/01/04 职场文书
父亲节活动总结
2015/02/12 职场文书
2015年客房服务员工作总结
2015/05/15 职场文书
开业庆典致辞
2015/08/01 职场文书
迎国庆主题班会
2015/08/17 职场文书
2015年幼师个人工作总结
2015/10/15 职场文书
MySQL去除重叠时间求时间差和的实现
2021/08/23 MySQL