原理:
K-means算法的工作原理:首先随机从数据集中选取K个点,每个点初始地代表每个族的聚类中心,然后计算剩余各个样本到聚类中心的距离,将它赋给最近的簇,接着重新计算每一簇的平均值, 整个过程不断重复,如果相邻两次调整没有明显变化,说明数据聚类形成的簇已经收敛。
计算流程
X1=(0,1)
X2=(1,0)
X3=(3,2)
X4=(7,7)
X5=(8,7)
X6=(9,7)
步骤一:随机选取N个点作为初始聚类中心,本文以x1(0,1),x2(1,0)为初始聚类中心
步骤二:计算各点到聚类中心的距离
步骤三:根据各点到聚类中心的距离将x分为2簇
类别 | 集合 |
(0,1) | X1 |
(1,0) | X2,x3,x4,x5,x6 |
步骤四:计算每簇x的平均坐标值,生成新的聚类中心
将新生成的聚类中心(0,1),(28/5,23/5)重复步骤一,知道新生成的聚类中心与上一步生成的聚类中心相同,则结束循环。
代码展示
%% K-means 均值聚类
x = [0 1;1 0;3 2;7 7;8 7;9 7]
z = zeros(2,2)
z1 = zeros(2,2)%设置两个聚类中心
z = x(1:2,1:2)
while 1%1是判断表达式,1显示永远为真,即永远循环,所以循环体中必须存在break
count = zeros(2,1);
allsum = zeros(2,2);
for i = 1:6
temp1 = sqrt((z(1,1)-x(i,1)).^2+(z(1,2)-x(i,2)).^2);%sqrt返还数组每一个元素的平方根,这里是计算x每一个坐标点与第一个坐标点的距离
temp2 = sqrt((z(2,1)-x(i,1)).^2+(z(2,2)-x(i,2)).^2);%计算x每一个坐标点与第二个坐标点的距离
if(temp1<temp2)%x中与第一个接近的坐标点计数、求和
count(1) = count(1)+1;
allsum(1,1) = allsum(1,1)+x(i,1);
allsum(1,2) = allsum(1,2)+x(i,2);
t(i,1) = x(i,1)
t(i,2) = x(i,2)
%x中与第一个接近的坐标点计数、求和
else
(temp2<temp1)
count(2) = count(2)+1;
allsum(2,1) = allsum(2,1)+x(i,1);
allsum(2,2) = allsum(2,2)+x(i,2);
end
end
z1(1,1) = allsum(1,1)/count(1);%与第一个接近的坐标点的横坐标求平均数
z1(1,2) = allsum(1,2)/count(1);%与第一个接近的坐标点的纵坐标求平均数
z1(2,1) = allsum(2,1)/count(2);%与第二个接近的坐标点的横坐标求平均数
z1(2,2) = allsum(2,2)/count(2);%与第二个接近的坐标点的横坐标求平均数
if(z == z1)
break
else
z = z1
end
end
如何改变聚类中心数(以3为例)
%改变聚类中心数为3
x = [0 1;1 0;3 2;7 7;8 7;9 7]
z = zeros(3,2)
z1 = zeros(3,2)%设置两个聚类中心
z = x(1:3,1:2)
while 1%1是判断表达式,1显示永远为真,即永远循环,所以循环体中必须存在break
count = zeros(3,1);
allsum = zeros(3,2);
for i = 1:6
temp1 = sqrt((z(1,1)-x(i,1)).^2+(z(1,2)-x(i,2)).^2);%sqrt返还数组每一个元素的平方根,这里是计算x每一个坐标点与第一个坐标点的距离
temp2 = sqrt((z(2,1)-x(i,1)).^2+(z(2,2)-x(i,2)).^2);%计算x每一个坐标点与第二个坐标点的距离
temp3 = sqrt((z(3,1)-x(i,1)).^2+(z(3,2)-x(i,2)).^2);
if(temp1<temp2)&&(temp1<temp3)%x中与第一个接近的坐标点计数、求和
count(1) = count(1)+1;
allsum(1,1) = allsum(1,1)+x(i,1);
allsum(1,2) = allsum(1,2)+x(i,2);
%x中与第一个接近的坐标点计数、求和
elseif(temp2<temp1)&&(temp2<temp3)
count(2) = count(2)+1;
allsum(2,1) = allsum(2,1)+x(i,1);
allsum(2,2) = allsum(2,2)+x(i,2);
else
count(3) = count(3)+1;
allsum(3,1) = allsum(3,1)+x(i,1);
allsum(3,2) = allsum(3,2)+x(i,2);
end
end
z1(1,1) = allsum(1,1)/count(1);%与第一个接近的坐标点的横坐标求平均数
z1(1,2) = allsum(1,2)/count(1);%与第一个接近的坐标点的纵坐标求平均数
z1(2,1) = allsum(2,1)/count(2);%与第二个接近的坐标点的横坐标求平均数
z1(2,2) = allsum(2,2)/count(2);%与第二个接近的坐标点的横坐标求平均数
z1(3,1) = allsum(3,1)/count(3);
z1(3,2) = allsum(3,2)/count(3);
if(z == z1)
break
else
z = z1
end
end
对聚类中心的原始数据可视化
x = [0 1;1 0;3 2;7 7;8 7;9 7]
z = zeros(2,2)
z1 = zeros(2,2)%设置两个聚类中心
z = x(1:2,1:2)
while 1%1是判断表达式,1显示永远为真,即永远循环,所以循环体中必须存在break
count = zeros(2,1);
allsum = zeros(2,2);
for i = 1:6
temp1 = sqrt((z(1,1)-x(i,1)).^2+(z(1,2)-x(i,2)).^2);%sqrt返还数组每一个元素的平方根,这里是计算x每一个坐标点与第一个坐标点的距离
temp2 = sqrt((z(2,1)-x(i,1)).^2+(z(2,2)-x(i,2)).^2);%计算x每一个坐标点与第二个坐标点的距离
if(temp1<temp2)%x中与第一个接近的坐标点计数、求和
count(1) = count(1)+1;
allsum(1,1) = allsum(1,1)+x(i,1);
allsum(1,2) = allsum(1,2)+x(i,2);
t(i,1) = x(i,1)
t(i,2) = x(i,2)
%x中与第一个接近的坐标点计数、求和
else
(temp2<temp1)
count(2) = count(2)+1;
allsum(2,1) = allsum(2,1)+x(i,1);
allsum(2,2) = allsum(2,2)+x(i,2);
end
end
z1(1,1) = allsum(1,1)/count(1);%与第一个接近的坐标点的横坐标求平均数
z1(1,2) = allsum(1,2)/count(1);%与第一个接近的坐标点的纵坐标求平均数
z1(2,1) = allsum(2,1)/count(2);%与第二个接近的坐标点的横坐标求平均数
z1(2,2) = allsum(2,2)/count(2);%与第二个接近的坐标点的横坐标求平均数
if(z == z1)
break
else
z = z1
end
end
plot(x(:,1),x(:,2),'k*',...
'LineWidth',2,...
'MarkerSize',10,...
'MarkerEdgeColor','k',...
'MarkerFaceColor',[0.5,0.5,0.5])
hold on
plot(z1(:,1),z1(:,2),'ko',...
'LineWidth',2,...
'MarkerSize',10,...
'MarkerEdgeColor','k',...
'MarkerFaceColor',[0.5,0.5,0.5])
set(gca,'LineWidth',2);
xlabel('特征1','fontsize',12)
ylabel('特征2','fontsize',12)
title('k-means分类图','fontsize',12)
对不同分类的簇可视化区分
x = [0 1;1 0;3 2;7 7;8 7;9 7]
z = zeros(2,2)
z1 = zeros(2,2)%设置两个聚类中心
z = x(1:2,1:2)
while 1%1是判断表达式,1显示永远为真,即永远循环,所以循环体中必须存在break
count = zeros(2,1);
allsum = zeros(2,2);
for i = 1:6
temp1 = sqrt((z(1,1)-x(i,1)).^2+(z(1,2)-x(i,2)).^2);%sqrt返还数组每一个元素的平方根,这里是计算x每一个坐标点与第一个坐标点的距离
temp2 = sqrt((z(2,1)-x(i,1)).^2+(z(2,2)-x(i,2)).^2);%计算x每一个坐标点与第二个坐标点的距离
if(temp1<temp2)%x中与第一个接近的坐标点计数、求和
count(1) = count(1)+1;
allsum(1,1) = allsum(1,1)+x(i,1);
allsum(1,2) = allsum(1,2)+x(i,2);
t(i,1) = x(i,1)
t(i,2) = x(i,2)
%x中与第一个接近的坐标点计数、求和
else
(temp2<temp1)
count(2) = count(2)+1;
allsum(2,1) = allsum(2,1)+x(i,1);
allsum(2,2) = allsum(2,2)+x(i,2);
t(i,3) = x(i,1)
t(i,4) = x(i,2)
end
end
z1(1,1) = allsum(1,1)/count(1);%与第一个接近的坐标点的横坐标求平均数
z1(1,2) = allsum(1,2)/count(1);%与第一个接近的坐标点的纵坐标求平均数
z1(2,1) = allsum(2,1)/count(2);%与第二个接近的坐标点的横坐标求平均数
z1(2,2) = allsum(2,2)/count(2);%与第二个接近的坐标点的横坐标求平均数
if(z == z1)
break
else
z = z1
end
end
%% 用颜色分类可视化
t1 = t(1:count(1),1:2)
t2 = t(count(1)+1:6,3:4)%6为聚类元素的总数
plot(t1(:,1),t1(:,2),'k*',...
'LineWidth',2,...
'MarkerSize',10,...
'MarkerEdgeColor','k',...
'MarkerFaceColor',[0.5,0.5,0.5])
hold on
plot(t2(:,1),t2(:,2),'k*',...
'LineWidth',2,...
'MarkerSize',10,...
'MarkerEdgeColor','g',...
'MarkerFaceColor',[0.5,0.5,0.5])
set(gca,'LineWidth',2);
xlabel('特征1','fontsize',12)
ylabel('特征2','fontsize',12)
title('k-means分类图','fontsize',12)
一维数组聚类
x = [0 ;1 ;3 ;7 ;8 ;9]
z = zeros(2,1)
z1 = zeros(2,1)%设置两个聚类中心
z = x(1:2,1)
while 1%1是判断表达式,1显示永远为真,即永远循环,所以循环体中必须存在break
count = zeros(2,1);
allsum = zeros(2,1);
for i = 1:6
temp1 = sqrt(z(1,1)-x(i,1).^2);%sqrt返还数组每一个元素的平方根,这里是计算x每一个坐标点与第一个坐标点的距离
temp2 = sqrt(z(2,1)-x(i,1).^2);%计算x每一个坐标点与第二个坐标点的距离
if(temp1<temp2)%x中与第一个接近的坐标点计数、求和
count(1) = count(1)+1;
allsum(1,1) = allsum(1,1)+x(i,1);
t(i,1) = x(i,1)
%x中与第一个接近的坐标点计数、求和
else
(temp2<temp1)
count(2) = count(2)+1;
allsum(2,1) = allsum(2,1)+x(i,1);
t(i,2) = x(i,1)
end
end
z1(1,1) = allsum(1,1)/count(1);%与第一个接近的坐标点的横坐标求平均数
z1(2,1) = allsum(2,1)/count(2);%与第二个接近的坐标点的横坐标求平均数
if(z == z1)
break
else
z = z1
end
end
t1 = t(1:count(1),1)%储存类别1的分类结果
t2 = t(count(1)+1:6,2)%储存类别2的分类结果
调用函数kmeans(),及可视化
x = [0 1;1 0;3 2;7 7;8 7;9 7]
k = kmeans(x,3)%x为待聚类数组,3为自定义聚类中心数
%可视化
num1 = length(find(k==1))
num2 = length(find(k==2))
num3 = length(find(k==3))
t1 = x(1:3,:)
t2 = x(4:5,:)
t3 = x(6,:)
plot(t1(:,1),t1(:,2),'k*',...
'LineWidth',2,...
'MarkerSize',10,...
'MarkerEdgeColor','k',...
'MarkerFaceColor',[0.5,0.5,0.5])
hold on
plot(t2(:,1),t2(:,2),'k*',...
'LineWidth',2,...
'MarkerSize',10,...
'MarkerEdgeColor','g',...
'MarkerFaceColor',[0.5,0.5,0.5])
hold on
plot(t3(:,1),t3(:,2),'k*',...
'LineWidth',2,...
'MarkerSize',10,...
'MarkerEdgeColor','y',...
'MarkerFaceColor',[0.5,0.5,0.5])
set(gca,'LineWidth',2);
xlabel('特征1','fontsize',12)
ylabel('特征2','fontsize',12)
title('k-means分类图','fontsize',12)
绘制kmeans聚类结果相关程度图
x = [0 1;1 0;3 2;7 7;8 7;9 7]
d = pdist(x)%计算任意两行数据之间的距离
dd = squareform(d)%返还距离矩阵
figure
imagesc(dd)%将矩阵中元素按照大小值转成不同颜色
set(gca,'LineWidth',2);
xlabel('数据点','fontsize',12)
ylabel('数据点','fontsize',12)
title('k-means聚类结果相关程度图','fontsize',12)
ylabel(colorbar,['距离矩阵'])
axis square