1. 程式人生 > >聚類——GAKFCM的matlab程式 聚類——GAKFCM

聚類——GAKFCM的matlab程式 聚類——GAKFCM

聚類——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

遺傳演算法中的具體實現細節有可能有誤,望指正。