-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding all the required files of ECWSA
- Loading branch information
1 parent
5517b71
commit dd88d66
Showing
12 changed files
with
783 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Functional dependency of the codes {Function <- dependency functions} | ||
|
||
main_ECWSA <- gen_mRMR, knnClassifier, ECWSA | ||
gen_mRMR <- maxRelMinRed | ||
ECWSA <- datacreate, chaotic, encircle, spiral, local_search |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,221 @@ | ||
function []=ECWSA(str,chaos,k) | ||
% Function implementing the entire ECWSA procedure | ||
|
||
fprintf("ECWSA starting......\n\n"); | ||
pause(3); | ||
rng('shuffle'); | ||
global x memory; | ||
global iteration populationSize ; | ||
createDivision(); % function to separate the dataset into folds for crossvalidation | ||
totalPop = populationSize; | ||
[~,featCount]=size(x); | ||
|
||
%% generating initial population | ||
population=datacreate(populationSize,featCount); | ||
p=0.3; % inital chaos value | ||
decrement_ratio=0.8; % death | ||
|
||
%% calculating fitness value of each solution | ||
[fitness, population] = rankPopulation(population); | ||
fprintf("==============Initial population of whales===============\n") | ||
displayPopulation(population) | ||
|
||
%% assiging fittest solution as prey | ||
prey=population(1,:); | ||
preyacc=fitness(1,1); | ||
init_best_acc=preyacc; | ||
init_best_feat=prey; | ||
fprintf('Initial percentage of selected features = %f\n',(sum(prey)*100)/featCount); | ||
fprintf('Initial best accuracy = %f\n',preyacc*100); | ||
|
||
%% for each iteration | ||
tic | ||
|
||
% For the complete psudo code, please refer to Algorithm 2 of the paper | ||
for q=2:iteration+1 | ||
fprintf('\n'); | ||
fprintf('========================================\n'); | ||
fprintf(' Iteration - %d\n',q-1); | ||
fprintf('========================================\n\n'); | ||
|
||
location = strcat('Results/',str,'/'); | ||
folderName = strcat(location,'ECWSA_',int2str(chaos),'_Pop_',int2str(totalPop),'_Iter_',int2str(iteration),'_KNN_',int2str(k)); | ||
|
||
for i=1:populationSize | ||
p=chaotic(p,chaos); | ||
|
||
if p<0.5 | ||
a=2-q*(2/iteration); | ||
r=rand(1,featCount); | ||
C=2*r; | ||
A=calculate_A(a,r,featCount); | ||
|
||
if modulas_A(A,featCount)<1 | ||
% Exploitation using shrinking encircling | ||
fprintf("Whale %d follows exploitation through encircling\n", i); | ||
D=dista(C,population(i,:),prey,featCount); | ||
updatedPopulation(i,:)=encircle(prey,featCount,A,D); % update according to Eqn. 3 | ||
else | ||
% Exploration using shrinking encircling | ||
fprintf("Whale %d follows exploration through encircling\n", i); | ||
sagent=round((populationSize-1)*(rand()))+1; | ||
D=dista(C,population(i,:),population(sagent,:),featCount); | ||
updatedPopulation(i,:)=encircle(population(sagent,:),featCount,A,D); % update according to Eqn. 8 | ||
end | ||
else | ||
% Spiral Motion | ||
fprintf("Whale %d follows spiral motion\n", i); | ||
updatedPopulation(i,:)=spiral(population(i,:),prey,featCount); % using spiral motion (Eqn. 2) to update the position | ||
end | ||
end | ||
|
||
% performing mRMR-based local search | ||
fprintf('\n================local search starts=================\n\n'); | ||
[updatedPopulation]=local_search(updatedPopulation,populationSize,str); | ||
fprintf('\n================local search ends===================\n\n'); | ||
|
||
% whale survival - less fit whales die due to starvation | ||
% Here the base population size is set to 15, change it if necessary | ||
populationSize=max(15,int16(decrement_ratio*populationSize)); | ||
|
||
% updating the population and prey based on the new population | ||
[new_fitness,updatedPopulation] = rankPopulation(updatedPopulation); | ||
if new_fitness(1,1) > preyacc | ||
prey=updatedPopulation(1,:); | ||
preyacc=new_fitness(1,1); | ||
end | ||
|
||
population=updatedPopulation; | ||
fprintf("Population after iteration %d...\n",q-1); | ||
displayPopulation(population); | ||
|
||
% displaying peformance of the best whale | ||
fprintf('Best accuracy till current iteration-%f\n',preyacc); | ||
save(strcat(folderName,'/Iteration_',int2str(q-1),'.mat'),'prey','preyacc'); | ||
end | ||
|
||
% Displaying best result obtained after all iterations are done | ||
fprintf('\n\n---------------------BEST RESULT------------------\n'); | ||
fprintf('Initial best accuracy:%f\n',init_best_acc); | ||
fprintf('Percentage of features selected initially=%f\n',sum(init_best_feat)*100/featCount); | ||
fprintf('Best aacuracy:%f\n',preyacc); | ||
fprintf('Percentage of selected features=%f\n',sum(prey)*100/featCount); | ||
fprintf('--------------------------------------------------\n'); | ||
time=toc; | ||
|
||
% Applying final population of whales over test data | ||
% Storing the results in memory | ||
fprintf("Till now test data is not considered while evaluating whales...\n"); | ||
fprintf("Now the final set of whales are introduced to the test data...\n"); | ||
final_acc = zeros(populationSize,1); | ||
for i=1:populationSize | ||
final_acc(i,1) = knnClassifier(updatedPopulation(i,:)); | ||
end | ||
preyacc = knnClassifier(prey); | ||
[~,nid]=sort(final_acc,'descend'); | ||
final_acc=final_acc(nid,:); | ||
updatedPopulation = updatedPopulation(nid,:); | ||
|
||
if(preyacc<final_acc(1,1)) | ||
preyacc = final_acc(1,1); | ||
prey = updatedPopulation(1,:); | ||
end | ||
|
||
memory.preyacc = preyacc; | ||
memory.prey = prey; | ||
memory.accuracy(1:populationSize,:) = final_acc; | ||
memory.features(1:populationSize,:) = updatedPopulation; | ||
memory.time=time; | ||
|
||
end | ||
|
||
function [P]=calculate_A(a,r,featCount) | ||
% Calculate A using Eqn. 4 | ||
P = zeros(1, featCount); | ||
for i=1:featCount | ||
P(1,i)=2*a*r(1,i)-a; | ||
end | ||
end | ||
|
||
function [m]=modulas_A(A,featCount) | ||
s=0; | ||
for i=1:featCount | ||
s=s+A(1,i)*A(1,i); | ||
end | ||
m=sqrt(s); | ||
end | ||
|
||
function [d]=dista(C,X,Xp,featCount) | ||
% Calculate distance according to Eqn. 5 | ||
d = zeros(1, featCount); | ||
for i=1:featCount | ||
d(1,i)=abs(C(1,i)*Xp(1,i)-X(1,i)); | ||
end | ||
end | ||
|
||
function [per, pop] = rankPopulation(population) | ||
% Sort the population of whales according to fitness scores | ||
global populationSize k; | ||
[popSize,~] = size(population); | ||
acc = zeros(popSize,1); | ||
for i=1:popSize | ||
acc(i,1) = crossValidation(population(i,:),k); | ||
end | ||
[~,nid]=sort(acc,'descend'); | ||
acc=acc(nid,:); | ||
population = population(nid,:); | ||
per = acc(1:populationSize,1); | ||
pop = population(1:populationSize,:); | ||
end | ||
|
||
function [] = displayPopulation(population) | ||
% Display the population of whales at any point | ||
[popSize,~] = size(population); | ||
fprintf("Current population size - %d\n", popSize) | ||
[acc, pop] = rankPopulation(population); | ||
for i=1:popSize | ||
fprintf("Whale %d: Features-%d\t Accuracy-%f\n",i, sum(pop(i,:)), acc(i,1)); | ||
end | ||
fprintf('\n\n'); | ||
end | ||
|
||
%% division of crossvalidation | ||
function [] = createDivision() | ||
|
||
% This function assigns each training sample to a particular fold | ||
% The variable selection contains the fold value for each sample | ||
|
||
global t fold selection; | ||
rows = size(t,1); | ||
s=size(t,1); | ||
labels=zeros(1,s); | ||
for i=1:s | ||
labels(1,i)=find(t(i,:),1); | ||
end | ||
l = max(labels); | ||
selection=zeros(1,rows); | ||
|
||
for k=1:l | ||
count1=sum(labels(:)==k); | ||
samplesPerFold=int16(floor((count1/fold))); | ||
for j=1:fold | ||
count=0; | ||
for i=1:rows | ||
if(labels(i)==k && selection(i)==0) | ||
selection(i)=j; | ||
count=count+1; | ||
end | ||
if(count==samplesPerFold) | ||
break; | ||
end | ||
end | ||
end | ||
j=1; | ||
for i=1:rows | ||
if(selection(i)==0 && labels(i)==k) | ||
selection(i)=j; % sorts any extra into rest | ||
j=j+1; | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
function [p]=chaotic(p,type) | ||
% function to introduce chaos to the system of whales | ||
% type determines nature of the chaos i.e. circular, logistics, piecewise | ||
% or tent | ||
|
||
if type==1 | ||
p=circle(p); | ||
elseif type==2 | ||
p=logistics(p); | ||
elseif type==3 | ||
p=piecewise(p); | ||
elseif type==4 | ||
p=tent(p); | ||
end | ||
|
||
end | ||
|
||
function [p]=circle(p) | ||
% circular chaos | ||
a=0.5; | ||
b=0.2; | ||
pi=3.1415; | ||
p=mod(p+b-(a/(2*pi))*sin(2*pi*p),1); | ||
end | ||
|
||
function [p]=logistics(p) | ||
%logistical chaos | ||
a=4; | ||
p=a*p*(1-p); | ||
end | ||
|
||
function [p]=piecewise(p) | ||
% piecewise chaos | ||
a=0.4; | ||
if (p>=0 && p<a) | ||
p=p/a; | ||
elseif (a<=p && p<0.5) | ||
p=(p-a)/(0.5-a); | ||
elseif (p>=0.5 && p<(1-a)) | ||
p=(1-a-p)/(0.5-a); | ||
elseif (p>=(1-a) && p<1) | ||
p=(1-p)/a; | ||
end | ||
end | ||
|
||
function [p]=tent(p) | ||
% tent chaos | ||
if(p<0.7) | ||
p=p/0.7; | ||
else | ||
p=(10*(1-p))/3; | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
function [per]=crossValidation(whale,k) | ||
% Crossvalidates the agents with (k-1) folds for training, 1 fold for testing | ||
|
||
global x t fold selection; | ||
rng('default'); | ||
|
||
rows=size(x,1); | ||
accuracy=zeros(1,fold); | ||
data=x(:,whale==1); | ||
if (size(data,2)==0) | ||
per = 0; | ||
return; | ||
end | ||
for i=1:fold | ||
chr=zeros(rows,1);%0 training, 1 test; | ||
for j=1:rows | ||
if selection(j)==i | ||
chr(j,1)=1; | ||
end | ||
end | ||
ch = 1; | ||
if (ch==1) | ||
accuracy(1,i) = knnClassify(data,t,chr,k); | ||
elseif (ch==2) | ||
accuracy(1,i) = svmClassify(data,t,chr,k); | ||
else | ||
accuracy(1,i) = mlpClassify(data,t,chr,k); | ||
end | ||
end | ||
|
||
per = mean(accuracy); | ||
per = per * 100; | ||
end | ||
|
||
function [performance]=knnClassify(x,t,chr,k) | ||
|
||
% This function implements knn classifier but it uses | ||
% only training dataset for classification thereby | ||
% preserving the test data only for the final accuracy computation | ||
|
||
x2=x(chr(:)==1,:); | ||
t2=t(chr(:)==1,:); | ||
x=x(chr(:)==0,:); | ||
t=t(chr(:)==0,:); | ||
|
||
s=size(t,1); | ||
label=zeros(1,s); | ||
for i=1:s | ||
label(1,i)=find(t(i,:),1); | ||
end | ||
|
||
knnModel=fitcknn(x,label,'NumNeighbors',k,'Standardize',1); | ||
[label,~] = predict(knnModel,x2); | ||
s=size(t2,1); | ||
lab=zeros(s,1); | ||
for i=1:s | ||
lab(i,1)=find(t2(i,:),1); | ||
end | ||
c = sum(lab ~= label)/s; % mis-classification rate | ||
performance=1-c; | ||
end | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
function [data] = datacreate(n,num) | ||
%creates a feature list | ||
%n is the number of whales we are working on | ||
%num is the number of features | ||
|
||
rng('shuffle'); | ||
max=int16(num*0.50);%number of features we have | ||
min=int16(num*0.40);%number of features we take minimum | ||
if(max+min>n) | ||
max=max-1; | ||
min=min-1; | ||
end | ||
data=int16(zeros(n,num)); | ||
|
||
for i=1:n | ||
x2=int16(abs(rand*(min)))+(max);%number of features we select at max will have 5 features less than maximum | ||
temp=rand(1,num); | ||
[~,temp]=sort(temp); | ||
for j= 1:x2 | ||
data(i,temp(j))=1; | ||
end | ||
clear x2 temp; | ||
end | ||
clear max min count; | ||
data = data > 0.5; | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
function [p]=encircle(Xp,c,A,D) | ||
% encircling mechanism followed by humpback wghales | ||
% follows Eqn. 10 of the paper | ||
|
||
q = zeros(1,c); | ||
p = zeros(1,c); | ||
|
||
for i=1:c | ||
q(1,i)=Xp(1,i)-A(1,i)*D(1,i); | ||
if q(1,i)>1 | ||
p(1,i)=1; | ||
else | ||
p(1,i)=0; | ||
end | ||
end | ||
end |
Oops, something went wrong.