![cover](https://img-blog.csdnimg.cn/e189a20c885141ecb466701e39ae85f9.png)
k-中心聚类(k-medoids)算法——附MATLAB代码
k-medoids聚类是一种无监督的聚类算法,它对未标记数据中的对象进行聚类
k-中心聚类(k-medoids)算法——附MATLAB代码
k-medoids算法
k-medoid(也称为围绕medoid的划分)算法是由Kaufman和Rousseeuw于1987年提出的。中间点可以定义为簇中的点,其与簇中所有其他点的相似度最小。
k-medoids聚类是一种无监督的聚类算法,它对未标记数据中的对象进行聚类。k-medoids算法步骤:
步骤1:随机选择k个样本作为初始的簇中心;
步骤2:对剩余的每个样本,将其划分入距离它最近的簇中心所在的簇中,从而形成k个簇;
步骤3:重新计算簇中心,即对于每个簇,找到该簇中的一个样本点,称为medoid,使得该簇中所有其他点到该样本点的距离之和最小;
k-medoids聚类中心一定是原始样本点,而k-means聚类中心不一定是原始样本点
步骤4:如果簇中心没有发生任何改变,算法停止,否则回到步骤2。
k-中心聚类算法代码
function k_medoids(x,k)
%%
%生成数据(为了可视化,生成二维数据)
%x=[rand(20,2);rand(30,2)+1;rand(40,2)*2+1.5];
%k=3;
%样本分布可视化
figure(1)
subplot(1,2,1)%子图1
scatter(x(:,1),x(:,2),"filled")
title("样本分布")
[m,n]=size(x);
%产生1-m范围内的随机的k个整数
%从原数组中提出这k个点对应坐标
s0=randperm(m,k);
c=x(s0,:);
%初始化
c0=zeros(k,n);
D=zeros(m,k);
%%
while (max(abs(c-c0))>0.0001)
c0=c;
%定义行数为k的元胞数组用以存储簇对应样本点
cluster=cell(k,1);
%将选取的k个点加入到对应的k个存储单元,每个单元的第一行存储相对应的簇中心
for i=1:k
cluster{i}=c(i,:);
end
%计算其他样本点到这k个点的距离,然后按照距离最近原则划分这些点
for i=1:k
D(:,i)=sum((x-c(i,:)).^2,2).^0.5;
end
[~,id]=min(D,[],2);
for i=1:k
%将样本点划分到对应的簇中
cluster{i}=cat(1,cluster{i},x(id==i,:));
len=size(cluster{i},1);
d=zeros(len,1);
%计算每一个簇内的样本点到该簇内其他所有样本点的距离之和
for j=1:len
d(j)=sum(sum((cluster{i}-cluster{i}(j,:)).^2,2).^0.5);
end
%更新簇内中心
%将距离其余样本点的距离之和最小的样本点作为该簇新的中心
[~,id1]=min(d);
c(i,:)=cluster{i}(id1,:);
end
end
%绘制k-中心算法聚类结果
subplot(1,2,2) %子图2
for i=1:k
scatter(cluster{i}(:,1),cluster{i}(:,2),'filled');
hold on
%聚类中心(!k个原始样本点)
plot(c(i,1),c(i,2),"o","MarkerSize",9)
end
title("k-中心聚类结果")
hold off
测试结果可视化:
算法总结
k-medoids与k-means比较
k-means算法是每次选择簇的均值作为新的中心点,迭代直到簇中心不再变化(趋于稳定)。其缺点是对离群点特别敏感,因为一个很大的极端值对象会扭曲数据分布,使簇均值严重偏离;于是我们考虑新的簇中心不用均值表示而是选择簇内的某个对象,只要使总的代价降低就行,即k-medoids聚类算法。
在k-medoids聚类中,我们将medoid作为参考点,而不是像k-means聚类那样将簇中对象的质心作为参考点。medoid是簇中位置最集中的对象,或其与所有对象的平均差异性最小。因此,k-medoids算法比k-means算法对噪声更具鲁棒性。
k-medoids算法的优缺点
(1). k-medoids算法的优点:
- 与其他聚类算法相比,它有效地处理了数据中存在的噪声和异常值;因为它使用medoid将对象划分为集群。
- 易于实现且易于理解。
- 与其他聚类算法相比,k-medoid算法速度相对较快。
- 它以固定的迭代次数输出最终的对象簇。
(2). k-medoids算法的缺点:
- 对于同一数据集上的不同运行,可能会产生不同的聚类,因为最初,我们从所有数据对象中随机选择k个medoid,并将它们逐个分配给每个聚类,使其成为该聚类的初始medoid。
- 它在开始时固定了k(簇/组的数量)的值,因此我们不知道当k的值是多少时,结果是准确和可区分的。
- 它的总体计算时间和对象在簇或组中的最终分布取决于初始划分。
![Logo](https://devpress.csdnimg.cn/79de2bf0b7994defa4242ef90d5513fa.jpg)
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)