#大神教你做项目#之K-means聚类算法的MATLAB实现
Posted 紫冬科协
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了#大神教你做项目#之K-means聚类算法的MATLAB实现相关的知识,希望对你有一定的参考价值。
本文中介绍的K-means,是一种非常经典,也是十分常用的一种聚类算法。考虑到大家对数学公式比较反感,这里只给出大致的描述,较为详细的说明大家可以参考下面这篇博客,里面涉及到算法的数学描述以及结果收敛的证明。
http://www.cnblogs.com/moondark/archive/2012/03/08/2385770.html
在分类之前,我们需要明确分类的标准。设我们一共有 N 个数据点需要分为K个类。这些数据的类别可以是二维平面中的点,也可以是更高维的向量。令μk 表示第k类的平均值(也就是中心)。K-means的目标是使每个点到其所属类的中心“距离”之和最小。“距离”的定义实际上多种多样,这里采用两点间距离(也就是欧氏距离)的平方,因为比较直观并且便于计算。
4. 重复步骤2,3,直到结果收敛
CreateData.m
% 按正态分布生成三组二维平面中的点,每一组100个,方差均为0.5
function X=CreateData()
X =[0.5.*randn(100,2)+ones(100,2);... %第一组:中心(1,1)
0.5.*randn(100,2)-ones(100,2);... %第二组:中心(-1,-1)
0.5.*randn(100,2)+repmat([1,-1],100,1)]; %第三组:中心(1,-1)
%返回矩阵300*2的矩阵X,每一行表示一个点的坐标
Kmeans.m
%通过Kmeans将数据X分成k类
%X是数据集,为n*p矩阵。n为数据个数,p为每一个数据的维数(此运行实例为2维)
%Ctrs为k*p矩阵,存储k个类的中心坐标,Class为n*1矩阵,存储每一个数据的分类(用1,…,k表示)
function [Ctrs,Class]=Kmeans(X,k)
[n,p]=size(X);
Ctrs=zeros(k,p);%用0初始化
Class=ones(n,1);%用1初始化
Init=randi(n,k,1);
for i=1:k %随机选取X中的k个点作为初始中心
Ctrs(i,:)=X(Init(i),:);
end
while 1 %反复迭代,直到中心收敛
TempCtrs=Ctrs;
for i=1:n %根据当前的中心,将每一个数据归类
Class(i)=Sort(X,Ctrs,k,i);
end
for i=1:k %根据新的分类结果,计算每一个类的中心
Ctrs(i,:)=ClassCtr(X,Class,i,n,p);
end
if sum((TempCtrs-Ctrs).^2)<0.001 %判断中心是否收敛
break;
end
end
function D=dist(X,Y) %计算向量X,Y之间欧氏距离的平方
D=sum((X-Y).^2);
%按照欧氏距离平方最小的原则,将X中第i个数据归到第NClass类中
function NClass=Sort(X,Ctr,k,i)
MinDist=dist(X(i,:),Ctr(1,:));
NClass=1;
for j=2:k
Dj=dist(X(i,:),Ctr(j,:));
if Dj<MinDist
MinDist=Dj;
NClass=j;
end
end
%计算第K类的中心,即第K类所有数据的均值
function Ctr=ClassCtr(X,Class,K,n,p)
Sum=zeros(1,p);
num=0;
for i=1:n
if Class(i)==K;
Sum=Sum+X(i,:);
num=num+1;
end
end
Ctr=Sum/num;
Plot.m
%将结果绘制成二维图片,参考帮助文件中kmeans词条
function Plot(X,idx,ctrs)
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(X(idx==3,1),X(idx==3,2),'g.','MarkerSize',12)
plot(ctrs(:,1),ctrs(:,2),'kx',...
'MarkerSize',12,'LineWidth',2)
plot(ctrs(:,1),ctrs(:,2),'ko',...
'MarkerSize',12,'LineWidth',2)
legend('Cluster 1','Cluster 2','Cluster 3','Centroids',...
'Location','NW')
(代码会稍后在科协学术博客更新提供下载)
由于MATLAB实在是博大精深,不可能面面俱到,所以这一部分用来教会大家如何在MATLAB上跑出我写的代码。
安装好MATLAB后(网上有好多安装教程),启动程序,应该是这样一个界面:
点击左上角的NewScript,在同一目录下新建三个源文件,文件名如第二部分所述。(注意文件名一定要与函数名一样,否则无法运行)。然后将源代码依次复制进去。
写好三个源文件之后,左边的“当前目录”栏会显示刚才创建的文件,需要编辑时可以从这里打开。
在CommandWindow中依次输入下列命令:
之后就会弹出分类的结果:
右侧的Workspace栏会显示刚才的计算结果,可以双击某一变量进行查看
需要说明的是MATLAB的帮助文件是学习MATLAB的利器,里面会有详细的语法说明,并提供相应的实例。比如说我们可以查看MATLAB中自带的kmeans算法:
如果不了解源代码中某一函数,可以直接在源代码中右键,点击Help on Selection,即可显示相应的帮助词条:
大家可以尝试生成不同的数据集X、修改一些参数,多次运行,观察最终结果有何不同。
最后我想说的是,这个项目难度不是很大,比较适合MATLAB初学者学习。可以看到算法的每一步都涉及的矩阵以及线性空间的知识,这充分说明大一学习的线性代数和微积分是非常有用的(微积分在证明迭代结果收敛时用到)。所以五字班的同学们一定要认真学习,打好基础。
以上是关于#大神教你做项目#之K-means聚类算法的MATLAB实现的主要内容,如果未能解决你的问题,请参考以下文章