MATLAB实现k-means算法(k-均值)对无标签数据进行聚类,并通过肘部法则确定聚类类别
应一个小伙伴的要求介绍了一下K均值聚类算法。本人也不是很专业,这是之前自学的,如果有错,大家可以提出来,共同进步嘛。
文章目录
- 一、k-means算法(k-均值)
- 1、k-means算法介绍
- 2、k-means算法步骤
- 二、k-means算法MATLAB实现
- 1、函数介绍
- 1)、kmeans函数
- 2)、silhouette函数
- 2、代码实现
- 3、通过肘部法则对算法的聚类类别数进行确定
一、k-means算法(k-均值)
1、k-means算法介绍
聚类属于非监督学习,K均值聚类是最基础常用的聚类算法。它的基本思想是,通过迭代寻找K个簇(Cluster)的一种划分方案,使得聚类结果对应的损失函数最小。其中,损失函数可以定义为各个样本距离所属簇中心点的误差平方和:
J(c,μ)=∑i=1M∣∣xi−μci∣∣2J(c,\mu) = \sum_{i=1}^{M}||x_i-\mu_{c_i}||^2 J(c,μ)=i=1∑M∣∣xi−μci∣∣2
其中xix_ixi表示第iii个样本,cic_ici是xix_ixi所属的簇,μci\mu_{c_i}μci表示簇对应的中心点,MMM是样本数。
图解算法:
2、k-means算法步骤
k-means的核心目标是将给定的数据集划分成K个簇(K是超参),并给出每个样本数据对应的中心点。具体步骤非常简单,可以分为4步:
(1)、数据预处理,主要是标准化、异常点过滤;
(2)、随机选取KKK个中心点,记为μ1(0),μ2(0),⋅⋅⋅,μk(0)\mu_1^{(0)},\mu_2^{(0)},···,\mu_k^{(0)}μ1(0),μ2(0),⋅⋅⋅,μk(0)
(3)、定义损失函数:J(c,μ)=min∑i=1M∣∣xi−μci∣∣2J(c,\mu) = \min\sum_{i=1}^{M}||x_i-\mu_{c_i}||^2J(c,μ)=mini=1∑M∣∣xi−μci∣∣2
(4)、令ttt=0,1,2,… 为迭代步数,重复如下过程直到JJJ收敛
(4.1)、对于每一个样本xix_ixi,将其分配到距离最近的中心
cit<−argmink∣∣xi−μkt∣∣2c_i^t < -arg min_k||x_i-\mu_k^t||^2 cit<−argmink∣∣xi−μkt∣∣2
(4.2)、对于每一个类中心KKK,重新计算该类的中心
μk(t+1)<−argmink∑i:cit=kb∣∣xi−μ∣∣2\mu_k^{(t+1)} < -argmin_k\sum_{i:c_i^t = k}^{b}||x_i-\mu||^2 μk(t+1)<−argminki:cit=k∑b∣∣xi−μ∣∣2
k-means最核心的部分就是先固定中心点,调整每个样本所属的类别来减少 ;再固定每个样本的类别,调整中心点继续减小 。两个过程交替循环, 单调递减直到最(极)小值,中心点和样本划分的类别同时收敛。
注意:KKK均值聚类的最终聚类结果在一定程度上依赖于初始凝聚点或初始分类选择。
算法流程图如下所示:
二、k-means算法MATLAB实现
1、函数介绍
MATLAB中与k-means算法相关的函数有:kmeans函数和silhouette函数。下面分别进行介绍。
1)、kmeans函数
kmeans函数用来作K均值聚类,将nnn个点(或者观测点)分为kkk个类。聚类过程是动态的,通过迭代使得每一个点与所属类重心距离和达到最小。默认情况下,kmeans采用平方欧式距离,其调用格式如下:
1、IDX=kmeans(X,k)IDX = kmeans(X,k)IDX=kmeans(X,k)
将nnn个点(或者观测点)分为kkk个类。输入参数XXX是n×pn \times pn×p的矩阵,矩阵的每一行对应一个点,每一列对应一个变量。输出参数IDXIDXIDX是一个n×1n \times 1n×1的向量,其元素为每一个点所属类别的序列号。
2、[IDX,C]=kmeans(X,k)[IDX,C] = kmeans(X,k)[IDX,C]=kmeans(X,k)
返回kkk个类的类重心坐标矩阵CCC,CCC是一个k×pk \times pk×p的矩阵,第iii行元素为第iii类的类重心坐标。
3、[IDX,C,sumd]=kmeans(X,k)[IDX,C,sumd] = kmeans(X,k)[IDX,C,sumd]=kmeans(X,k)
返回类内距离和(即类各点与类重心距离之和)向量sumdsumdsumd,sumdsumdsumd是一个1×k1 \times k1×k的向量,第iii行元素为第iii类的类内距离之和。
4、[IDX,C,sumd,D]=kmeans(X,k)[IDX,C,sumd,D] = kmeans(X,k)[IDX,C,sumd,D]=kmeans(X,k)
返回每个点与每个类重心之间的距离矩阵DDD,DDD是一个n×kn \times kn×k的矩阵,第iii行第jjj列元素是第iii个点与第jjj类的类重心之间的距离。
4、[⋅⋅⋅]=kmeans(⋅⋅⋅,paraml1,val1,param2,val2,⋅⋅⋅)[···] = kmeans(···,paraml1,val1,param2,val2,···)[⋅⋅⋅]=kmeans(⋅⋅⋅,paraml1,val1,param2,val2,⋅⋅⋅)
允许用户设置更多的参数及参数值,用来控制kmeans函数所用的迭代算法。param1,param2,⋅⋅⋅param1,param2,···param1,param2,⋅⋅⋅为参数名,val1,val2,⋅⋅⋅val1,val2,···val1,val2,⋅⋅⋅为相应的参数值。可用的参数名可以上MATLAB官网查看。
2)、silhouette函数
silhouettesilhouettesilhouette函数用来根据cluster、clusterdata或kmeanscluster、clusterdata 或kmeanscluster、clusterdata或kmeans函数的聚类结果绘制轮廊图,从轮廊图上能看出每个点的分类是否合理。轮康图上第iii个点的轮廊值(silhouettevalue)(silhouette value)(silhouettevalue)定义为:
S(i)=min(b)−amax[a,min(b)],i=1,2,⋅⋅⋅,nS(i) = \frac{min(b)-a}{\max[a,\min(b)]},i=1,2,···,n S(i)=max[a,min(b)]min(b)−a,i=1,2,⋅⋅⋅,n
其中,aaa是第iii个点与同类的其他点之间的平均距离,bbb为一个向量,其元素是第iii个点与不同类的类内各点之间的平均距离,例如bbb的第个kkk元素是第iii个点与第k类各点之间的平均距离。
轮廓值S(i)S(i)S(i)的取值范幽为[-1,1],S(i)S(i)S(i)值越大,说明第iii个点的分类越合理,当 S(i)S(i)S(i)<0 时,说明第iii个点的分类不合理,还有比目前分类更合理的方案。
silhouettesilhouettesilhouette函数函数的调用格式如下:
1、silhouette(X,clust)silhouette(X,clust)silhouette(X,clust)
根据样本观测值短阵XXX 和聚类结果clustclustclust绘制轮廓图。输人参数XXX是一个n×pn \times pn×p的矩阵,矩阵的每一行对应一个观测,每一列对应一个变量。clustclustclust是聚类结果,可以是由每个观测所属类的类序号构成的数值向量,也可以是由类名称构成的字符矩阵或字符串元胞数组。silhouettesilhouettesilhouette函数会把clustclustclust 中的NaNNaNNaN或空字符作为缺失数据,从而忽略XXX中相应的观测。默认情况下,silhouettesilhouettesilhouette函数采用平方欧氏距离。
2、s=silhouette(X,clust)s = silhouette(X, clust)s=silhouette(X,clust)
返回轮廓值向量sss,它是一个n×1n \times 1n×1的向量,其元素为相应点的轮廓值。此时不会绘制轮廓图。
3、[s,h]=silhouette(x,clust)[s,h] = silhouette(x,clust)[s,h]=silhouette(x,clust)
绘制轮廓图,并返回轮廓值向量sss和图形句柄hhh。
4、[⋅⋅⋅]=silhouette(x,clust,metric)[···]= silhouette(x,clust, metric)[⋅⋅⋅]=silhouette(x,clust,metric)
指定距离计算的方法,绘制轮廓图。输人参数metricmetricmetric为字符串或距离矩阵,用来指定距
离计算的方法或距离矩阵。silhouettesilhouettesilhouette函数支持的各种距离可以上MATLAB官网查看。
5、[⋅⋅⋅]=silhouette(x,clust,distfun,p1,p2,⋅⋅⋅)[···]= silhouette(x,clust, distfun,p1,p2,···)[⋅⋅⋅]=silhouette(x,clust,distfun,p1,p2,⋅⋅⋅)
接受函数句柄作为第三个输入,即distfundistfundistfun为函数句柄,用来自定义距离计算方法。distfundistfundistfun对应的函数形式如下
d=distfun(X0,X,p1,p2,⋅⋅⋅)d = distfun(X0,X,p1,p2,···)d=distfun(X0,X,p1,p2,⋅⋅⋅)
其中X0X0X0是一个1×p1 \times p1×p的向量,表示一个点的坐标。XXX是n×pn \times pn×p的矩阵,p1,p2,⋅⋅⋅p1,p2,···p1,p2,⋅⋅⋅是可选的参数。ddd是n×1n \times 1n×1的距离向量,ddd的第kkk个元素是X0X0X0与XXX矩阵的第kkk行之间的距离。
2、代码实现
本文数据采用了MATLAB自带的鸢尾花数据集
1、导入数据集
clc
clear;
load fisheriris
2、用数据集的第三列和第四列数据将原数据画图呈现
X = meas(:,3:4);
figure;
plot(X(:,1),X(:,2),'k*','MarkerSize',5);
title 'Fisher''s Iris Data';
xlabel 'Petal Lengths (cm)';
ylabel 'Petal Widths (cm)';
结果如下所示:
3、使用kmeans将其聚类并将其可视化
rng(1); % 设置随机数种子,使得结果具有重现性
[idx,C] = kmeans(X,3);
figure;
plot(X(idx==1,1),X(idx==1,2),'r.','MarkerSize',12)
hold on
plot(X(idx==2,1),X(idx==2,2),'b.','MarkerSize',12)
plot(C(:,1),C(:,2),'kx',...'MarkerSize',15,'LineWidth',3)
legend('Cluster 1','Cluster 2','Centroids',...'Location','NW')
title 'Cluster Assignments and Centroids'
hold off
结果如下所示:
4、画出轮廓图
[S, H] = silhouette(X,idx); % 绘制轮廓图,并返回轮廓值向量S和图形句柄H
结果如下所示:
可以看出,每一个观测的轮廓值都是正的,这说明我们分为三类是合理的。
全部代码如下所示:
clc
clear;
load fisheriris
X = meas(:,3:4);
figure;
plot(X(:,1),X(:,2),'k*','MarkerSize',5);
title 'Fisher''s Iris Data';
xlabel 'Petal Lengths (cm)';
ylabel 'Petal Widths (cm)';rng(1); % 设置随机数种子,使得结果具有重现性
[idx,C] = kmeans(X,3);
figure;
plot(X(idx==1,1),X(idx==1,2),'r.','MarkerSize',12)
hold on
plot(X(idx==2,1),X(idx==2,2),'b.','MarkerSize',12)
hold on;
plot(X(idx==3,1),X(idx==3,2),'y.','MarkerSize',12)
hold on;
% plot(X(idx==4,1),X(idx==4,2),'y.','MarkerSize',12)
% hold on;
plot(C(:,1),C(:,2),'kx',...'MarkerSize',15,'LineWidth',3)
legend('Cluster 1','Cluster 2','Cluster 3','Centroids',...'Location','NW')
title 'Cluster Assignments and Centroids'
hold off
[S, H] = silhouette(X,idx); % 绘制轮廓图,并返回轮廓值向量S和图形句柄H
3、通过肘部法则对算法的聚类类别数进行确定
通常我们遇到的问题大多数都是无法确定确定聚类个数的,属于无监督机器学习。但是K均值聚类算法又要我们提前规定好聚类的类别数KKK。这样就会导致如果给的聚类类别数KKK不恰当,就会导致聚类效果很差。
1、下面我们用刚才的数据,把聚类的类别数改为四类。
代码如下:
clc
clear;
load fisheriris
X = meas(:,3:4);
figure;
plot(X(:,1),X(:,2),'k*','MarkerSize',5);
title 'Fisher''s Iris Data';
xlabel 'Petal Lengths (cm)';
ylabel 'Petal Widths (cm)';rng(1); % 设置随机数种子,使得结果具有重现性
[idx,C] = kmeans(X,4);
figure;
plot(X(idx==1,1),X(idx==1,2),'r.','MarkerSize',12)
hold on
plot(X(idx==2,1),X(idx==2,2),'b.','MarkerSize',12)
hold on;
plot(X(idx==3,1),X(idx==3,2),'y.','MarkerSize',12)
hold on;
plot(X(idx==4,1),X(idx==4,2),'y.','MarkerSize',12)
hold on;
plot(C(:,1),C(:,2),'kx',...'MarkerSize',15,'LineWidth',3)
legend('Cluster 1','Cluster 2','Cluster 3','Cluster 4','Centroids',...'Location','NW')
title 'Cluster Assignments and Centroids'
hold off
结果试图如下:
轮廓图如下所示:
可以看出,有些点的轮廓值小于0,说明该些点的聚类结果较差,不合理。
2、用肘部法则判断最佳聚类类别数。
Elbow Method(肘部法则) :Elbow意思是手肘,如下图左所示,此种方法适用于 K 值相对较小的情况,当选择的k值小于真正的时,k每增加1,cost值就会大幅的减小;当选择的k值大于真正的K时, k每增加1,cost值的变化就不会那么明显。这样,正确的k值就会在这个转折点,类似elbow的地方。 如下图:
下面用本道题通过对不同的KKK值求解进行解释:
代码如下:
clc
clear;
load fisheriris
X = meas(:,3:4);
% figure;
% plot(X(:,1),X(:,2),'k*','MarkerSize',5);
% title 'Fisher''s Iris Data';
% xlabel 'Petal Lengths (cm)';
% ylabel 'Petal Widths (cm)';
%
% rng(1); % 设置随机数种子,使得结果具有重现性
% [idx,C] = kmeans(X,4);
% figure;
% plot(X(idx==1,1),X(idx==1,2),'r.','MarkerSize',12)
% hold on
% plot(X(idx==2,1),X(idx==2,2),'b.','MarkerSize',12)
% hold on;
% plot(X(idx==3,1),X(idx==3,2),'y.','MarkerSize',12)
% hold on;
% plot(X(idx==4,1),X(idx==4,2),'y.','MarkerSize',12)
% hold on;
% plot(C(:,1),C(:,2),'kx',...
% 'MarkerSize',15,'LineWidth',3)
% legend('Cluster 1','Cluster 2','Cluster 3','Cluster 4','Centroids',...
% 'Location','NW')
% title 'Cluster Assignments and Centroids'
% hold off
% [S, H] = silhouette(X,idx); % 绘制轮廓图,并返回轮廓值向量S和图形句柄H
for k=2:8rng(100)
[lable,c,sumd,d]=kmeans(X,k,'dist','sqeuclidean');
% data,n×p原始数据向量
% lable,n×1向量,聚类结果标签;
% c,k×p向量,k个聚类质心的位置
% sumd,k×1向量,类间所有点与该类质心点距离之和
% d,n×k向量,每个点与聚类质心的距离
sse1 = sum(sumd.^2);
D(k,1) = k;
D(k,2) = sse1;
endplot(D(2:end,1),D(2:end,2))
hold on;
plot(D(2:end,1),D(2:end,2),'or');title('不同K值聚类偏差图')
xlabel('分类数(K值)')
ylabel('簇内误差平方和')
结果试图如下:
由此图可以看出,当分类数K=3K=3K=3时折线的下降趋势骤缓,故可将类别数设置为 3。
喜欢的小伙伴麻烦点个赞奥,谢谢啦
MATLAB实现k-means算法(k-均值)对无标签数据进行聚类,并通过肘部法则确定聚类类别相关推荐
- kmeans改进 matlab,基于距离函数的改进k―means 算法
摘要:聚类算法在自然科学和和社会科学中都有很普遍的应用,而K-means算法是聚类算法中经典的划分方法之一.但如果数据集内相邻的簇之间离散度相差较大,或者是属性分布区间相差较大,则算法的聚类效果十分有 ...
- k means算法C语言伪代码,K均值算法(K-Means)
1. K-Means算法步骤 算法步骤 收敛性定义,畸变函数(distortion function): 伪代码: 1) 创建k个点作为K个簇的起始质心(经常随机选择) 2) 当任意一个点的蔟分配结果 ...
- 【DELM回归预测】基于matlab多元宇宙优化算法改进深度学习极限学习机数据回归预测【含Matlab源码 2230期】
⛄一.多元宇宙优化算法 MVO是Seyedali Mirjalili受到多元宇宙理论的启发提出来的元启发式优化算法.主要根据多元宇宙理论的3个主要概念-白洞.黑洞和虫洞,来建立数学模型. MVO算法中 ...
- k均值聚类算法(K Means)及其实战案例
算法说明 K均值聚类算法其实就是根据距离来看属性,近朱者赤近墨者黑.其中K表示要聚类的数量,就是说样本要被划分成几个类别.而均值则是因为需要求得每个类别的中心点,比如一维样本的中心点一般就是求这些样本 ...
- python k近邻算法_python中的k最近邻居算法示例
python k近邻算法 K最近邻居(KNN) (K-Nearest Neighbors (KNN)) KNN is a supervised machine learning algorithm t ...
- K means 图片压缩
k-means的基本原理较为清晰,这里不多赘述,本次博客主要通过基础的k means算法进行图像的压缩处理. 原理分析 在彩色图像中,每个像素的大小为3字节(RGB),可以表示的颜色总数为256 * ...
- 机器学习——聚类之k近邻算法及python使用
聚类算法之k近邻及python使用 什么是k近邻算法 k近邻算法流程 使用sklearn进行代码实现 数据集介绍 标准化 代码实现 写在开头,套用我的老师的一句话目前所有自然学科的前沿都是在研究数学, ...
- 机器学习第七章之K近邻算法
K近邻算法(了解) 7.1 K近邻算法 7.1.1 K近邻算法的原理介绍 7.1.2 K近邻算法的计算步骤及代码实现 7.2 数据预处理之数据归一化 7.2.1 min-max标准化 7.2.2 Z- ...
- 机器学习实战之K近邻算法
k近邻算法概述 简单地说,K近邻算法采用测量不同特征值之间的距离方法进行分类. 优 点 :精度高.对异常值不敏感.无数据输入假定. 缺点:计算复杂度高.空间复杂度高. 适用数据范围:数值型和标称型. ...
最新文章
- 积少成多 Flash(ActionScript 3.0 Flex 3.0) 系列文章索引
- redis的过期策略和淘汰策略
- android仿qq聊天项目点评,android 实现qq聊天对话界面效果
- java线程的创建线程_多线程(Thread、线程创建、线程池)
- java并发编程实战阅读总结(b)
- Java 集合(初稿)
- leetcode679:24Game
- mysql反掩码_Linux运维:文件目录管理
- wordpress在Linux nginx下权限设置
- 【渝粤教育】国家开放大学2018年春季 0266-22T设计构成 参考试题
- 【内购篇】5 分钟教你成为会赚钱的独立开发者
- bus Hound使用详解
- IP地址和mac地址的区别
- 微信小程序“IU同学”使用方法,一起来找同学!
- 电桥测量电路Multisim仿真AD电路原理图PCB
- 中南大学2021计算机专硕复试分数线,中南大学2021年考研复试分数线
- Cortex-M3技术参考手册 2022年3月1日
- 数学之美:常用的微分,求导和积分公式大总结
- 【STM32】HAL库-备份寄存器(BKP)
- 如何简单的模拟发送http post请求