K-means聚类算法介绍与利用python实现的代码示例


Posted in Python onNovember 13, 2017

聚类

今天说K-means聚类算法,但是必须要先理解聚类和分类的区别,很多业务人员在日常分析时候不是很严谨,混为一谈,其实二者有本质的区别。

分类其实是从特定的数据中挖掘模式,作出判断的过程。比如Gmail邮箱里有垃圾邮件分类器,一开始的时候可能什么都不过滤,在日常使用过程中,我人工对于每一封邮件点选“垃圾”或“不是垃圾”,过一段时间,Gmail就体现出一定的智能,能够自动过滤掉一些垃圾邮件了。这是因为在点选的过程中,其实是给每一条邮件打了一个“标签”,这个标签只有两个值,要么是“垃圾”,要么“不是垃圾”,Gmail就会不断研究哪些特点的邮件是垃圾,哪些特点的不是垃圾,形成一些判别的模式,这样当一封信的邮件到来,就可以自动把邮件分到“垃圾”和“不是垃圾”这两个我们人工设定的分类的其中一个。

聚类的的目的也是把数据分类,但是事先我是不知道如何去分的,完全是算法自己来判断各条数据之间的相似性,相似的就放在一起。在聚类的结论出来之前,我完全不知道每一类有什么特点,一定要根据聚类的结果通过人的经验来分析,看看聚成的这一类大概有什么特点。

1、概述

k-means是一种非常常见的聚类算法,在处理聚类任务中经常使用。K-means算法是集简单和经典于一身的基于距离的聚类算法

采用距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度就越大。

该算法认为类簇是由距离靠近的对象组成的,因此把得到紧凑且独立的簇作为最终目标。

2、核心思想

通过迭代寻找k个类簇的一种划分方案,使得用这k个类簇的均值来代表相应各类样本时所得的总体误差最小。

k个聚类具有以下特点:各聚类本身尽可能的紧凑,而各聚类之间尽可能的分开。

k-means算法的基础是最小误差平方和准则,

其代价函数是:

K-means聚类算法介绍与利用python实现的代码示例

式中,μc(i)表示第i个聚类的均值。

各类簇内的样本越相似,其与该类均值间的误差平方越小,对所有类所得到的误差平方求和,即可验证分为k类时,各聚类是否是最优的。

上式的代价函数无法用解析的方法最小化,只能有迭代的方法。

3、算法步骤图解

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

K-means聚类算法介绍与利用python实现的代码示例

4、算法实现步骤

k-means算法是将样本聚类成 k个簇(cluster),其中k是用户给定的,其求解过程非常直观简单,具体算法描述如下:

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

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

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

K-means聚类算法介绍与利用python实现的代码示例

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

K-means聚类算法介绍与利用python实现的代码示例

}

其伪代码如下:

******************************************************************************

创建k个点作为初始的质心点(随机选择)

当任意一个点的簇分配结果发生改变时

      对数据集中的每一个数据点

          对每一个质心

              计算质心与数据点的距离

将数据点分配到距离最近的簇

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

********************************************************

5、K-means聚类算法python实战

需求:

对给定的数据集进行聚类

本案例采用二维数据集,共80个样本,有4个类。

K-means聚类算法介绍与利用python实现的代码示例

#!/usr/bin/python
# coding=utf-8
from numpy import *
# 加载数据
def loadDataSet(fileName): # 解析文件,按tab分割字段,得到一个浮点数字类型的矩阵
  dataMat = []       # 文件的最后一个字段是类别标签
  fr = open(fileName)
  for line in fr.readlines():
    curLine = line.strip().split('\t')
    fltLine = map(float, curLine)  # 将每个元素转成float类型
    dataMat.append(fltLine)
  return dataMat

# 计算欧几里得距离
def distEclud(vecA, vecB):
  return sqrt(sum(power(vecA - vecB, 2))) # 求两个向量之间的距离

# 构建聚簇中心,取k个(此例中为4)随机质心
def randCent(dataSet, k):
  n = shape(dataSet)[1]
  centroids = mat(zeros((k,n)))  # 每个质心有n个坐标值,总共要k个质心
  for j in range(n):
    minJ = min(dataSet[:,j])
    maxJ = max(dataSet[:,j])
    rangeJ = float(maxJ - minJ)
    centroids[:,j] = minJ + rangeJ * random.rand(k, 1)
  return centroids

# k-means 聚类算法
def kMeans(dataSet, k, distMeans =distEclud, createCent = randCent):
  m = shape(dataSet)[0]
  clusterAssment = mat(zeros((m,2)))  # 用于存放该样本属于哪类及质心距离
  # clusterAssment第一列存放该数据所属的中心点,第二列是该数据到中心点的距离
  centroids = createCent(dataSet, k)
  clusterChanged = True  # 用来判断聚类是否已经收敛
  while clusterChanged:
    clusterChanged = False;
    for i in range(m): # 把每一个数据点划分到离它最近的中心点
      minDist = inf; minIndex = -1;
      for j in range(k):
        distJI = distMeans(centroids[j,:], dataSet[i,:])
        if distJI < minDist:
          minDist = distJI; minIndex = j # 如果第i个数据点到第j个中心点更近,则将i归属为j
      if clusterAssment[i,0] != minIndex: clusterChanged = True; # 如果分配发生变化,则需要继续迭代
      clusterAssment[i,:] = minIndex,minDist**2  # 并将第i个数据点的分配情况存入字典
    print centroids
    for cent in range(k):  # 重新计算中心点
      ptsInClust = dataSet[nonzero(clusterAssment[:,0].A == cent)[0]]  # 去第一列等于cent的所有列
      centroids[cent,:] = mean(ptsInClust, axis = 0) # 算出这些数据的中心点
  return centroids, clusterAssment
