K-means算法是一种聚类算法,属于无监督学习。K-means算法主要做两件事情:1、簇分配;2、移动聚类中心。
算法主要流程:
1. 随机地选择k个对象,每个对象初始地代表了一个簇的中心;
2. 对剩余的每个对象,根据其与各簇中心的距离,将它赋给最近的簇;
3. 重新计算每个簇的平均值,更新为新的簇中心;
4. 不断重复2、3,直到准则函数收敛。
K-means算法伪代码
Repeat{
for i=1 to m
c(i)=index (form 1 to K) of cluster centroid closest to x(i) %簇分配
for k=1 to K
center=mean of points assigned to cluster k %移动聚类中心
}
matlab 代码实现
%%输入数据
function data=datafile()
%随机产生三组随机数
% 第一组数据
mu1=[0 0 ]; %均值
S1=[.1 0 ;0 .1]; %协方差
data1=mvnrnd(mu1,S1,100); %产生高斯分布数据
%第二组数据
mu2=[1 1 ];
S2=[.1 0 ;0 .1];
data2=mvnrnd(mu2,S2,100);
% 第三组数据
mu3=[-1.25 1.25 ];
S3=[.1 0 ;0 .1];
data3=mvnrnd(mu3,S3,100);
data=[data1;data2;data3];
end
%%k-means函数
function [id,center]=k_means(data,K)
%K-means聚类
%id是表示数据点属于哪一类的标记,center是每个类的聚类中心
%data为输入数据,K为需要分的聚类
% data=datafile();
% K=3;
[m,n]=size(data); %求输入数据点的个数m
id=zeros(m,1);
%随机初始化聚类中心
C=zeros(K,n);
for i=1:K
C(i,:)=data(randi(m,1),:); %随机初始化聚类中心%randi(n,1)产生一个1到n的伪随机整数
end
%C(i)表示第i类的聚类中心
while 1
%分配簇
for x=1:m
for y=1:K
d(y)=norm(data(x,:)-C(y,:)); %计算数据点到每个聚类中心的距离
end
[~,idx]=min(d);
id(x)=idx;
end
%更新聚类中心
new_C=zeros(K,n);
num=zeros(K);
q=0;
for y=1:K
for x=1:m
if id(x,1)==y
new_C(y,:)=new_C(y,:)+data(x,:);
num(y)=num(y)+1;
end
end
new_C(y,:)=new_C(y,:)/num(y);
if norm(new_C(y,:)-C(y,:))<0.1 %判断是否收敛
q=q+1;
end
end
% %更新聚类第二种写法
% for y=1:K
% datak=data(id==y,:); %属于第k类的数据点
% new_C(y,:)=mean(datak);
% if norm(new_C(y,:)-C(y,:))<0.1
% q=q+1;
% end
% end
%%%
if q==K
break;
else
C=new_C;
end
end
center=C;
end
%%运行程序
data=datafile();
%k-means均值聚类
K=3;
figure
[id,center]=k_means(data,K);
plot(data(id==1,1),data(id==1,2),'k*');
hold on;
plot(data(id==2,1),data(id==2,2),'g*');
hold on;
plot(data(id==3,1),data(id==3,2),'b*');
hold on;
plot(center(:,1),center(:,2),'ro');
grid on;
效果图: