您的位置:首页 > 其它

[置顶] 【分类器】常用的聚类算法-K-means

2016-06-24 15:28 204 查看

K-means算法

是硬聚类算法,是典型的基于原型的目标函数聚类方法的代表,它是数据点到原型的某种距离作为优化的目标函数,利用函数求极值的方法得到迭代运算的调整规则。K-means算法以欧式距离作为相似度测度,它是求对应某一初始聚类中心向量V最优分类,使得评价指标J最小。算法采用误差平方和准则函数作为聚类准则函数。

该算法是典型的基于聚类的聚类算法,采用距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度就越大。该算法认为簇是由距离考级的对象组成,因此得到紧凑并且独立的簇作为最终的目标。



算法过程:

(1)从N个文档随机K个文档作为质心

(2)对剩余的每个文档测量其到每个质心的距离,并把它归到最近的质心的类

(3)重新计算已经得到的各个类的质心

(4)迭代2-3步直到新的质心与原质心相等或者小于指定阈值偏差,算法结束

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);

%显示数据
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;
hold on;
for i=1:m
if re(i,4)==1
plot3(re(i,1),re(i,2),re(i,3),'ro');
elseif re(i,4)==2
plot3(re(i,1),re(i,2),re(i,3),'go');
else
plot3(re(i,1),re(i,2),re(i,3),'bo');
end
end
grid on;
plot(u(:,1),u(:,2),'kx','MarkerSize',14,'LineWidth',4)
grid on


KMean.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
[~, 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
[~, index]=min(tmp);
re=[re;data(i,:) index];
end

end


算法验证



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: