本算法已经整理成文档如下,有需要的朋友可以点击进行下载
序号 | 文档(点击下载) |
---|---|
本项目文档 | 【老生谈算法】模糊K-均值算法及其matlab实现.doc |
模糊K-均值算法由K-均值算法派生而来。K-均值算法在聚类过程中,每次得到的结果虽然不一定是预期的结果,但类别之间的边界是明确的,聚类中心根据各类当前具有的样本进行修改。模糊K-均值算法在聚类过程中,每次得到的类别边界仍是模糊的,每类聚类中心的修改都需要用到所有样本,此外聚类准则也体现了模糊性。
模糊K-均值算法聚类的结果仍是模糊集合,但是如果实际问题希望有一个明确的界限,也可以对结果进行去模糊化,通过一定的规则将模糊聚类转化为确定性分类。
模糊K-均值算法基本思想是首先设定一些类及每个样本对各类的隶属度; 然后通过迭代,不断调整隶属度至收敛。收敛条件是隶属度的变化量小于规定的阈值。具体步骤如下:
(1) 确定模式类数K,,N为样本个数。
(2) 根据先验知识确定样本从属于各类的隶属度 ,建立初始隶属度矩阵,其中i为类别编号、矩阵的行号,j为样本编号、矩阵的列号。表示第个元素对第个类的隶属度。对隶属度矩阵的第列而言,它表示第个元素分别对各模式类的隶属度,因此矩阵的每列元素之和为1。
式中,参数,是一个控制聚类结果模糊程度的参数。可以看出各聚类中心的计算必须用到全部的N个样本,这是与一般(非模糊)K-均值算法的区别之一。在一般(非模糊)K-均值算法中,某一类的聚类中心仅由该类样本决定,不涉及其他类。
式中,d是第L次迭代完成时,第j个样本到第i类聚类中心的距离。为避免分母为零,特别的
当算法收敛时,就得到了各类的聚类中心以及表示个样本对各类隶属程度的隶属度矩阵,模糊聚类到此结束。这时,准则函数
达到最小。
(6) 根据隶属度矩阵U(L+1)进行聚类,按照隶属原则进行划分,即
若
则
类。
例 设有4个二维样本,分别是
去参数,利用模糊K-均值算法把它们聚为两类。
解:(1)根据要求N=4,K=2。
(2)根据先验知识确定初始隶属度矩阵
Matlab代码实现如下:
function y=fuzzy_Kmeans(X,k,m,U,e)
k=2; %自定义k个类中心数
X=[0 0;0 1;3 1;3 2];%样本
U=[0.9 0.8 0.7 0.1;0.1 0.2 0.3 0.9]; %隶属度初始值
% load fisheriris;X=meas;[M,N]=size(X);U=1/k*ones(k,M);U(1,1)=U(1,1)-0.1;U(k,1)=U(k,1)+0.1;%Iris测试数据集,目的是让U的值不全为1/k
%%%%%%%%%%%%初始化
m=2; %控制模糊程度的参数
e=0.0001; %达到收敛时最小误差
UL=membership(U,X,m); %求隶属度
err=abs(UL-U); %误差
while(max(err(1,:))>e) %收敛条件没达到要求,则继续迭代
temp=UL; %保存先前的隶属度
UL=membership(UL,X,m); %更新隶属度
err=abs(UL-temp); %更新误差
end
UL %输出最终的隶属度矩阵
%%%%%%%%%%%%%通过最终所获得的隶属度矩阵,判断样本所属类别
class=cell(k,1); %初始化类样本class
for i=1:size(X,1);
[MAX,index]=max(UL(:,i));
class{index}=cat(1,class{index},i);
end
celldisp(class);%显示Kmeans聚类结果
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%子函数部分
function y=membership(U0,X,m)
%U0初始隶属度矩阵,X为需聚类样本,m为控制聚类结果的模糊程度,y为返回的新的隶属度
classNum=size(U0,1); %求出类别数
for i=1:classNum
U0(i,:)=U0(i,:).^m; %隶属度各值平方
end
Z=zeros(classNum,size(X,2));%聚类中心初始化
for i=1:classNum
for j=1:size(X,1)
Z(i,:)=Z(i,:)+U0(i,j)*X(j,:);
end
Z(i,:)=Z(i,:)/sum(U0(i,:)); %计算聚类中心
end
for i=1:size(X,1)
for j=1:size(Z,1)
d(i,j)=dist(X(i,:),Z(j,:)')^(2/(m-1));%求距离
end
end
[m,n]=size(d);
u=zeros(m,n);%新的隶属度初始化
for i=1:m
for j=1:n
for k=1:n
u(i,j)=u(i,j)+d(i,j)/d(i,k);
end
u(i,j)=1/u(i,j); %由隶属度更新公式
end
end
y=u';