聚類——GAKFCM的matlab程式 聚類——GAKFCM
阿新 • • 發佈:2018-12-09
聚類——GAKFCM的matlab程式
作者:凱魯嘎吉 - 部落格園 http://www.cnblogs.com/kailugaji/
在聚類——GAKFCM文章中已介紹了GAKFCM演算法的理論知識,現在用matlab進行實現,下面這個例子是用GA初始化聚類中心。
1.matlab程式
GAKFCM_main.m
function [ave_acc_GAKFCM,max_acc_GAKFCM,min_acc_GAKFCM,ave_iter_GA,ave_iter_KFCM,ave_run_time]=GAKFCM_main(X,real_label,K) %輸入K:聚的類,max_iter是最大迭代次數,T:遺傳演算法最大迭代次數,n:種群個數, X:沒有進行歸一化 %輸出ave_acc_KFCM:迭代max_iter次之後的平均準確度,iter:實際KFCM迭代次數 t0=cputime; max_iter=20; s=0; s_1=0; s_2=0; iter_GA=zeros(max_iter,1); iter_KFCM=zeros(max_iter,1); accuracy=zeros(max_iter,1); for i=1:max_iter [label, iter_KFCM(i), ~,iter_GA(i)]=My_GAKFCM(X,K); accuracy(i)=succeed(real_label,K,label); s=s+accuracy(i); s_1=s_1+iter_GA(i); s_2=s_2+iter_KFCM(i); fprintf('第 %2d 次,GA的迭代次數為:%2d,KFCM的迭代次數為:%2d,準確度為:%.8f\t\n', i, iter_GA(i), iter_KFCM(i), accuracy(i)); end ave_acc_GAKFCM=s/max_iter; max_acc_GAKFCM=max(accuracy); min_acc_GAKFCM=min(accuracy); ave_iter_GA=s_1/max_iter; ave_iter_KFCM=s_2/max_iter; run_time=cputime-t0; ave_run_time=run_time/max_iter;
My_GAKFCM.m
function [label, iter_KFCM, para_miu,iter_GA]=My_GAKFCM(X,K) %用GA初始聚類中心 %輸入K:聚類數,X:資料集 %輸出:label:聚的類, para_miu:模糊聚類中心μ,iter_KFCM:KFCM迭代次數 format long eps=1e-4; %定義迭代終止條件的eps alpha=2; %模糊加權指數,[1,+無窮) T=100; %最大迭代次數 %sigma_2=2^(-4); %高斯核函式的引數2*sigma^2 sigma_2=150; %高斯核函式的引數sigma^2 [X_num,X_dim]=size(X); fitness=zeros(X_num,1); %目標函式 responsivity=zeros(X_num,K); %隸屬函式 R_up=zeros(X_num,K); %隸屬函式的分子部分 count=zeros(X_num,1); %統計distant中每一行為0的個數 %隨機初始化K個聚類中心 % [X_num,~]=size(X); % rand_array=randperm(X_num); %產生1~X_num之間整數的隨機排列 % para_miu=X(rand_array(1:K),:); %隨機排列取前K個數,在X矩陣中取這K行作為初始聚類中心 %用GA初始聚類中心 [para_miu,iter_GA]=my_genetic(X,K); % KFCM演算法 for t=1:T %歐氏距離,計算(X-para_miu)^2=X^2+para_miu^2-2*para_miu*X',矩陣大小為X_num*K distant=(sum(X.*X,2))*ones(1,K)+ones(X_num,1)*(sum(para_miu.*para_miu,2))'-2*X*para_miu'; %高斯核函式,X_num*K的矩陣 kernel_fun=exp((-distant)./(sigma_2)); %更新隸屬度矩陣X_num*K for i=1:X_num count(i)=sum(kernel_fun(i,:)==1); if count(i)>0 for k=1:K if kernel_fun(i,k)==1 responsivity(i,k)=1./count(i); else responsivity(i,k)=0; end end else R_up(i,:)=(1-kernel_fun(i,:)).^(-1/(alpha-1)); %隸屬度矩陣的分子部分 responsivity(i,:)= R_up(i,:)./sum( R_up(i,:),2); end end %目標函式值 fitness(t)=2*sum(sum((ones(X_num,K)-kernel_fun).*(responsivity.^(alpha)))); %更新聚類中心K*X_dim miu_up=(kernel_fun.*(responsivity.^(alpha)))'*X; %μ的分子部分 para_miu=miu_up./(sum(kernel_fun.*(responsivity.^(alpha)))'*ones(1,X_dim)); if t>1 if abs(fitness(t)-fitness(t-1))<eps break; end end end iter_KFCM=t; %實際迭代次數 [~,label]=max(responsivity,[],2);
succeed.m
function accuracy=succeed(real_label,K,id) %輸入K:聚的類,id:訓練後的聚類結果,N*1的矩陣 N=size(id,1); %樣本個數 p=perms(1:K); %全排列矩陣 p_col=size(p,1); %全排列的行數 new_label=zeros(N,p_col); %聚類結果的所有可能取值,N*p_col num=zeros(1,p_col); %與真實聚類結果一樣的個數 %將訓練結果全排列為N*p_col的矩陣,每一列為一種可能性 for i=1:N for j=1:p_col for k=1:K if id(i)==k new_label(i,j)=p(j,k); %iris資料庫,1 2 3 end end end end %與真實結果比對,計算精確度 for j=1:p_col for i=1:N if new_label(i,j)==real_label(i) num(j)=num(j)+1; end end end accuracy=max(num)/N;
my_genetic.m
function [para_miu_new,iter]=my_genetic(data,K) %data:資料集,K:聚類數 pc_0=0.6; %初始交叉概率 pm_0=0.1; %初始變異概率 eps=1e-4; %定義迭代終止條件的eps n=50; %n:n個初始個體,每個個體為K*X_dim T=100; %T:最大迭代次數 pc=zeros(T,1); %交叉概率 pm=zeros(T,1); %變異概率 fitness=zeros(n,1); ave_fitness=zeros(T,1); %實數編碼 %對data做最大-最小歸一化處理 [data_num,~]=size(data); X=(data-ones(data_num,1)*min(data))./(ones(data_num,1)*(max(data)-min(data))); %產生初始種群 population=init_population(X,K,n); for t=1:T %更新適應度 fitness=fit_vector(X,K,population,n); %非線性排序選擇 population=sort_select(population,fitness); %計算交叉概率,進行交叉操作 pc(t)=pc_0*(1-(t-1)/T); population=crossover(population,pc(t)); %計算變異概率,進行變異操作 pm(t)=pm_0*(1-(t-1)/T); population=mutation(population,pm(t)); ave_fitness(t)=sum(fitness)/n; if t>1 if abs( ave_fitness(t)- ave_fitness(t-1))<eps break; end end end iter=t; %實際迭代次數 %輸出適應度最大的個體 [~,index_final]=max(fitness); para_miu=population(:,:,index_final); %解碼para_miu para_miu_new=para_miu.*(ones(K,1)*(max(data)-min(data)))+ones(K,1)*min(data);
init_population.m
function population=init_population(X,K,n) %data:資料集,K:聚類數,n:n個初始個體,每個個體為K*X_dim,new_index為排序後的個體序號 rand_num=3; %rand_num:隨機取rand_num個樣本作為一類 [X_num,X_dim]=size(X); individual=zeros(K,X_dim); %individual為聚類中心矩陣,K*X_dim的矩陣 population=zeros(K,X_dim,n); for i=1:n %隨機初始化K個聚類中心 for k=1:K rand_array=randperm(X_num); %產生1~X_num之間整數的隨機排列 temp=X(rand_array(1:rand_num),:); individual(k,:)=sum(temp)./rand_num; %individual(k)為1*X_dim的矩陣,為一類的聚類中心,對rand_num取平均 end population(:,:,i)=individual; end
fit_vector.m
function fitness=fit_vector(X,K,population,n) fitness=zeros(n,1); for i=1:n %計算個體適應度 fitness(i)=fitness_value(X,K,population(:,:,i)); %fitness為GAKFCM適應度函式 n*1的矩陣 end
fitness_value.m
function fitness=fitness_value(X,K,para_miu) %X是資料,para_miu為每一個individual矩陣,K*X_dim,fitness為GAKFCM適應度函式 %sigma_2=2^(-4); %高斯核函式的引數2*sigma^2 sigma_2=150; %高斯核函式的引數sigma^2 alpha=2; %模糊加權指數,[1,+無窮) [X_num,~]=size(X); responsivity=zeros(X_num,K); %隸屬函式 R_up=zeros(X_num,K); count=zeros(X_num,1); %統計distant中每一行為0的個數 %歐氏距離,計算(X-para_miu)^2=X^2+para_miu^2-2*para_miu*X',矩陣大小為X_num*K distant=(sum(X.*X,2))*ones(1,K)+ones(X_num,1)*(sum(para_miu.*para_miu,2))'-2*X*para_miu'; %高斯核函式,X_num*K的矩陣 kernel_fun=exp((-distant)./(sigma_2)); %更新隸屬度矩陣X_num*K for i=1:X_num count(i)=sum(kernel_fun(i,:)==1); if count(i)>0 for k=1:K if kernel_fun(i,k)==1 responsivity(i,k)=1./count(i); else responsivity(i,k)=0; end end else R_up(i,:)=(1-kernel_fun(i,:)).^(-1/(alpha-1)); %隸屬度矩陣的分子部分 responsivity(i,:)= R_up(i,:)./sum( R_up(i,:),2); end end %目標函式值 fitness_KFCM=2*sum(sum((ones(X_num,K)-kernel_fun).*(responsivity.^(alpha)))); %KFCM的目標函式 fitness=1/(1+fitness_KFCM); %fitness為GAKFCM適應度函式
sort_select.m
function population=sort_select(population,fitness) %q屬於(0,1)為引數, i表示排序序號,本文取q=0.1 q=0.1; [n,~]=size(fitness); new_index=zeros(n,1); %選擇之後最優個體的序號 fun=zeros(n,1); %非線性排序選擇概率分佈函式 add_pro=zeros(n,1); %累積概率 [~,index_fit]=sort(fitness,'descend'); %將fitness按降序排序 %計算每個個體選擇的概率 for i=1:n fun(i)=q*(1-q)^(i-1); end new_fun=fun/sum(fun); %求累積概率 for i=1:n add_pro(i)=sum(new_fun(1:i)); end %選擇最優個體,求其在X中的順序 for t=1:n rand_pro=rand(); %[0,1]之間的隨機數 if rand_pro<=add_pro(1) new_index(t)=index_fit(1); end for i=2:n if (rand_pro>add_pro(i-1))&&(rand_pro<=add_pro(i)) new_index(t)=index_fit(i); end end population(:,:,t)=population(:,:,new_index(t)); end
crossover.m
function population=crossover(population,pc) %個體之間進行交叉操作,交換兩行 [K,~,n]=size(population); num=floor(n/2); %對n/2向下取整 for i=1:num rand_c=rand(); %[0,1]之間的隨機數 rand_pro=unidrnd(K); %[1,K]之間的隨機整數 %交換兩個矩陣中的第rand_pro行 if pc>rand_c t=population(rand_pro,:,2*i-1); population(rand_pro,:,2*i-1)=population(rand_pro,:,2*i); population(rand_pro,:,2*i)=t; end end
mutation.m
function population=mutation(population,pm) %個體進行變異操作 [K,X_dim,n]=size(population); for i=1:n rand_m=rand(); %[0,1]之間的隨機數 rand_pro=unidrnd(K); %[1,K]之間的隨機整數 if pm>rand_m %對第rand_pro行進行變異操作 population(rand_pro,:,i)=rand(1,X_dim); end end
2.在UCI資料庫的iris上的執行結果
>> data_load=dlmread('E:\My matlab\database\iris.data');data=data_load(:,1:4);real_label=data_load(:,5); >> [ave_acc_GAKFCM,max_acc_GAKFCM,min_acc_GAKFCM,ave_iter_GA,ave_iter_KFCM,ave_run_time]=GAKFCM_main(data,real_label,3) 第 1 次,GA的迭代次數為:10,KFCM的迭代次數為: 6,準確度為:0.89333333 第 2 次,GA的迭代次數為: 3,KFCM的迭代次數為:13,準確度為:0.89333333 第 3 次,GA的迭代次數為:39,KFCM的迭代次數為: 8,準確度為:0.89333333 第 4 次,GA的迭代次數為:66,KFCM的迭代次數為:10,準確度為:0.89333333 第 5 次,GA的迭代次數為:18,KFCM的迭代次數為: 8,準確度為:0.89333333 第 6 次,GA的迭代次數為:26,KFCM的迭代次數為: 6,準確度為:0.89333333 第 7 次,GA的迭代次數為:93,KFCM的迭代次數為: 7,準確度為:0.89333333 第 8 次,GA的迭代次數為:70,KFCM的迭代次數為: 5,準確度為:0.89333333 第 9 次,GA的迭代次數為:11,KFCM的迭代次數為: 8,準確度為:0.89333333 第 10 次,GA的迭代次數為: 9,KFCM的迭代次數為: 9,準確度為:0.89333333 第 11 次,GA的迭代次數為:80,KFCM的迭代次數為: 7,準確度為:0.89333333 第 12 次,GA的迭代次數為:39,KFCM的迭代次數為: 7,準確度為:0.89333333 第 13 次,GA的迭代次數為:12,KFCM的迭代次數為: 6,準確度為:0.89333333 第 14 次,GA的迭代次數為:22,KFCM的迭代次數為: 6,準確度為:0.89333333 第 15 次,GA的迭代次數為: 7,KFCM的迭代次數為: 8,準確度為:0.89333333 第 16 次,GA的迭代次數為:13,KFCM的迭代次數為: 8,準確度為:0.89333333 第 17 次,GA的迭代次數為:19,KFCM的迭代次數為:15,準確度為:0.89333333 第 18 次,GA的迭代次數為:22,KFCM的迭代次數為:14,準確度為:0.89333333 第 19 次,GA的迭代次數為:30,KFCM的迭代次數為: 9,準確度為:0.89333333 第 20 次,GA的迭代次數為:13,KFCM的迭代次數為: 7,準確度為:0.89333333 ave_acc_GAKFCM = 0.893333333333333 max_acc_GAKFCM = 0.893333333333333 min_acc_GAKFCM = 0.893333333333333 ave_iter_GA = 30.100000000000001 ave_iter_KFCM = 8.350000000000000 ave_run_time = 2.457812500000000
遺傳演算法中的具體實現細節有可能有誤,望指正。