k-均值聚类实际上是多元统计分析中的聚类分析部分的内容,但是也是机器学习的基础算法。它的目的就是把数据(无标签)进行分类,但是具体分多少个类却不知道,只能我们先认为的假设分为多少个类进行计算。

聚类与分类是有着本质区别的。对于分类问题及其算法算法(如逻辑回归、支持向量机等分类算法),它们属于监督学习——根据原有的数据(有标签类别)和对应的类别进行训练,训练后可以把新的未知类别的数据进行预测判别其属于哪一类;而聚类则是只有一堆数据,我们不知道类别(即无标签),而是人为地进行分类。简单来说,分类问题,就好比人们经过了以往的学习,我们知道绿豆是绿色的,红豆是红色的,当看到一个红色的圆状物体我们就认为他很可能是红豆;聚类问题,就好比我们收获了很多苹果,然后把大一点的放一堆,中等放一堆,小一点的放一堆,做一下分类,具体分多少堆以及大小指标在于人们的意愿。

所以,当我们了解聚类问题后,就应该去想如何进行聚类。而k-均值聚类就属于聚类算法之一,也是一种比较简单的算法。

(1)算法思想

我们前面讲到了苹果分堆的聚类例子。比如我们就分两堆苹果,那通常肯定是大的放一堆,小的放一堆,所以每一堆里面苹果大小差别不大,比较相似。

而对于数据聚类,也是同样的思想,我们让每一类内的数据距离尽可能的近(即相似)。那么数据间的距离(相似度)如何度量呢?

在多元统计中,数据之间的距离有很多的度量方法,如欧式距离、切比雪夫距离、马式距离、兰式距离等等。关于距离的度量方法兔兔在另外的文章单独讨论。本文为了方便讲述算法,采用欧式距离度量方法,即

其中分别表示第i组、第j组数据。k表示每组数据内第k个指标,总共有p个指标。对应苹果,如果只根据大小分类,指标p=1个;如果根据大小、颜色、味道进行分类,那么指标p=3个。每一组数据就对应一个苹果。

