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批量修改文件后缀示例代码分享
Dec 24 Python
python之wxPython应用实例
Sep 28 Python
python中循环语句while用法实例
May 16 Python
pygame播放音乐的方法
May 19 Python
关于python pyqt5安装失败问题的解决方法
Aug 08 Python
python中文分词,使用结巴分词对python进行分词(实例讲解)
Nov 14 Python
Flask和Django框架中自定义模型类的表名、父类相关问题分析
Jul 19 Python
详解python执行shell脚本创建用户及相关操作
Apr 11 Python
Selenium+Python 自动化操控登录界面实例(有简单验证码图片校验)
Jun 28 Python
用sleep间隔进行python反爬虫的实例讲解
Nov 30 Python
如何用PyPy让你的Python代码运行得更快
Dec 02 Python
python3 字符串str和bytes相互转换
Mar 23 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
声音就能俘获人心,蕾姆,是哪个漂亮小姐姐配音呢?
2020/03/03 日漫
有道搜索和IP138的IP的API接口(PHP应用)
2012/11/29 PHP
详解PHP中的 input属性(隐藏 只读 限制)
2017/08/14 PHP
PHP时间日期增减操作示例【date strtotime实现加一天、加一月等操作】
2018/12/21 PHP
浅谈laravel-admin的sortable和orderby使用问题
2019/10/03 PHP
Laravel实现ApiToken认证请求
2019/10/14 PHP
mapper--图片热点区域高亮组件官方站点
2007/12/22 Javascript
锋利的jQuery 要点归纳(一) jQuery选择器
2010/03/21 Javascript
js实现简单的验证码
2015/12/25 Javascript
js实现的简单图片浮动效果完整实例
2016/05/10 Javascript
微信小程序 闭包写法详细介绍
2016/12/14 Javascript
AngularJS中$http的交互问题
2017/03/29 Javascript
js实现把时间戳转换为yyyy-MM-dd hh:mm 格式(es6语法)
2017/12/28 Javascript
Vue-cli@3.0 插件系统简析
2018/09/05 Javascript
基于vue框架手写一个notify插件实现通知功能的方法
2019/03/31 Javascript
详解JQuery基础动画操作
2019/04/12 jQuery
VUE项目中加载已保存的笔记实例方法
2019/09/14 Javascript
JavaScript命令模式原理与用法实例详解
2020/03/10 Javascript
[36:02]DOTA2上海特级锦标赛D组小组赛#2 Liquid VS VP第一局
2016/02/28 DOTA
[51:27]LGD vs Liquid 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/19 DOTA
[01:04:20]完美世界DOTA2联赛PWL S2 LBZS vs Forest 第一场 11.29
2020/12/02 DOTA
在Django中创建URLconf相关的通用视图的方法
2015/07/20 Python
实例讲解Python中浮点型的基本内容
2019/02/11 Python
Python3实现的简单工资管理系统示例
2019/03/12 Python
基于Python安装pyecharts所遇的问题及解决方法
2019/08/12 Python
Python Django实现layui风格+django分页功能的例子
2019/08/29 Python
Python MongoDB 插入数据时已存在则不执行,不存在则插入的解决方法
2019/09/24 Python
在tensorflow中实现去除不足一个batch的数据
2020/01/20 Python
python里反向传播算法详解
2020/11/22 Python
美国潜水装备、水肺潜水和浮潜设备商店:Leisure Pro
2018/08/08 全球购物
手工制作的意大利太阳镜和光学元件:Illesteva
2019/01/19 全球购物
老师自我鉴定范文
2013/12/25 职场文书
《放飞蜻蜓》教学反思
2014/04/27 职场文书
2015年会计年终工作总结
2015/05/26 职场文书
新闻报道稿范文
2015/07/23 职场文书
使用HttpSessionListener监听器实战
2022/03/17 Java/Android