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以环状形式组合排列图片并输出的方法
Mar 17 Python
30分钟搭建Python的Flask框架并在上面编写第一个应用
Mar 30 Python
Python函数返回值实例分析
Jun 08 Python
Python实现将罗马数字转换成普通阿拉伯数字的方法
Apr 19 Python
Python实现针对含中文字符串的截取功能示例
Sep 22 Python
详解分布式任务队列Celery使用说明
Nov 29 Python
在python2.7中用numpy.reshape 对图像进行切割的方法
Dec 05 Python
将python文件打包成EXE应用程序的方法
May 22 Python
用Q-learning算法实现自动走迷宫机器人的方法示例
Jun 03 Python
python动态视频下载器的实现方法
Sep 16 Python
Pandas数据分析的一些常用小技巧
Feb 07 Python
python使用XPath解析数据爬取起点小说网数据
Apr 22 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
CodeIgniter php mvc框架 中国网站
2008/05/26 PHP
php错误提示failed to open stream: HTTP request failed!的完美解决方法
2011/06/06 PHP
PHP登录(ajax提交数据和后台校验)实例分享
2016/12/29 PHP
PHP 扩展Memcached命令用法实例总结
2020/06/04 PHP
jQuery学习笔记之jQuery的DOM操作
2010/12/22 Javascript
Javascript学习笔记之 对象篇(四) : for in 循环
2014/06/24 Javascript
jquery使用remove()方法删除指定class子元素
2015/03/26 Javascript
JavaScript实现点击按钮字体放大、缩小
2016/02/29 Javascript
详解Javascript几种跨域方式总结
2017/02/27 Javascript
vue实现登陆登出的实现示例
2017/09/15 Javascript
jquery中有哪些api jQuery主要API
2017/11/20 jQuery
vue-content-loader内容加载器的使用方法
2018/08/05 Javascript
NodeJs实现简单的爬虫功能案例分析
2018/12/05 NodeJs
Vue事件修饰符native、self示例详解
2019/07/09 Javascript
JavaScript在web自动化测试中的作用示例详解
2019/08/25 Javascript
vue深度监听(监听对象和数组的改变)与立即执行监听实例
2020/09/04 Javascript
跟老齐学Python之开始真正编程
2014/09/12 Python
Python的Bottle框架中实现最基本的get和post的方法的教程
2015/04/30 Python
Python中运算符&quot;==&quot;和&quot;is&quot;的详解
2016/10/08 Python
python爬虫获取多页天涯帖子
2018/02/23 Python
python匹配两个短语之间的字符实例
2018/12/25 Python
详解安装mitmproxy以及遇到的坑和简单用法
2019/01/21 Python
PyQt5的PyQtGraph实践系列3之实时数据更新绘制图形
2019/05/13 Python
在python plt图表中文字大小调节的方法
2019/07/08 Python
利用python list完成最简单的DB连接池方法
2019/08/09 Python
Python如何使用字符打印照片
2020/01/03 Python
前台文员岗位职责及工作流程
2013/11/19 职场文书
投标单位介绍信
2014/01/09 职场文书
共筑中国梦演讲稿
2014/04/23 职场文书
三好生演讲稿
2014/09/12 职场文书
2014年基建工作总结
2014/12/12 职场文书
小学语文教师年度考核个人总结
2015/02/05 职场文书
结婚通知短信怎么写
2015/04/17 职场文书
开除员工通知
2015/04/22 职场文书
python实现腾讯滑块验证码识别
2021/04/27 Python
Python 读写 Matlab Mat 格式数据的操作
2021/05/19 Python