k均值算法原理详细讲解以及matlab代码实现

有研究生物电信号处理和机器学习的欢迎加我qq429500506共同交流学习进步。

最近更新文章的频率太低了,主要原因是不想为了发文章而发文章,想潜心研究,写好文章,顺便想说一句开源万岁,最近一个月虽然一直在研究脑电信号特征提取和分类的算法,虽然待在实验室的时间不短,但是效率很低,归根结底还是因为自己没有明确的计划,紧迫感不足,每研究透一点点就想休息一下犒劳一下自己,再加上出国留学的可能性比较大,陪女朋友的时间也更长了一些。总之这一个月过得不怎么样。今天是周一,从今天开始,明确目标,紧迫感要强一些。合理的规划时间,争取最后学业爱情双丰收。顺便分享一下基础得要命的算法K均值算法。

先说下原理:原理很简单,就是随机初始化几个中心,你的数据集要分几个类就有几个中心,然后通过不断的计算数据离设置的中心的欧式距离也就是初中学的两点之间直线的距离公式。然后设定迭代次数,不断的更新数据的中心,直到数据集离中心的距离为零或者达到设定的迭代次数为止。

附上matlab代码(网上有很多但是可能解释没有那么详细)

%%%K-means

clear all
clc

%% 构造随机数据 
mu1=[0 0 0];  
S1=[0.23 0 0;0 0.87 0;0 0 0.56]; 
data1=mvnrnd(mu1,S1,100);   %产生高斯分布数据

%%第二类数据
mu2=[1.25 1.25 1.25];
S2=[0.23 0 0;0 0.87 0;0 0 0.56];
data2=mvnrnd(mu2,S2,100);

%第三个类数据
mu3=[-1.25 1.25 -1.25];
S3=[0.23 0 0;0 0.87 0;0 0 0.56];
data3=mvnrnd(mu3,S3,100);

mu4=[1.5 1.5 1.5];
S4=[0.23 0 0;0 0.87 0;0 0 0.56];
data4 =mvnrnd(mu4,S4,100);

%显示数据
figure;
plot3(data1(:,1),data1(:,2),data1(:,3),'+');
title('原始数据');
hold on
plot3(data2(:,1),data2(:,2),data2(:,3),'r+');
plot3(data3(:,1),data3(:,2),data3(:,3),'g+');
plot3(data4(:,1),data4(:,2),data3(:,3),'y+');
grid on;


data=[data1;data2;data3;data4];   
K = 4;
max_iter = 300;%%迭代次数
min_impro = 0.1;%%%%最小步长
display = 1;%%%判定条件
[row,col]=size(data)%%求数据的行和列
center = zeros(K,col)
U = zeros(K,col);
%% 初始化聚类中心
mi = zeros(col,1)
ma = zeros(col,1);
for i = 1:col
    mi(i,1) = min(data(:,i));%%求构造的数据每一列的最小值
    ma(i,1) = max(data(:,i));%%求构造的数据每一列的最大值
    center(:,i) = ma(i,1) - (ma(i,1) - mi(i,1)) * rand(K,1);%%随机初始化聚类中心
end

%% 开始迭代
for o = 1:max_iter
    %% 计算欧氏距离,用norm函数
    for i = 1:K
        dist{i} = [];
        for j = 1:row
            dist{i} = [dist{i};data(j,:) - center(i,:)];%%dist为元胞数组计算数据离中心的几何距离
        end
    end
    
    minDis = zeros(row,K);
    for i = 1:row
        tem = [];
        for j = 1:K
            tem = [tem norm(dist{j}(i,:))];
        end%%norm函数为矩阵范数,求矩阵每一列模的最大值
        [nmin,index] = min(tem);
        minDis(i,index) = norm(dist{index}(i,:));
    end
    
    
    %% 更新聚类中心
     for i = 1:K
        for j = 1:col
            U(i,j) = sum(minDis(:,i).*data(:,j)) / sum(minDis(:,i));
        end
     end
     
     %% 判定
      if display
   end
   if o >1,
       if max(abs(U - center)) < min_impro;
           break;
       else
           center = U;
       end
   end
end

 %% 返回所属的类别
 class = [];
 for i = 1:row
     dist = [];
     for j = 1:K
         dist = [dist norm(data(i,:) - U(j,:))];
     end
     [nmin,index] = min(dist);
     class = [class;data(i,:) index];
 end
  
 %% 显示最后结果
[m,n] = size(class);
figure;
title('聚类结果');
hold on;
for i=1:row 
    if class(i,4)==1   
         plot3(class(i,1),class(i,2),class(i,3),'ro'); 
    elseif class(i,4)==2
         plot3(class(i,1),class(i,2),class(i,3),'go'); 
    elseif class(i,4) == 3
         plot3(class(i,1),class(i,2),class(i,3),'bo'); 
    else
        plot3(class(i,1),class(i,2),class(i,3),'yo'); 
    end
end
grid on;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值