K-means聚类 matlab简单实现及解析

K-means基本思想:

优先设置分为K类,初始随机分配K个中心。

计算每个点到每个中心的距离,分配到离自己最近的那个中心(贴上标签)。

分配完后计算每一类的均值,并重新分配中心。

重复上两步,直到中心点不再更改。

以下代码参考

https://blog.csdn.net/Justin_bibo/article/details/83904357

稍作修改并加以注释:

function kmeanstest()
clear all;
clc;
%聚类个数为3
k = 3;

%初始化数据
x = 0.8 + sqrt(0.01) * randn(200,2);% randn(m.n)返回一个m*n的随即向矩阵
y = 0.2 + sqrt(0.02) * randn(200,2);
z = 0.5 + sqrt(0.02) * randn(200,2);
%plot(x(:,1),x(:,2),'+r',y(:,1),y(:,2),'+b',z(:,1),z(:,2),'+g');%取矩阵一二列并画出
%axis([0,1,0,1]);xlabel('red');ylabel('acc');title('');%坐标轴的设置

D = [x;y;z];%数据集
%plot (D(:,1),D(:,2),'+r');%查看初始数据集分布情况(画图)

u = randperm(size(D,1),k);%随机选取k个初始中心点
u = D(u,:);%完整数据
c = zeros(size(D,1),1);%存放聚类标签
distance = zeros(k,1);%存放数据与中心点的距离

while 1
    mark = 0;%标记
    for i=1:size(D,1)%D所有数据
        for j=1:k%k类
            distance(j) = sqrt((D(i,1)-u(j,1))^2 + (D(i,2)-u(j,2))^2);%到中心点的距离
        end
        [~,m] = min(distance);%最小赋给m
        c(i) = m; %数据贴上标签
    end
    u1 = zeros(k,2);%新的中心点
    for i=1:k
        u1(i,1) = sum(D(find(c(:) == i),1))/size(find(c(:)==i),1);%计算新的中心点(i标签的第一列数据之和除以个数)
        u1(i,2) = sum(D(find(c(:) == i),2))/size(find(c(:)==i),1);%计算新的中心点
        if u(i,1) ~= u1(i,1) || u(i,2) ~= u1(i,2)%若有更新,即与上一次值不一样
            mark = 1;%标记更新
            u(i,1) = u1(i,1);%更新
            u(i,2) = u1(i,2);
        end
    end
    if mark == 0%若没有更新,跳出循环
        break;
    end
end
x = D(find(c(:) == 1),:);
y = D(find(c(:) == 2),:);
z = D(find(c(:) == 3),:);

 plot(x(:,1),x(:,2),'+y',y(:,1),y(:,2),'+b',z(:,1),z(:,2),'+g',u(1,1),u(1,2),'*r',u(2,1),u(2,2),'*r',u(3,1),u(3,2),'*r');
axis([0,1,0,1]);xlabel('red');ylabel('acc');title('');
end

结果:

猜你喜欢

转载自blog.csdn.net/mxxxkuku/article/details/102491252