在采用了欧式距离度量方法之后就是该进行聚类了。在开始时,我们需要人为确定聚类成多少个种类。当我们确定分为n个种类后,初始时把所有数据随机分成n类。并计算每一类的中心点。(这里的中心点就是求和平均,例如对于第i组数据(x11,x12),(x21,x22),(x31,x32),那么这个组的中心点就是

之后就是对所有的点(数据)遍历一遍,每一个点计算到n个类中心的距离,然后把这个点归到那个距离最近的那个类。比如数据到第n组的数据中心是最近的,那么就把这个数据放到第n类。所有点变量后,就形成了新的n个类。

之后对这新的n个类再求中心点,再遍历所有的点,重复前面的过程,就又更新一遍。

这样,执行循环多次,最终就可以实现聚类了。这个也就是k-均值聚类的所有过程。

(2)算法流程

(1)初始时把m个数据随机分成n类(一般都是平均分,每个类里面数据个数相同)。

(2)计算每个类里面数据的平均值,得到n个类的中心点。

(3)计算所有数据(每个点)到各个中心的距离,把这个点归到距离最近的那一类。

(4)所有点遍历后得到新的聚类。再计算这n个类的n个中心点。

(5)重复(3)的操作,再(4),一直循环多次。

(6)多次循环结束后,得到聚类结果。

(3)算法实现

我们以下面的数据为例,该数据有两个指标,可以表示为二维平面的点。

x=[1,2,3,4,3,2,6,5,4,3,10,12,24,33,45,44,22,50,44,30,31,29,20,21,24,24,22,23,15,12,11,9,15,14,12,8,6,29,22,44]
y=[5,2,8,1,9,3,9,2,1,5,11,33,20,22,39,42,50,50,40,40,31,40,30,20,31,44,50,48,9,8,10,3,3,4,8,7,8,25,39,20]
data=list(zip(x,y))

散点如下所示:

我们通过直觉可以发现左下角可以分成一堆,右上也可以分为一堆,所以可以设分为两类。

class k_mean:def __init__(self,data,n=2,circle=10):self.circle=circleself.data=data #待聚类的数据self.n=n #把数据分成的类数self.category=[]self.m=len(data) #数据个数self.mean=[] #用来储存每个类的中心点for i in range(n):self.category.append([])def distance(self,x,y):'''计算数据之间的距离,采用欧式距离'''n=len(x) #判断数据的维数s=0for i in range(n):s+=(x[i]-y[i])**2return np.sqrt(s)def main(self):'''聚类过程'''l=int(self.m/self.n) #l为初始的每个类里面元素的个数for i in range(self.n-1):self.category[i]=data[i*l:i*l+l] #把数据分别分到各个类中self.category[-1]=data[l*(self.n-1):self.m] #防止m无法被n整除的情况,把剩下的数据放最后一类数据for i in range(self.circle):'''开始循环'''category=[[] for i in range(self.n)] #用来储存遍历后点的分类print('the {} epoch'.format(i))for j in range(self.n):self.mean.append(np.mean(self.category[j],axis=0)) #求各个类的中心点并保存到mean中for j in range(self.m): #开始遍历各个点:d=[] #用来保存数据点j到各个中心的距离for k in range(self.n):d.append(self.distance(data[j],self.mean[k]))index=d.index(min(d)) #找到离这个点最近的那一类,类为第indexcategory[index].append(data[j]) #把这个点加到那一类中self.category=category #把新聚类传递到self.category中,用于下一次计算中心点,同时下一次category清空return self.categoryif __name__=='__main__':x=[1,2,3,4,3,2,6,5,4,3,10,12,24,33,45,44,22,50,44,30,31,29,20,21,24,24,22,23,15,12,11,9,15,14,12,8,6,29,22,44]y=[5,2,8,1,9,3,9,2,1,5,11,33,20,22,39,42,50,50,40,40,31,40,30,20,31,44,50,48,9,8,10,3,3,4,8,7,8,25,39,20]data=list(zip(x,y))k=k_mean(data=data)c=k.main()print(c)for i in c:x=[]y=[]for j in i:x.append(j[0])y.append(j[1])plt.scatter(x,y)plt.show()

其实如果自己定义分类个数和已知指标个数,算法实现要比上面简单很多,距离就直接两点做差求平方和后开方;而且如果知道分类个数,可以初始类C1、C2...,构造这些空列表,每次往里加数值,之后求平均,而且初始时也不需考虑数据个数是否被类整除的情况。但是兔兔上面写的k-mean则更具有普适性,如果打算把样本分几类,只需改变参数n即可,而且样本的指标的个数也是任意的,可以是二维、三维、四维等,但是处理过程也更复杂一些。所以k-均值算法难点不在流程,而在于算法的完整实现。程序结果如下:

我们发现,运行结果于预想的是一致的。如果我们把它分成三类,则结果如下:

我们发现,效果也是可以的。

其实,对应一些随机的散点,也都是可以用k-均值计算的,虽然我们看起来这些点没有太多规律。但这种情况有时聚类也是没有太大意义的。如下图所示。

我们看到,开始还是随机是混合散点,但是k-均值算法可以很快就完成聚类。上面的图片的迭代十次的情况。

下面的代码对应的是处理指标个数为2的数据,分成两类,对应G1、G2,所以实现起来比较简单,但是却不具普遍性,一旦更改聚类个数或是数据不是二维的,代码就又要重新修改。

import numpy as np
def distance(x,y):return np.sqrt((x[0]-y[0])**2+(x[1]-y[1])**2)
for i in range(10):'''循环10次'''print('the {} epoch'.format(i))m1=np.mean(G1,axis=0)m2=np.mean(G2,axis=0)g1=[];g2=[]for j in range(len(G1)):d1=distance(G1[j],m1)d2=distance(G1[j],m2)if d1<=d2:g1.append(G1[j])else:g2.append(G1[j])for j in range(len(G2)):d1=distance(G2[j],m1)d2=distance(G2[j],m2)if d1<=d2:g1.append(G2[j])else:g2.append(G2[j])G1=g1;G2=g2

(4)总结

k-mean算法作为聚类分析中常用的一种算法,在实际应用中也具有广泛的用途。在统计学中、数学建模或是一些数据分析等都会用到这个算法。该算法流程简单,但真正能够实现好这个算法还是需要仔细琢磨的,体会如何实现对于不同聚类个数、不同指标数的个数都能很好地完成聚类。

k-均值(k-means)聚类相关推荐

  1. K均值与DBSCAN聚类效果

    K均值与DBSCAN聚类效果 K均值的发展状况 K-means算法(Lloyod,1982)是简单而又有效的统计聚类算法,使机器能够将具有相同属性的样本归置到一块儿.K-均值算法的理论研究主要包括三块 ...

  2. PRML第九章读书笔记——Mixture Models and EM K均值/K中心点、高斯混合奇异性、EM观点下的高斯混合/K-means/混合伯努利分布/贝叶斯线性回归、推广EM算法

    目录 9.1 K-means Clustering P429 K中心点算法K-medoids 9.2 Mixtures of Gaussians P433 高斯混合的奇异性 9.3 An Altern ...

  3. k均值聚类算法python_K均值和其他聚类算法:Python快速入门

    k均值聚类算法python This post was originally published here 这篇文章最初发表在这里 Clustering is the grouping of obje ...

  4. 机器学习之原型聚类算法(K均值和高斯混合)

    "原型"是指样本空间中具有代表性的点. 原型聚类算法是假设聚类结构能通过一组原型进行刻画,在现实聚类任务中极为常用. 通常情形下,算法先对原型进行初始化,然后对原型进行迭代更新求解 ...

  5. vb.net机器学习-手写和本机数字识别-K均值和欧氏距离

    一.欧氏距离 二维的公式 ρ = sqrt( (x1-x2)2+(y1-y2)2 ) 三维的公式 ρ = sqrt( (x1-x2)2+(y1-y2)2+(z1-z2)^2 ) n维空间的公式 n维欧 ...

  6. K均值 - 案例实现(python)

    K均值 K均值案例(python) 背景介绍 算法定义 K值的选取 案例实现(python) 数据集 代码实现 运行结果 总结 参考文献 K均值案例(python) k均值聚类算法(k-means c ...

  7. R语言 k均值算法(k-means)

    k均值算法针对聚类所得簇划分求得最小平方误差,k均值算法采用了贪心策略,通过迭代优化来近似求解 算法如下: kmeans的计算方法如下: 1 随机选取k个中心点 2 遍历所有数据,将每个数据划分到最近 ...

  8. K 均值算法-如何让数据自动分组

    公号:码农充电站pro 主页:https://codeshellme.github.io 目录 1,K 均值算法 2,K 均值算法聚类过程 3,K 均值算法的实现 4,准备数据点 5,对数据聚类 6, ...

  9. Matlab 主成分分析与K均值聚类分析实验报告

    Matlab 主成分分析与K均值聚类分析实验报告 提示:数据资源在本CSDN号的上传资料中直接领取 1 引言 数据:gyzb.mat(按顺序对应每一列)为:31个省市区的国有控股企业的主要指标(包括: ...

  10. k均值聚类算法(K Means)及其实战案例

    算法说明 K均值聚类算法其实就是根据距离来看属性,近朱者赤近墨者黑.其中K表示要聚类的数量,就是说样本要被划分成几个类别.而均值则是因为需要求得每个类别的中心点,比如一维样本的中心点一般就是求这些样本 ...

最新文章

  1. 设计模式---(设计原则)面向对象设计原则
  2. Spring - Java/J2EE Application Framework 应用框架 第 17 章 使用Spring邮件抽象层发送Email
  3. [css] 你知道全屏滚动的原理是什么吗?它用到了CSS的哪些属性?
  4. java编程中的持有对方引用是什么意思?有什么作用?
  5. C程序设计导引(1)
  6. uboot kernel 博客
  7. Linux的Open Files设置过小导致程序退出并且Unable to create new native thread
  8. [读码时间] 记住密码提示框
  9. [Leetcode 18]四数之和 4 Sum
  10. 工程计算书(计算稿)共享和服务—PASS云计算书平台
  11. Pytorch中报错RuntimeError: The size of tensor a (60) must match the size of tensor b (56)
  12. php 无父类 用parrent,Leaflet_扩展Leaflet:类(2017-10-26)
  13. 安装Pytorch后torch.cuda.is_available()返回False问题解决
  14. Docker学习十:网络
  15. registrar计算机词汇,HR常用短语英语词汇表(转载)
  16. C# Winform 置顶属性Topmost 的误区
  17. LeetCode#2379. 得到 K 个黑块的最少涂色次数
  18. 单机魔兽世界服务器显示不兼容,官网公告:解决登陆游戏设备驱动不兼容问题...
  19. 超宽带(UWB)无线通信技术介绍
  20. 计算机存储器件中运行速度最快,选择题:下列存储器中,存取速度最快的是()...

热门文章

  1. Ansible中的任务执行控制介绍
  2. VB与数据库结合开发全过程!
  3. 使用两个路由器共享上网的接法
  4. 中缀 转 后缀 实现计算
  5. 一起围观春晚“打工牛”,2021中国智能智造牛起来!
  6. Error response from daemon: manifest for java:8 not found: manifest unknown: manifest unknown
  7. 项目管理sod_大型工程建设全过程项目管理PPT.ppt
  8. 翻转内衬法用于供水管道修复浅析
  9. 问题 N: 【搜索】泡泡龙
  10. 焕然一新 | 寻息科技官网重磅升级