matlab练习程序(k-means聚类) (转载,原文代码有点问题,这是修改版)
https://www.cnblogs.com/tiandsp/archive/2013/04/24/3040883.html
来自这篇博客
来个matlab的trick
matlab里也有现成的kmeans函数


来个matlab的trick
三维数组大小为[1004,417,200]
想将200这一维上的数据求平均然后放入数组B
B=mean(A,3);
这么写
https://www.cnblogs.com/lihanlin/p/12582019.html KMeans优化思路
https://www.cnblogs.com/hxsyl/p/4054583.html Matlab实现K-Means聚类算法

不管三七二十一,这里的例子是
300个三维空间点,进行3聚类
数据产生的很有技巧,很有人为性,很有规律罢了
KMeans是无监督学习
算法流程如下

main.m
clear all;
close all;
clc;
%第一类数据
mu1=[0 0 0]; %均值
S1=[0.3 0 0;0 0.35 0;0 0 0.3]; %协方差
data1=mvnrnd(mu1,S1,100); %产生高斯分布数据
%%第二类数据
mu2=[1.25 1.25 1.25];
S2=[0.3 0 0;0 0.35 0;0 0 0.3];
data2=mvnrnd(mu2,S2,100);
%第三个类数据
mu3=[-1.25 1.25 -1.25];
S3=[0.3 0 0;0 0.35 0;0 0 0.3];
data3=mvnrnd(mu3,S3,100);
%显示数据
figure(1);
plot3(data1(:,1),data1(:,2),data1(:,3),'+');
hold on;
plot3(data2(:,1),data2(:,2),data2(:,3),'r+');
plot3(data3(:,1),data3(:,2),data3(:,3),'g+');
grid on;
%三类数据合成一个不带标号的数据类
data=[data1;data2;data3]; %这里的data是不带标号的
%k-means聚类
[u re]=KMeans(data,3); %最后产生带标号的数据,标号在所有数据的最后,意思就是数据再加一维度
[m n]=size(re);
%最后显示聚类后的数据
figure(2);
%hold on;
for i=1:m
if re(i,4)==1
plot3(re(i,1),re(i,2),re(i,3),'ro');
hold on;
elseif re(i,4)==2
plot3(re(i,1),re(i,2),re(i,3),'go');
hold on;
else
plot3(re(i,1),re(i,2),re(i,3),'bo');
hold on;
end
end
plot3(u(1,1),u(1,2),u(1,3),'r*');
plot3(u(2,1),u(2,2),u(2,3),'g*');
plot3(u(3,1),u(3,2),u(3,3),'b*');
grid on;
KMeans.m
%N是数据一共分多少类
%data是输入的不带分类标号的数据
%u是每一类的中心
%re是返回的带分类标号的数据
function [u re]=KMeans(data,N)
[m n]=size(data); %m是数据个数,n是数据维数
ma=zeros(n); %每一维最大的数
mi=zeros(n); %每一维最小的数
u=zeros(N,n); %随机初始化,最终迭代到每一类的中心位置
for i=1:n
ma(i)=max(data(:,i)); %每一维最大的数
mi(i)=min(data(:,i)); %每一维最小的数
for j=1:N
u(j,i)=ma(i)+(mi(i)-ma(i))*rand(); %随机初始化,不过还是在每一维[min max]中初始化好些
end
end
while 1
pre_u=u; %上一次求得的中心位置
for i=1:N
tmp{i}=[]; % 公式一中的x(i)-uj,为公式一实现做准备
for j=1:m
tmp{i}=[tmp{i};data(j,:)-u(i,:)];
end
end
quan=zeros(m,N);
for i=1:m %公式一的实现
c=[];
for j=1:N
c=[c norm(tmp{j}(i,:))];
end
[junk index]=min(c);
quan(i,index)=norm(tmp{index}(i,:));
end
for i=1:N %公式二的实现
for j=1:n
u(i,j)=sum(quan(:,i).*data(:,j))/sum(quan(:,i));
end
end
if norm(pre_u-u)<0.1 %不断迭代直到位置不再变化
break;
end
end
re=[];
for i=1:m
tmp=[];
for j=1:N
tmp=[tmp norm(data(i,:)-u(j,:))];
end
[junk index]=min(tmp);
re=[re;data(i,:) index];
end
end



浙公网安备 33010602011771号