FCM代碼
function[center,U,obj_fun]=FCMCluster(data,n,options)%採用模糊C均值將資料集data分為n類%用法% 1 [center,U,obj_fcn]=FCMCluster(data,n,options);% 2 [center,U,obj_fcn]=FCMCluster(data,n);%輸入 % data n*m矩陣,n個樣本數,每個樣本的維度為m% n 類別數% options 4*1 矩陣% options(1):隸屬度矩陣U的加權指數% options(2):最大迭代次數% options(3):隸屬度最小變化量,迭代終止條件% options(4):每次迭代是否輸出資訊標誌%輸出% center 聚類中心% U 隸屬度矩陣% obj_fun 目標函數值if nargin~=2 && nargin~=3 error('Too many or too few input arguments');end data_n=size(data,1);in_n=size(data,2);%預設參數default_options=[2;100;1e-5;1];%參數配置 %如果只輸入前兩個參數,選用預設的參數;如果參數個數小於4,其他選用預設參數 if nargin==2 options=default_options; else if length(options)<4 tmp=default_options; tmp(1:length(options))=options; options=tmp; end nan_index=find(isnan(options)==1); options(nan_index)=default_options(nan_index); if options(1)<=1 error('The exponent should be greater than 1!'); end end %將options 中的分量分別賦值給四個變數 expo=options(1); max_iter=options(2); min_impro=options(3); display=options(4); obj_fun=zeros(max_iter,1); %初始化模糊分配矩陣 U=initfcm(n,data_n); %主程式 for i=1:max_iter [U,center,obj_fun(i)]=stepfcm(data,U,n,expo); if display fprintf('FCM:Iteration count=%d,obj_fun=%f\n',i,obj_fun(i)); end %終止條件判別 if i>1 if abs(obj_fun(i)-obj_fun(i-1))<min_impro break; end end end iter_n=i; obj_fun(iter_n+1:max_iter)=[];% end%%子函數 模糊矩陣初始化 function U= initfcm(n,data_n) U=rand(n,data_n); col_sum=sum(U); U=U./col_sum(ones(n,1),:); end%%子函數 逐步聚類 function [U_new,center,obj_fun]=stepfcm(data,U,n,expo) mf=U.^expo; center=mf*data./((ones(size(data,2),1)*sum(mf'))'); dist=distfcm(center,data); obj_fun=sum(sum((dist.^2).*mf)); tmp=dist.^(-2/(expo-1)); U_new=tmp./(ones(n,1)*sum(tmp)); end%%子函數 計算距離 function out=distfcm(center,data) out=zeros(size(center,1),size(data,1)); for k=1:size(center,1) out(k,:)=sqrt(sum(((data-ones(size(data,1),1)*center(k,:)).^2)',1)); end end演算法測試
data=rand(100,2);
[center,U,obj_fcn] = FCMCluster(data,2);
plot(data(:,1),data(:,2),’o’);
hold on;
index1=find(U(1,:)==max(U));%找出劃分為第一類的資料索引
index2=find(U(2,:)==max(U));%找出劃分為第二類的資料索引
plot(data(index1,1),data(index1,2),’g*’);
hold on;
plot(data(index2,1),data(index2,2),’r*’);
hold on;
plot([center([1 2],1)],[center([1 2],2)],’*’,’color’,’k’);
實驗結果展示:
原資料分布
聚類結果