聚类(cluster)与分类的不同之处在于, 分类算法训练过程中样本所属的分类是已知的属监督学习. 而聚类算法不需要带有分类的训练数据,而是根据样本特征的相似性将其分为几类,又称为无监督分类.

K均值聚类(K-means cluster)算法是一种比较简单的聚类算法:

  1. 在特征空间中选择k个质心,每个质心代表一个分类

  2. 对于每个样本点计算其到各质心的距离,将其归入最近质心的类中

  3. 对于每个类计算所有样本点的均值,作为新的质心

  4. 反复执行2,3直至所有样本点分类均不再发生变化为止.

上述算法中的距离可以采用不同的定义, 最常见的为欧式距离:

def distEclud(vecA, vecB):
return sqrt(sum(power(vecA - vecB, 2)))

初始质心可以在数据集边界内随机选取:

def randCent(dataSet, k):
n = shape(dataSet)[1]
centers = mat(zeros((k, n)))
for j in range(n):
minJ = min(dataSet[:, j])
rangeJ = float(max(dataSet[:, j]) - minJ)
centers[:, j] = mat(minJ + rangeJ * random.rand(k, 1))
return centers

实现KMean算法:

def kMeans(dataSet, k, distMethod=distEclud, createCent=randCent):
m = shape(dataSet)[0]
clusterAssess = mat(zeros((m, 2)))
centers = createCent(dataSet, k)
clusterChanged = True
while clusterChanged:
clusterChanged = False
for i in range(m): # for each sample
# get closest center
minDist = inf
minIndex = -1
for j in range(k): # for each class
dist = distMethod(centers[j, :], dataSet[i, :])
if dist < minDist:
minDist = dist
minIndex = j
if clusterAssess[i, 0] != minIndex:
clusterChanged = True
clusterAssess[i, :] = minIndex, minDist ** 2
# update center
for cent in range(k):
ptsInClust = dataSet[nonzero(clusterAssess[:, 0].A == cent)[0]]
centers[cent, :] = mean(ptsInClust, axis=0)
return centers, clusterAssess

centers为所有质心的坐标列表, clusterAssess记录了每个点的序号和距其质心距离的平方.

定义误差平方和(Sum of Squared Error, SSE)为所有样本点距其质心的距离平方和, 误差越小则聚类效果越好.

K-Mean算法很容易实现,但是需要手动指定分类数k故而在实际应用中非常不便.

二分K均值算法是该问题的一种解决方案, 该算法仅需指定最大的分类数而自行选择最佳分类数:

  1. 将整个数据集作为一个分类

  2. 使用kMeans算法将其进行二分类

  3. 选择误差较大的分类进行进一步划分

算法实现:

def binKMeans(dataSet, k, distMethod=distEclud):
m = shape(dataSet)[0]
clusterAssess = mat(zeros((m, 2)))
originCenters = mean(dataSet, axis=0).tolist()[0]
centers = [originCenters]
# get origin error
for j in range(m):
clusterAssess[j, 1] = distMethod(mat(originCenters), dataSet[j, :]) ** 2
# try to cluster
while (len(centers) < k):
# get best spilt
minError = inf
for i in range(len(centers)):
ptsInCurrCluster = dataSet[nonzero(clusterAssess[:, 0].A == i)[0], :]
splitCenter, splitAssess = kMeans(ptsInCurrCluster, 2, distMethod)
spiltError = sum(splitAssess[:, 1])
formerError = sum(clusterAssess[nonzero(clusterAssess[:, 0].A != i)[0], 1])
if (spiltError + formerError) < minError:
bestCentToSplit = i
bestNewCents = splitCenter
bestClustAss = splitAssess.copy()
minError = spiltError + formerError
# update assessment
bestClustAss[nonzero(bestClustAss[:, 0].A == 1)[0], 0] = len(centers)
bestClustAss[nonzero(bestClustAss[:, 0].A == 0)[0], 0] = bestCentToSplit
# update global centers and assessment
centers[bestCentToSplit] = bestNewCents[0, :].tolist()[0]
centers.append(bestNewCents[1, :].tolist()[0])
clusterAssess[nonzero(clusterAssess[:, 0].A == bestCentToSplit)[0], :] = bestClustAss
return centers, clusterAssess

完整源码

