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实现的简单文本类游戏实例
Apr 28 Python
详解Python中heapq模块的用法
Jun 28 Python
python实现发送邮件及附件功能
Mar 02 Python
python利用OpenCV2实现人脸检测
Apr 16 Python
python使用tkinter实现简单计算器
Jan 30 Python
详解Python中的type和object
Aug 15 Python
python读取文件指定行内容实例讲解
Mar 02 Python
django queryset 去重 .distinct()说明
May 19 Python
Keras模型转成tensorflow的.pb操作
Jul 06 Python
python openCV自制绘画板
Oct 27 Python
详解用Python把PDF转为Word方法总结
Apr 27 Python
Python pandas之求和运算和非空值个数统计
Aug 07 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中文件读、写、删的操作(PHP中对文件和目录操作)
2012/03/06 PHP
php写的带缓存数据功能的mysqli类
2012/09/06 PHP
php另类上传图片的方法(PHP用Socket上传图片)
2013/10/30 PHP
PHP实现上传图片到数据库并显示输出的方法
2018/05/31 PHP
php获取微信基础接口凭证Access_token
2018/08/23 PHP
PHP随机生成中文段落示例【测试网站内容时使用】
2020/04/26 PHP
JQuery 遮罩层实现(mask)实现代码
2010/01/09 Javascript
javascript之querySelector和querySelectorAll使用说明
2011/10/09 Javascript
JavaScript 判断用户输入的邮箱及手机格式是否正确
2013/12/08 Javascript
js+css实现超简洁的二级下拉菜单效果代码
2015/09/07 Javascript
浅析在javascript中创建对象的各种模式
2016/05/06 Javascript
JS加载器如何动态加载外部js文件
2016/05/26 Javascript
js 弹出虚拟键盘修改密码的简单实例
2016/10/10 Javascript
Bootstrap CSS布局之图像
2016/12/17 Javascript
jQuery实现字符串全部替换的方法【推荐】
2017/03/09 Javascript
EasyUI的DataGrid绑定Json数据源的示例代码
2017/12/16 Javascript
使用preload预加载页面资源时注意事项
2020/02/03 Javascript
使用nodeJS中的fs模块对文件及目录进行读写,删除,追加,等操作详解
2020/02/06 NodeJs
Python学习笔记(二)基础语法
2014/06/06 Python
Python import自定义模块方法
2015/02/12 Python
教你使用python实现微信每天给女朋友说晚安
2018/03/23 Python
python3 遍历删除特定后缀名文件的方法
2018/04/23 Python
Django+Ajax+jQuery实现网页动态更新的实例
2018/05/28 Python
python和opencv实现抠图
2018/07/18 Python
Python从函数参数类型引出元组实例分析
2019/05/28 Python
python实现H2O中的随机森林算法介绍及其项目实战
2019/08/29 Python
浅谈Django2.0 加xadmin踩的坑
2019/11/15 Python
使用Pandas将inf, nan转化成特定的值
2019/12/19 Python
如何基于python实现年会抽奖工具
2020/10/20 Python
CSS3 实现弹跳的小球动画
2020/10/26 HTML / CSS
跑步爱好者一站式服务网站:Jack Rabbit
2016/09/01 全球购物
学生实习自我鉴定
2013/10/11 职场文书
幼儿园小班教学反思
2014/02/02 职场文书
青年文明号创建承诺
2014/03/31 职场文书
环境保护与污染治理求职信
2014/07/16 职场文书
领导走群众路线整改措施思想汇报
2014/10/12 职场文书