机器学习(2): K-means (k均值) 聚类算法 小结

news/2024/10/23 21:29:34/

目录

1 聚类简介

2 k-means算法流程

3 利用k-means 对数据进行聚类

4 利用K-means进行图像分割

5 小结

参考资料


1 聚类简介

在无监督学习中,训练样本的标记信息是未知的,我们的目标是通过对无标记训练样本的学习来解释数据的内在性质及规律,为了进一步的数据分析提供基础,此类学习应用最多的就是“聚类”(clustering)。

聚类(clustering) 就是视图将数据集中的样本划分为若干个互不相交的子集,每个子集称为一个簇(cluster)。通过这样的划分,每个簇可能对应于一些潜在的类别,如有一堆瓜,分为:有籽瓜和无籽瓜 或者 浅色瓜和深色瓜 或进口瓜和国产瓜 等分类。注意:这些概念对聚类算法而言是实现位置的,聚类过程是自动形成簇结构。

使用数学语言描述聚类为:假设有样本集 D = \{ {​{\bf{x}}_1},{​{\bf{x}}_2}, \ldots ,{​{\bf{x}}_m}\}包含 m个无标记样本,每个样本{​{\bf{x}}_i} = {({x_{i1}},{x_{i1}}, \ldots ,{x_{in}})^T} 是一个n维的特征向量,则聚类算法需要将样本集 D 划分为 k 各互不相交的簇\{ {C_l}\left| {l = 1,2, \ldots ,k} \right.\} ,其中{C_{l'}}{ \cap _{l' \ne l}}{C_l} = \emptysetD = \cup _{l = 1}^k{C_l} 。相应的,我们用{\lambda _j} \in \{ 1,2, \ldots ,k\} 表示样本 {​{\bf{x}}_j}的“簇标记”(cluster label),即 {​{\bf{x}}_j} \notin {C_{​{\lambda _j}}}。于是,聚类的结果可用包含m个元素的簇标记向量{\bf{\lambda }} = {({\lambda _1},{\lambda _2}, \ldots ,{\lambda _m})^T} 表示。

当看完这个数学描述时,心中默念:啥啥啥,这写的是啥。

其实,聚类没有那么难,上面的数学描述看着挺吓人的,其实通过简单地例子来说明,就基本理解了。下面就介绍经典的聚类算法——k-means (k均值)。​​​​

k-means是最简单的聚类算法之一,应用十分广泛,k-means以距离作为相似性的评价指标,其基本思想是按照距离将样本聚成不同的簇,两个点的距离越近,其相似度就越大,以得到紧凑且独立的簇作为聚类目标。

 

2 k-means算法流程

下面是k-means的算法流程:


输入:样本集D = \{ {​{\bf{x}}_1},{​{\bf{x}}_2}, \ldots ,{​{\bf{x}}_m}\}
           聚类簇数 k


过程:
1:从D随机选择k个样本作为初始均值向量 \{ {​{\bf{\mu }}_1},{​{\bf{\mu }}_2}, \ldots ,{​{\bf{\mu }}_k}\}
2:repeat
3:    令 {C_i} \ne \emptyset {\rm{ }}(1 \le i \le k)
4:    for j = 1,2, \ldots ,m  do
5:     计算样本 {​{\bf{x}}_j}与个均值向量 {​{\bf{\mu }}_i}{\rm{ }}(1 \le i \le k)的距离:{d_{ji}} = {\left\| {​{​{\bf{x}}_j} - {​{\bf{\mu }}_i}} \right\|_2}


6:     根据样本距离最近的均值向量确定{​{\bf{x}}_j} 的簇标记:{​{\bf{\lambda }}_j} = \mathop {\arg \min }\limits_{i \in \{ 1,2, \ldots ,k\} } {\rm{ }}{d_{ji}}
7:     将样本 {​{\bf{x}}_j}划入相应的簇:{C_{​{​{\bf{\lambda }}_j}}} = {C_{​{​{\bf{\lambda }}_j}}} \cup \{ {​{\bf{x}}_j}\}
8: end for

9:    for  i = 1,2, \ldots ,k do