K均值聚类的更多相关文章

  1. 【转】算法杂货铺——k均值聚类(K-means)

    k均值聚类(K-means) 4.1.摘要 在前面的文章中,介绍了三种常见的分类算法.分类作为一种监督学习方法,要求必须事先明确知道各个类别的信息,并且断言所有待分类项都有一个类别与之对应.但是很多时 ...

  2. 5-Spark高级数据分析-第五章 基于K均值聚类的网络流量异常检测

    据我们所知,有‘已知的已知’,有些事,我们知道我们知道:我们也知道,有 ‘已知的未知’,也就是说,有些事,我们现在知道我们不知道.但是,同样存在‘不知的不知’——有些事,我们不知道我们不知道. 上一章 ...

  3. 机器学习实战5:k-means聚类:二分k均值聚类+地理位置聚簇实例

    k-均值聚类是非监督学习的一种,输入必须指定聚簇中心个数k.k均值是基于相似度的聚类,为没有标签的一簇实例分为一类. 一 经典的k-均值聚类 思路: 1 随机创建k个质心(k必须指定,二维的很容易确定 ...

  4. Python实现kMeans(k均值聚类)

    Python实现kMeans(k均值聚类) 运行环境 Pyhton3 numpy(科学计算包) matplotlib(画图所需,不画图可不必) 计算过程 st=>start: 开始 e=> ...

  5. 机器学习理论与实战(十)K均值聚类和二分K均值聚类

    接下来就要说下无监督机器学习方法,所谓无监督机器学习前面也说过,就是没有标签的情况,对样本数据进行聚类分析.关联性分析等.主要包括K均值聚类(K-means clustering)和关联分析,这两大类 ...

  6. 第十篇:K均值聚类(KMeans)

    前言 本文讲解如何使用R语言进行 KMeans 均值聚类分析,并以一个关于人口出生率死亡率的实例演示具体分析步骤. 聚类分析总体流程 1. 载入并了解数据集:2. 调用聚类函数进行聚类:3. 查看聚类 ...

  7. K均值聚类的失效性分析

    K均值聚类是一种应用广泛的聚类技术,特别是它不依赖于任何对数据所做的假设,比如说,给定一个数据集合及对应的类数目,就可以运用K均值方法,通过最小化均方误差,来进行聚类分析. 因此,K均值实际上是一个最 ...

  8. ML: 聚类算法-K均值聚类

    基于划分方法聚类算法R包: K-均值聚类(K-means)                   stats::kmeans().fpc::kmeansruns() K-中心点聚类(K-Medoids) ...

  9. 探索sklearn | K均值聚类

    1 K均值聚类 K均值聚类是一种非监督机器学习算法,只需要输入样本的特征 ,而无需标记. K均值聚类首先需要随机初始化K个聚类中心,然后遍历每一个样本,将样本归类到最近的一个聚类中,一个聚类中样本特征 ...

随机推荐

  1. 别人的Linux私房菜(6)文件权限与目录配置

    账号与一般身份用户存放在/etc/passwd文件中 个人密码存放在/etc/shadow文件中 Linux所有组名存放在/etc/group中 ls -al查看所有信息并显示权限等 文件权限的10字 ...

  2. Linux 第十三天

    十五.shell编程 1.Shell是什么 1)Shell是一个命令行解释器,它为用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序,用户可以用Shell来启动.挂起.停止甚至是编写一 ...

  3. cropper,图片剪辑上传工具的使用

    cropper工具是一个功能强,兼容性好的一个图片裁剪和上传工具 GitHub地址:https://github.com/kesixin/Head_Cut_PC <div class=" ...

  4. 子div撑不开父div

    方法一:推荐 设置父div的overflow:hidden; 方法二: 父div结束前增加一个空div style=”clear:both;” .clear { clear:both; } <d ...

  5. MySQL数据库插入中文乱码解决方法

    在mysql数据库中,插入中文数据时,会出现乱码的现象. 我的测试方法: 首先用Navicat for MySql 插入一行数据,带有中文的. 再用mysql命令行来查看插入的数据,看是否出现乱码. ...

  6. Java学习过程

    按照这个流程巩固自己学习的东西吧

  7. Django Auth 专题

    Django的标准库存放在 django.contrib 包中.每个子包都是一个独立的附加功能包. 这些子包一般是互相独立的,不过有些django.contrib子包需要依赖其他子包,其中django ...

  8. Linux-程序包管理

    Linux上的软件安装有2种形式:源码.二进制文件,源码需要在编译环境下编译安装,二进制可以直接安装. 1.程序包管理器 rpm 程序包管理器能够将目标二进制格式(也就是从源码编译好的二进制文件,包括 ...

  9. Thinking in Java from Chapter 7

    From Thinking in Java 4th Edition final 1. 对于基本类型,final使数值恒定不变 2. 对于对象引用,final使引用恒定不变,即不能指向别的对象,但指向的 ...

  10. “全栈2019”Java多线程第三十七章:如何让等待的线程无法被中断

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...