K-means均值聚类 MATLAB

文章详细介绍了K-means聚类算法的工作原理,包括步骤、计算流程以及使用Matlab代码进行实例演示。通过不断迭代更新聚类中心直到收敛,算法将数据分为不同的簇。同时,展示了如何通过可视化展示聚类结果和数据点间的相关性。
摘要由CSDN通过智能技术生成

原理:

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)为初始聚类中心

步骤二:计算各点到聚类中心的距离

52de75dbf9d64a4d9136b37358438360.png

 

步骤三:根据各点到聚类中心的距离将x分为2簇

类别

集合

(0,1)

X1

(1,0)

X2,x3,x4,x5,x6

步骤四:计算每簇x的平均坐标值,生成新的聚类中心

9db4dcd7d29c4720bb1132c841168ed1.png

 

将新生成的聚类中心(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)

cca88510ddfe47309fab99b536dd6324.png

 

对不同分类的簇可视化区分

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)

090014a7b3dc4c6abdbe06331006daa8.png

一维数组聚类

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)

df96bcaf33de4adaab341c1a75f0e4c9.png

 绘制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

c86b898030e64b36b9a0f71f6c03c1bb.png

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江希垣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值