10:   计算新均值向量: \mathbf{\mu }_{i}^{'}=\frac{1}{\left| {​{C}_{i}} \right|}\sum\limits_{x\in {​{C}_{i}}}{\mathbf{x}}
11:        if   \mathbf{\mu }_{i}^{'}\ne {​{\mathbf{\mu }}_{i}} then
12:                将当前均值向量{​{\bf{\mu }}_i} 更新为 {\bf{\mu }}_i^'
13:        else
14:                 保持当前均值向量不变
15:        else if 
16:    end for
17:until 当前均值向量均未更新


输出:簇划分  C = \{ {C_1},{C_2}, \ldots ,{C_k}\}


直接看算法,一时半会很难理解,直接用实际数据一步步计算,更直观,下面用实际的数据进行实验。

 

3 利用k-means 对数据进行聚类

实验数据使用 周志华-机器学习 中的 西瓜数据集4.0 ,如表1所示:

表1 西瓜数据集4.0

编号

密度

含糖率

1

0.679

0.460

2

0.744

0.376

3

0.634

0.264

4

0.608

0.318

5

0.556

0.215

6

0.403

0.237

7

0.481

0.149

8

0.437

0.211

9

0.666

0.091

10

0.243

0.267

11

0.245

0.057

12

0.343

0.099

13

0.639

0.161

14

0.567

0.198

15

0.360

0.370

16

0.593

0.042

17

0.719

0.103

18

0.387

0.188

19

0.339

0.241

20

0.282

0.257

21

0.748

0.232

22

0.714

0.346

23

0.483

0.312

24

0.478

0.437

25

0.525

0.369

26

0.751

0.489

27

0.532

0.472

28

0.473

0.376

29

0.725

0.445

30

0.446

0.459

 

使用上面的数据集,假设现在需要聚类簇数 k=3。
(1)首先随机选取三个样本 {​{\bf{x}}_6},{​{\bf{x}}_{12}},{​{\bf{x}}_{27}}(编号为6,12,27对应的数据)作为初始均值向量,即:

{​{\bf{\mu }}_1}=(0.403;0.237),  {​{\bf{\mu }}_2}=(0.343;0.099),  {​{\bf{\mu }}_2}=(0.532;0.472)

(2)将第一个样本 {​{\bf{x}}_1}=(0.697;0.460)与当前的均值向量 {​{\bf{\mu }}_1},{​{\bf{\mu }}_2},{​{\bf{\mu }}_3}计算他们之间的距离,距离结果为:0.369,0.506,0.166,因此第一个样本{​{\bf{x}}_1} 被划入到簇{C_3} 中。同样的,对数据集中的所有样本就进行计算,可得到当前簇划分为:

 {C_1} = \{ {​{\bf{x}}_5},{​{\bf{x}}_6},{​{\bf{x}}_7},{​{\bf{x}}_8},{​{\bf{x}}_9},{​{\bf{x}}_{10}},{​{\bf{x}}_{13}},{​{\bf{x}}_{14}},{​{\bf{x}}_{15}},{​{\bf{x}}_{17}},{​{\bf{x}}_{18}},{​{\bf{x}}_{19}},{​{\bf{x}}_{20,}}{​{\bf{x}}_{23}}\}

 {C_2} = \{ {​{\bf{x}}_{11}},{​{\bf{x}}_{12,}}{​{\bf{x}}_{16}}\}

 {C_3} = \{ {​{\bf{x}}_1},{​{\bf{x}}_2},{​{\bf{x}}_3},{​{\bf{x}}_4},{​{\bf{x}}_{21}},{​{\bf{x}}_{22}},{​{\bf{x}}_{24}},{​{\bf{x}}_{25}},{​{\bf{x}}_{26}},{​{\bf{x}}_{27}}{​{\bf{x}}_{28}},{​{\bf{x}}_{29}},{​{\bf{x}}_{30}}\}

 

(3){C_1},{C_2},{C_3} 中分别计算新的均值向量

 {\mathbf{\mu }}_1^'=(0.473;0.214), {\bf{\mu }}_2^'=(0.394;0.066), {\bf{\mu }}_2^'=(0.623;0.388)

 

(4)重新进入(2)和(3),不断重复,知道当前的均值向量保持不变,即可停止。

 

分类的结果如下图所示:

 

下面是k-means聚类使用的Matlab代码

clear all;clc;tic;X=[0.679,0.460;0.744,0.376;0.634,0.264;0.608,0.318;0.556,0.215;0.403,0.237;0.481,0.149;0.437,0.211;0.666,0.091;0.243,0.267;0.245,0.057;0.343,0.099;0.639,0.161;0.567,0.198;0.360,0.370;0.593,0.042;0.719,0.103;0.387,0.188;0.339,0.241;0.282,0.257;0.748,0.232;0.714,0.346;0.483,0.312;0.478,0.437;0.525,0.369;0.751,0.489;0.532,0.472;0.473,0.376;0.725,0.445;0.446,0.459];k=3;
[Idx,Ctrs,SumD,D]=kmeans(X,k);%画出聚类为1的点。
%X(Idx==1,1),为第一类的样本的第一个坐标;
%X(Idx==1,2)为第二类的样本的第二个坐标
plot(X(Idx==1,1),X(Idx==1,2),'r.','MarkerSize',14)
hold on
plot(X(Idx==2,1),X(Idx==2,2),'b.','MarkerSize',14)
hold on
plot(X(Idx==3,1),X(Idx==3,2),'g.','MarkerSize',14)%绘出聚类中心点,kx表示是圆形
plot(Ctrs(:,1),Ctrs(:,2),'kx','MarkerSize',14,'LineWidth',4)
plot(Ctrs(:,1),Ctrs(:,2),'kx','MarkerSize',14,'LineWidth',4)
plot(Ctrs(:,1),Ctrs(:,2),'kx','MarkerSize',14,'LineWidth',4)legend('Cluster 1','Cluster 2','Cluster 3','Centroids','Location','NW')toc;

 

下面简单介绍Matlab 中 kmeans 函数如何使用:

kmeans 函数使用方法:


Idx=kmeans(X,K) 

[Idx,C]=kmeans(X,K) 

[Idx,C,sumD]=kmeans(X,K) 

[Idx,C,sumD,D]=kmeans(X,K) 

[…]=kmeans(…,’Name1’,Value1,’Name2’,Value2,…)


函数中,输入和输出参数的介绍:

X:数据为N\timesP维度的矩阵;

K:表示将X划分为几类,为整数;

Idx:N\times1的向量,存储的是每个点的聚类标号;

C:K\timesP的矩阵,存储的是K个聚类质心位置;

sumD:1\timesK的和向量,存储的是类间所有点与该类质心点距离之和;

D:N\timesK的矩阵,存储的是每个点与所有质心的距离;

 

[…]=kmeans(…,’Name1’,Value1,’Name2’,Value2,…);

这个用法可以查看 Matlab kmeans 帮助文档,这里简单介绍一下:Distance (距离测度) 和 Start (初始质心位置选择方法)
      主要可以设置为如下:
      1)‘Distance’:(距离测度),value如下:

‘sqEuclidean’ :欧式距离(默认时,采用此距离方式);

 ‘cityblock’ :绝度误差和,又称:L1;

 ‘cosine’ :针对向量;

‘correlation’  :针对有时序关系的值; 

‘Hamming’ :只针对二进制数据;

Example: 'Distance','cityblock'


      2) ‘Start’:初始质心位置选择方法,value如下:

‘sample’:从X中随机选取K个质心点;

‘uniform’: 根据X的分布范围均匀的随机生成K个质心;

‘cluster’: 初始聚类阶段随机选择10%的X的子样本(此方法初始使用’sample’方法;

Example: 'start','sample'

还有其他的参数设置,可以参见Matlab kmeans 帮助文档 。


 

4 利用K-means进行图像分割

下面是利用K-means进行图像分割的Matlab 代码:

clear all;clc;tic;C_Segments=2;%聚类的个数img_original = imread('lena.tiff');%读入图像
figure,imshow(img_original),title('原始图像');    %显示原图像
img_gray=rgb2gray(img_original);
figure,imshow(img_gray),title('原始灰度图像');% 获取图像的长宽
[m,n]=size(img_gray);% 灰度阈值计算
T=graythresh(img_gray);
img_bw=im2bw(img_gray,T);
figure,imshow(img_bw),title('原始二值图像');% 将图像进行RGB——3通道分解
R = reshape(img_original(:, :, 1), m*n, 1);  % 将R分量各转为kmeans使用的数据格式m*n=512*512=262144行
G = reshape(img_original(:, :, 2), m*n, 1);  % 将G分量各转为kmeans使用的数据格式m*n=512*512=262144行
B = reshape(img_original(:, :, 3), m*n, 1);  % 将B分量各转为kmeans使用的数据格式m*n=512*512=262144行
dat = [R,G,B];  % r g b分量组成样本的特征,每个样本有三个属性值,共width*height个样本()
cRGB = kmeans(double(dat), C_Segments,'Distance','city', 'emptyaction','singleton','start','sample');  % 使用聚类算法分为2类rRGB = reshape(cRGB, m, n);     % 反向转化为图片形式
figure, imshow(label2rgb(rRGB)),title('RGB通道分割结果');   % 显示分割结果% 将图像进行单一通道灰度分解
GraySeg= reshape(img_gray(:, :), m*n, 1);
cGray=kmeans(double(GraySeg), C_Segments);
rGray= reshape(cGray, m, n);     % 反向转化为图片形式
figure, imshow(label2rgb(rGray)),title('灰度图分割结果');   % 显示分割结果toc;

 

分类结果如下图所示:

 

 

5 小结

k-means聚类算法的实现过程大致表示如下:

(1) 随机选取k个初始聚类中心; 

(2) 计算每个样本到各聚类中心的距离,将每个样本归到其距离最近的聚类中心; 

(3) 对每个簇,以所有样本的均值作为该簇新的聚类中心; 

(4) 重复第(2)~(3)步,直到聚类中心不再变化或达到设定的迭代次数。 

 

参考资料

[1] https://blog.csdn.net/mrharvey/article/details/18085163

[2] https://blog.csdn.net/jteng/article/details/48811881

[3] https://blog.csdn.net/google19890102/article/details/52911835

[4] https://blog.csdn.net/mingtian715/article/details/51534165

[5] https://blog.csdn.net/a493823882/article/details/79282425

[6] Matlab kmeans 帮助文档

[7] 周志华 著. 机器学习, 北京: 清华大学出版社, 2016年1月.

[8] 机器学习(西瓜书). 公式推导解析

 


http://www.ppmy.cn/news/130841.html

相关文章

S32K系列S32K144学习笔记——CAN

一用S32K144苦似海,道友,能不用,千万不去用。 本例程基以下如图所示接口操作,MCU为S32K144,开发平台S32DSworkspace 功能描述:CAN0通信 CAN0_EN–>PB15 如有错误,麻烦帮忙指出,谢…

Android 65K问题之65K来源探究

65K问题相信不少人都遇到过,65K即65536,关于这个值,是怎么来的?本文进行探究! 1Unable to execute dex: method ID not in [0, 0xffff]: 65536PS:本文只是纯探索一下这个65K的来源,仅此而已。 到底是65k还是…

聚类分析(K-means算法)

1 聚类分析 1.1 相似度与距离度量1.2 聚类算法 及 划分方法 2 聚类模型评估(优缺点)3 K-means 在 sklearn方法4 确定K值–肘部法则–SSE5 模型评估指标–轮廓系数法–最近簇 5.1 轮廓系数5.2 最近簇定义—平均轮廓系数 [0,1]:5.3、Canopy算法…

K-means聚类算法

目录 简介 对距离的度量及SSE 问题及如何避免 k-means示例 k值选取 肘方法 可视化方法 TSNE 雷达图 总结一些对K-means聚类算法的理解。 K-means是一种聚类分析方法,聚类分析即是在没有给定划分类别的情况下,根据数据自身的相似度对样本数据进行…

K-Means中K值的选取

K-Means中K值的选择 (1)拍脑袋法(2)肘部法则(Elbow Method)(3)间隔统计量(Gap Statistic)(4)轮廓系数(Silhouette Coeffic…

k近邻算法

本文来自的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/qq_35082030/article/details/60965320?utm_sourcecopy 0. 写在前面 在这一讲的讨论班中,我们将要讨论一下K近邻模型。可能有人会说,K近邻模型有什么好写的&#x…

华为k662c的虚拟服务器,华为k662c路由器怎么设置 | 华为k662c路由器设置_什么值得买...

WIFI6光猫(无线路由器)华为K662C使用设置 2021-01-09 18:50:50 39点赞 155收藏 64评论 华为K662C是一个三合一的设备,有3种工作模式。一种是光猫模式,另外一种是无线路由器模式,还有一种是光纤组网模式(设置较复杂,需要补全shell和更新固件程序,不推荐普通用户尝试,这里就…

K-D树算法的一些总结

在2016年ACM ICPC青岛站的比赛中,一道K-D树问题成为了金银牌的分界线,最后由我们队一个强力队友写出了该题,其实那题本来该由我负责的,都怪我学艺不精。 k-d树(k-dimensional树的简称),是一种分…