简单易懂的人工智能系列:K-means算法

K-Means

算法概念

k-Mens即K均值聚类,属于划分聚类。其工作原理为根据初始化的聚类中心信息,计算每个样本到这些中心的距离,可以判断每个样本 均归属于某个类簇,更新聚类中心信息,重新计算每个样本到新的聚类中心的距离,重新划分样本到新的聚类中心对应的类中,重复进行,知道满足终止条件

如果用数据表达式表示,假设簇划分为,则我们的目标是最小化平方误差E:

                                               

其中 μi 是簇 Ci 的均值向量,有时也称为质心,表达式为:

                                                         

如果我们想直接求上式的最小值并不容易,这是一个NP难的问题,因此只能采用启发式的迭代方法。

K-Means采用的启发式方式很简单,用下面一组图就可以形象的描述:

有N个样本点,使用K-Means将其聚类的步骤:

其中 Step3 中的重新计算k个类粗的中心点可采用平均距离中心——质心的计算公式。上图以 K 为2,样本数为 N 来描述KMean算法。

当然在实际K-Mean算法中,我们一般会多次运行图c和图d,才能达到最终的比较优的类别

具体实现步骤

第一步,确定聚类个数,确定聚类中心,确定距离计算公式

1. 对于K-Means算法,首先要注意的是k值的选择,一般来说,我们会根据对数据的先验经验选择一个合适的k值,如果没有什么先验知识,则可以通过交叉验证选择一个合适的k值。

2. 在确定了k的个数后,我们需要选择k个初始化的质心,就像上图b中的随机质心。由于我们是启发式方法,k个初始化的质心的位置选择对最后的聚类结果和运行时间都有很大的影响,因此需要选择合适的k个质心,最好这些质心不能太近。

常用的几种距离计算方法

通常情况下,在聚类算法中,样本的属性主要由其在特征空间中的相对距离来表示。这就使得距离这个概念,对于聚类非常重要。以下是几种最常见的距离计算方法:

欧式距离(又称 2-norm 距离或平方距离)

在欧几里德空间中,点 x=(x1,…,xn) 和 y=(y1,…,yn) 之间的欧氏距离为:

在欧几里德度量下,两点之间线段最短。

余弦距离(又称余弦相似性)

两个向量间的余弦值可以通过使用欧几里德点积公式求出:

                                                a⋅b=∥a∥∥b∥cosθ

所以:

                                          

也就是说,给定两个属性向量 A 和 B,其余弦距离(也可以理解为两向量夹角的余弦)由点积和向量长度给出,如下所示:

                     

这里的 Ai 和 Bi 分别代表向量 A 和 B 的各分量。

曼哈顿距离(Manhattan Distance, 又称 1-norm 距离或绝对值距离)

曼哈顿距离的定义,来自于计算在规划为方型建筑区块的城市(如曼哈顿)中行车的最短路径。

假设一个城市是完备的块状划分,从一点到达另一点必须要按照之间所隔着的区块的边缘走,没有其他捷径(如下图):

                                          

因此,曼哈顿距离就是:在直角坐标系中,两点所形成的线段对 x 和 y 轴投影的长度总和。

从点 (x1,y1) 到点 (x2,y2),曼哈顿距离为:

                                                    |x1−x2|+|y1−y2|

第二步,计算每个点和聚类中心的距离,进行归类

第三步,计算当前类簇的中心,更新聚类中心 Ck 的位置(质心法)

重复第二、三步,将各样本Si点根据新聚类中心Ck进行重新划分,根据最新聚类结果计算最新聚类中心,更新Ck取值

重复第二、三步,知道聚类中心不再变化,或者循环次数达到预先 设定的阈值,结束,得到聚类结果

 

实现伪码

选择k个点作为初始类簇中心

repeat

     将每个样本点指派到最近的类簇中心,形成K个类簇

     重新计算每个类簇的中心

until 类簇不发生变化 or 达到最大迭代ci

实现源码

定义一个计算欧式距离的函数distEucDistance

定义初始化K个聚类中心的函数

定义k-均值算法函数kMeans:

 

K-means优缺点

优点:

缺点:

非球状聚类效果图示(很差):

K-means算法思考

  • 异常点的存在:K-means算法在迭代的过程中使用所有点的均值作为新的质点(中心点),如果簇中存在异常点,将导致均值偏差比较严重。 比如一个簇中有2、4、6、8、100五个数据,那么新的质点为24,显然这个质点离绝大多数点都比较远;在当前情况下,使用中位数6可能比使用均值的想法更好,使用中位数的聚类方式叫做K-Mediods聚类(K中值聚类)。
  • 初值敏感:K-means算法是初值敏感的,选择不同的初始值可能导致不同的簇划分规则。为了避免这种敏感性导致的最终结果异常性,可以采用初始化多套初始节点构造不同的分类规则,然后选择最优的构造规则。针对这点后面因此衍生了:二分K-Means算法、K-Means++算法、K-Means||算法、Canopy算法等。
  • 4
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
《 — 人工智能方向实习—》 实 习 报 告 专业: 计算机科学与技术 班级: 12419013 学号: 姓名: 江苏科技大学计算机学院 2016年 3 月 实验一 数据聚类分析 一、实验目的 编程实现数据聚类的算法。 二、实验内容 k-means聚类算法。 三、实验原理方法和手段 k-means算法接受参数k ;然后将事先输入的n个数据对象划分为k个聚类以便使得所获得的聚类满足:同一聚类 中的对象相似度较高. 四、实验条件 Matlab2014b 五、实验步骤 1) 初始化k个聚类中心。 2) 计算数据集各数据到中心的距离,选取到中心距离最短的为该数据所属类别。 3) 计算(2)分类后,k个类别的中心(即求聚类平均距离) 4) 继续执行(2)(3)直到k个聚类中心不再变化(或者数据集所属类别不再变化) 六、实验代码 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % main.m % k-means algorithm % @author matcloud %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% clear; close all; load fisheriris; X = [meas(:,3) meas(:,4)]; figure; plot(X(:,1),X(:,2),'ko','MarkerSize',4); title('fisheriris dataset','FontSize',18,'Color','red'); [idx,ctrs] = kmeans(X,3); figure; subplot(1,2,1); plot(X(idx==1,1),X(idx==1,2),'ro','MarkerSize',4); hold on; plot(X(idx==2,1),X(idx==2,2),'go','MarkerSize',4); hold on; plot(X(idx==3,1),X(idx==3,2),'bo','MarkerSize',4); hold on; plot(ctrs(:,1),ctrs(:,2),'kx','MarkerSize',12); title('official kmeans','FontSize',16,'Color','red'); [idx,ctrs] = my_kmeans(X,3); subplot(1,2,2); plot(X(idx==1,1),X(idx==1,2),'ro','MarkerSize',4); hold on; plot(X(idx==2,1),X(idx==2,2),'go','MarkerSize',4); hold on; plot(X(idx==3,1),X(idx==3,2),'bo','MarkerSize',4); hold on; plot(ctrs(:,1),ctrs(:,2),'kx','MarkerSize',12); title('custom kmeans','FontSize',16,'Color','red'); function [idx,ctrs] = my_kmeans(m,k) [row col] = size(m); %init k centroids p = randperm(size(m,1)); for i = 1 : k ctrs(i,:) = m(p(i),:); end idx = zeros(row,1);%idex is pointer of group while 1 d = dist2matrix(m,ctrs); [z,g] = min(d,[],2); if(g == idx) break; else idx = g; end %update ctroids for i = 1 : k v = find(g == i); if v ctrs(i,:) = mean(m(v,:),1); end end end end function [idx,ctrs] = my_kmeans(m,k) [row col] = size(m); %init k centroids p = randperm(size(m,1)); for i = 1 : k ctrs(i,:) = m(p(i),:); end idx = zeros(row,1);%idex is pointer of group while 1 d = dist2matrix(m,ctrs); [z,g] = min(d,[],2); if(g == idx) break; else idx = g; end %update ctroids for i =

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

薛定谔的猫96

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值