function [c,u,dist]=self_kfcm(data,k,iter,err,w) %c 返回各类中心 %u 返回隶属度矩阵 %dist 返回各类内距离之和 %data 数据集 %n 希望聚成的类数 %iter 迭代数 %err 最小误差 %w 高斯核函数的宽度 %% %初始化 [m,n]=size(data); c=zeros(k,n); u=zeros(m,k); dist=[]; %% %确定初始类中心 for i=1:k c(i,:)=data(i,:); end %% k_dist=zeros(m,k); for t=1:iter disp(c); %各点与各类中心的距离(一部分) for i=1:m for j=1:k k_dist(i,j)=exp((-1/(w^2))*((data(i,:)*data(i,:)'+c(j,:)*c(j,:)'-2*data(i,:)*c(j,:)'))); end end % disp(k_dist); %disp('**************************************************') %隶属度计算 for j=1:m for l=1:k u(j,l)=(1-k_dist(j,l))^(-1); end end % disp('一部分u') % disp(u); a=0; u_copy=u; for i=1:m for l=1:k a=sum(u_copy(i,:)); u(i,l)=(u(i,l)/a); end end u(isnan(u))=1; % disp(u); %距离计算 dist_k=zeros(1,k); for l=1:k dist_k(1,l)=2*((u(:,l).^2)'*(1-k_dist(:,l))); end dist=[dist,sum(dist_k)]; if length(dist)>=2 err1=abs(dist(length(dist)-1)-dist(length(dist))); if err1<=err disp('达到误差要求'); disp('当前迭代次数为:'); disp(t) break; end end %重新确定类中心 pre_c=c; ans=zeros(m,n); for i=1:k for j=1:m ans(j,:)=u(j,i)^2*k_dist(j,i)*data(j,:); end c(i,:)=sum(ans)/(sum((u(:,i).^2)'*(k_dist(:,i)))); end % disp(ans); if pre_c==c disp('类中心不变'); disp('当前迭代次数'); disp(t) break; end % disp(c) % disp('~~~~~~~~~~~~~~~~~~~~~~~~~~') if t==iter disp('迭代次数用尽') end end
这是我自己编的,也不知道对不对,反正跑出来了结果,但是总感觉怪怪的,下面是自己跑出的结果对比图(iris数据集上):
如果不对的话,有什么逻辑错误或者代码错误,欢迎各位在底下留言批评改正。