目录
K-means聚类算法
算法流程
优点
缺点
随机点聚类
人脸聚类
旋转物体聚类
K-means聚类算法
K-means聚类算法是一种无监督的学习方法,通过对样本数据进行分组来发现数据内在的结构。K-means的基本思想是将n个实例分成k个簇,使得同一簇内数据相似度高而不同簇之间数据相似度低。
算法流程
K-means的算法过程如下:
优点
K-means优点:
①是解决聚类问题的一种经典算法,简单、快速。
②对处理大数据集,该算法保持可伸缩性和高效率。
③当簇近似为高斯分布时,它的效果比较好。
缺点
K-means缺点:
①在簇的平均值可被定义的情况下才能使用,可能不适用于某些应用。
②必须事先给出要生成的簇的数目k。
③对初值敏感,对于不同的初始值,可能会导致不同的结果。
④不适合发现非凸形状的簇或者大小差别很大的簇。
⑤对噪声和孤立点数据敏感。
随机点聚类
代码中的变量mu
和sigma
定义了两个高斯分布的均值和标准差,用来生成三个不同的类别的样本数据。然后将这些样本数据合并在一个矩阵sample
中。
接下来,代码定义了K值为3,表示将样本数据聚成3个类别。classSampleNumber
表示每个类别的样本数量为100。color
矩阵用于存储样本点的颜色信息,classColor
定义了三个类别的颜色。
class
向量用于存储每个样本点的类别标签,初始值为0。classCenter
矩阵定义了初始的类别中心点的坐标。
之后的代码通过迭代更新类别中心点的坐标,使得样本点与其所属类别中心点的距离最小。具体的更新过程为:对每个样本点,计算其与三个类别中心点的距离,将其归到距离最近的类别,并更新该类别的样本数和下一次迭代的类别中心点坐标。
每次迭代完成后,代码通过绘制散点图展示了聚类结果。其中,三个类别的中心点使用实心圆点表示,不同类别的样本点使用不同符号和颜色进行标记。
代码最终会生成四张图,分别展示初始状态和三次迭代后的聚类结果。
mu=[0 0];
sigma=[1 1];
class1=mvnrnd(mu,sigma,10);
mu=[5 5];
class2=mvnrnd(mu,sigma,10);
mu=[10 10];
class3=mvnrnd(mu,sigma,10);
sample=[class1;class2;class3];
k=3;
sampleNumberAll=size(sample,1);
classSampleNumber=100;
color=zeros(sampleNumberAll,3);
classColor=[[255 0 0];[0 255 0];[0 0 255]];
class=zeros(1,k);
classCenter=[2 8;3 9;4 10];
figure(1);
hold on;
scatter(classCenter(:,1),classCenter(:,2),[],classColor,'filled');
scatter(sample(:,1),sample(:,2),'m');
for iterator=1:3
nextCenter=[0 0;0 0;0 0];
classNumber=[0 0 0];
for i=1:sampleNumberAll
distances=zeros(1,k);
for j=1:k
distances(j)=pdist2(sample(i,:),classCenter(j,:));
end
[~,index]=sort(distances);
class(i)=index(1);
classNumber(class(i))=classNumber(class(i))+1;
nextCenter(class(i),:)=nextCenter(class(i),:)+sample(i,:);
end
for i=1:k
if classNumber(i)~=0
classCenter(i,:)=nextCenter(i,:)/classNumber(i);
end
end
figure(iterator+1);
scatter(classCenter(:,1),classCenter(:,2),[],classColor,'filled');
hold on;
for i=1:sampleNumberAll
if class(i)==1
scatter(sample(i,1),sample(i,2),'r','s');
elseif class(i)==2
scatter(sample(i,1),sample(i,2),'g','d');
else
scatter(sample(i,1),sample(i,2),'b','h');
end
end
end
人脸聚类
代码和随机生成点的差不多,不过有一个地方我研究了很久,那就是如何给每个点配上相应的照片,我之前都是一张张手贴上去的,这次努力研究了一把,终于实现自动配图。
figure(2);
scatter(classCenter(:,1),classCenter(:,2),[],classColor,'filled');
hold on;
for i=1:sampleNumberAll
if class(i)==1
scatter(sample(i,1),sample(i,2),'r','s','filled');
elseif class(i)==2
scatter(sample(i,1),sample(i,2),'g','d','filled');
end
hold on;
picture=pictures(:,i);
picture=reshape(picture,128,128);
picture=imrotate(picture,180);
colormap(gray(256));
image('CData',picture,'XData',[sample(i,1)-150 sample(i,1)+150],'YData',[sample(i,2)-500+700 sample(i,2)+500+700]);
end
旋转物体聚类
实际上你也可以看出来,k-means适合聚一堆的凸形状的,像下面这种流形和条形的不凸的就没有办法聚的好。