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的迭代器、生成器以及相关的itertools包
Apr 02 Python
基础的十进制按位运算总结与在Python中的计算示例
Jun 28 Python
python 获取指定文件夹下所有文件名称并写入列表的实例
Apr 23 Python
Python基于Logistic回归建模计算某银行在降低贷款拖欠率的数据示例
Jan 23 Python
通过python3实现投票功能代码实例
Sep 26 Python
python定间隔取点(np.linspace)的实现
Nov 27 Python
Python异常原理及异常捕捉实现过程解析
Mar 25 Python
python时间序列数据转为timestamp格式的方法
Aug 03 Python
python MD5加密的示例
Oct 19 Python
Django中的DateTimeField和DateField实现
Feb 24 Python
python基础之文件操作
Oct 24 Python
Python利用zhdate模块实现农历日期处理
Mar 31 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实现的MySQL通用查询程序
2007/03/11 PHP
php无限遍历文件夹示例分享
2014/03/04 PHP
Yii学习总结之安装配置
2015/02/22 PHP
php防止sql注入简单分析
2015/03/18 PHP
codeigniter显示所有脚本执行时间的方法
2015/03/21 PHP
为你总结一些php信息函数
2015/10/21 PHP
php实现贪吃蛇小游戏
2016/07/26 PHP
php实现的简单数据库操作Model类
2016/11/16 PHP
自定义jQuery选项卡插件实例
2013/03/27 Javascript
js加减乘除丢失精度问题解决方法
2014/05/16 Javascript
indexOf 和 lastIndexOf 使用示例介绍
2014/09/02 Javascript
JavaScript调用传递变量参数的相关问题及解决办法
2015/11/01 Javascript
javascript针对不确定函数的执行方法
2015/12/16 Javascript
Bootstrap Table使用方法详解
2016/08/01 Javascript
jQuery简单自定义图片轮播插件及用法示例
2016/11/21 Javascript
nuxt.js 缓存实践
2018/06/25 Javascript
Layui 带多选框表格监听事件以及按钮自动点击写法实例
2019/09/02 Javascript
Vue Render函数创建DOM节点代码实例
2020/07/08 Javascript
vue-列表下详情的展开与折叠案例
2020/07/28 Javascript
Vue ElementUI实现:限制输入框只能输入正整数的问题
2020/07/31 Javascript
[31:47]夜魇凡尔赛茶话会 第三期01:选手知多少
2021/03/11 DOTA
python获取各操作系统硬件信息的方法
2015/06/03 Python
Python logging管理不同级别log打印和存储实例
2018/01/19 Python
python实现求解列表中元素的排列和组合问题
2018/03/15 Python
Python针对给定字符串求解所有子序列是否为回文序列的方法
2018/04/21 Python
python调用自定义函数的实例操作
2019/06/26 Python
Django ImageFiled上传照片并显示的方法
2019/07/28 Python
Centos7下源码安装Python3 及shell 脚本自动安装Python3的教程
2020/03/07 Python
CSS3的新特性介绍
2008/10/31 HTML / CSS
CSS3 实现的加载动画
2020/12/07 HTML / CSS
物流专业大学生职业生涯规划书范文
2014/01/15 职场文书
入党自荐书范文
2014/03/09 职场文书
Redis IP地址的绑定的实现
2021/05/08 Redis
Ajax请求超时与网络异常处理图文详解
2021/05/23 Javascript
教你怎么用python selenium实现自动化测试
2021/05/27 Python
基于Redis结合SpringBoot的秒杀案例详解
2021/10/05 Redis