# --------------------测试----------------------------------------------------
# 用测试数据及测试kmeans算法
datMat = mat(loadDataSet('testSet.txt'))
myCentroids,clustAssing = kMeans(datMat,4)
print myCentroids
print clustAssing

运行结果:

K-means聚类算法介绍与利用python实现的代码示例

6、K-means算法补充

K-means算法的缺点及改进方法

(1)k值的选择是用户指定的,不同的k得到的结果会有挺大的不同,如下图所示,左边是k=3的结果,这个就太稀疏了,蓝色的那个簇其实是可以再划分成两个簇的。而右图是k=5的结果,可以看到红色菱形和蓝色菱形这两个簇应该是可以合并成一个簇的:

改进:

对k的选择可以先用一些算法分析数据的分布,如重心和密度等,然后选择合适的k

K-means聚类算法介绍与利用python实现的代码示例

(2)对k个初始质心的选择比较敏感,容易陷入局部最小值。例如,我们上面的算法运行的时候,有可能会得到不同的结果,如下面这两种情况。K-means也是收敛了,只是收敛到了局部最小值:

改进:

有人提出了另一个成为二分k均值(bisecting k-means)算法,它对初始的k个质心的选择就不太敏感

K-means聚类算法介绍与利用python实现的代码示例

(3)存在局限性,如下面这种非球状的数据分布就搞不定了:

K-means聚类算法介绍与利用python实现的代码示例

(4)数据集比较大的时候,收敛会比较慢。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
python 将字符串转换成字典dict
Mar 24 Python
使用python分析git log日志示例
Feb 27 Python
Python入门学习之字符串与比较运算符
Oct 12 Python
Python使用正则表达式实现文本替换的方法
Apr 18 Python
关于Python的一些学习总结
May 25 Python
基于DataFrame改变列类型的方法
Jul 25 Python
用python代码将tiff图片存储到jpg的方法
Dec 04 Python
Python list列表中删除多个重复元素操作示例
Feb 27 Python
使用Python轻松完成垃圾分类(基于图像识别)
Jul 09 Python
Python中使用threading.Event协调线程的运行详解
May 02 Python
520使用Python实现“我爱你”表白
May 20 Python
celery在python爬虫中定时操作实例讲解
Nov 27 Python
python通过opencv实现批量剪切图片
Nov 13 #Python
flask + pymysql操作Mysql数据库的实例
Nov 13 #Python
django之session与分页(实例讲解)
Nov 13 #Python
python实现图片处理和特征提取详解
Nov 13 #Python
Queue 实现生产者消费者模型(实例讲解)
Nov 13 #Python
python图像常规操作
Nov 11 #Python
python中实现k-means聚类算法详解
Nov 11 #Python
You might like
php trim 去除空字符的定义与语法介绍
2010/05/31 PHP
php读取csv实现csv文件下载功能
2013/12/18 PHP
ThinkPHP多表联合查询的常用方法
2020/03/24 PHP
PHP获取当前所在目录位置的方法
2014/11/26 PHP
javascript tips提示框组件实现代码
2010/11/19 Javascript
Javascript的各种节点操作实例演示代码
2012/06/27 Javascript
Jquery动态替换div内容及动态展示的方法
2015/01/23 Javascript
无刷新上传文件并返回自定义值
2015/06/11 Javascript
JS实现放大、缩小及拖拽图片的方法【可兼容IE、火狐】
2016/08/23 Javascript
深入理解AngularJS中的ng-bind-html指令和$sce服务
2016/09/08 Javascript
纯js实现手风琴效果代码
2020/04/17 Javascript
vue2.0开发实践总结之疑难篇
2016/12/07 Javascript
Bootstrap源码解读网格系统(3)
2016/12/22 Javascript
JavaScript定义全局对象的方法示例
2017/01/12 Javascript
layui选项卡效果实现代码
2017/05/19 Javascript
bootstrap table实现双击可编辑、添加、删除行功能
2017/09/27 Javascript
angular.js实现列表orderby排序的方法
2018/10/02 Javascript
JS调用安卓手机摄像头扫描二维码
2018/10/16 Javascript
微信小程序实现同时上传多张图片
2020/02/03 Javascript
Vue中key的作用示例代码详解
2020/06/10 Javascript
vue切换菜单取消未完成接口请求的案例
2020/11/13 Javascript
python检测lvs real server状态
2014/01/22 Python
浅析Python中的序列化存储的方法
2015/04/28 Python
微信 用脚本查看是否被微信好友删除
2016/10/28 Python
如何实现删除numpy.array中的行或列
2018/05/08 Python
windows下的pycharm安装及其设置中文菜单
2020/04/23 Python
cookies应对python反爬虫知识点详解
2020/11/25 Python
css3实现元素环绕中心点布局的方法示例
2019/01/15 HTML / CSS
中国海淘族值得信赖的海淘返利网站:55海淘
2017/01/16 全球购物
C++如何引用一个已经定义过的全局变量
2014/08/25 面试题
管理站站长岗位职责
2013/11/27 职场文书
干部现实表现材料
2014/02/13 职场文书
局机关干部群众路线个人对照检查材料思想汇报
2014/10/05 职场文书
拾金不昧通报表扬范文
2015/05/05 职场文书
建议书的格式及范文
2015/09/14 职场文书
关于python中readlines函数的参数hint的相关知识总结
2021/06/24 Python