% Please use Octave version 4.0.0 (Code was executed on ubuntu platform)
% This code extracts the secondary structure, ASA and torsion angles from Phosphoglycerylationstruct file for each lysine K
% The code generates the arff files which is used to train MLP in WEKA
% Before executing the code, please create a folder by the name 'arffs' and provide its directory in the Third Phase section of the code
% The new set of train and test generated when this code is executed is everytime different due to shuffling. But the overall performance based on evaluation metrics are similar
% The generated training sets are labelled Train1, Train2, ..., Train10 while the test sets Fold1_10, Fold2_10, ..., Fold10_10 once the code has executed

pkg load statistics
%-------------------------------------------------------------
% First Phase: Data Extraction and construction of testing set
%-------------------------------------------------------------
load Phosphoglycerylationstruct % Load the phosphoglycerylation dataset (raw file from which we will extract the data from. It already has features for protein sequences)

% Data extraction
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Unprocessed_data = DB_Phosphoglycerylation;

Field = size(Unprocessed_data,2); % Columns of unprocessed data. It is number of protein sequences 

z=0;
for a = 1:Field
    z = z + size(strfind(Unprocessed_data(a).seq{1},'K'), 2); % Finding total lysine K in the entire protein sequences
end

Final_Data = cell(z,4); % Create data file which will contain info of each lysine k
k=0;  

for l = 1:Field
    K_locations_field{l} = strfind(Unprocessed_data(l).seq{1},'K'); % Saves the locations of K found in protein sequences
end

window = 2; % Window of 2 indicates 2 upstream and 2 downstream of lysine k

for m = 1:Field
    for n=1:size(K_locations_field{m},2) % loop in all the K locations
        
        k = k+1; % Increment to next data saving location
        Final_Data{k,1} = Unprocessed_data(m).name; % Save protein name at 1st position
        
        if K_locations_field{m}(n) <= window % Location K close to N terminus

            matrix_a_1 = Unprocessed_data(m).ASA(1:K_locations_field{m}(n)+window,:); % Vector containing ASA from start of protein seq till 2 downstream of K
            matrix_b_1 = Unprocessed_data(m).ASA(K_locations_field{m}(n)+K_locations_field{m}(n):K_locations_field{m}(n)+window,:); % Vector containing ASA from location 2x the location of K till end of downstream 
            matrix_c_1 = flipud(matrix_b_1); % Mirroring the matrix_b_1 (flipping on horizontal axis) 
            Final_1_1 = [matrix_c_1; matrix_a_1]; % Concatenate the two vectors which contains sufficient upstream and downstream amino acid   

            matrix_a_2 = Unprocessed_data(m).SSpre(1:K_locations_field{m}(n)+window,:); % Matrix containing SSpre from start of protein seq till 2 downstream of K
            matrix_b_2 = Unprocessed_data(m).SSpre(K_locations_field{m}(n)+K_locations_field{m}(n):K_locations_field{m}(n)+window,:); % Matrix containing SSpre from location 2x the location of K till end of downstream 
            matrix_c_2 = flipud(matrix_b_2); % Mirroring the matrix_b_2 (flipping on horizontal axis) 
            Final_1_2 = [matrix_c_2; matrix_a_2]; % Concatenate the two matrices which contains sufficient upstream and downstream amino acid 
            
            matrix_a_3 = Unprocessed_data(m).Phi(1:K_locations_field{m}(n)+window,:); % Vector containing Phi from start of protein seq till 2 downstream of K
            matrix_b_3 = Unprocessed_data(m).Phi(K_locations_field{m}(n)+K_locations_field{m}(n):K_locations_field{m}(n)+window,:); % Vector containing Phi from location 2x the location of K till end of downstream 
            matrix_c_3 = flipud(matrix_b_3); % Mirroring the matrix_b_3 (flipping on horizontal axis) 
            Final_1_3 = [matrix_c_3; matrix_a_3]; % Concatenate the two vectors which contains sufficient upstream and downstream amino acid 

            matrix_a_4 = Unprocessed_data(m).Psi(1:K_locations_field{m}(n)+window,:); % Vector containing Psi from start of protein seq till 2 downstream of K
            matrix_b_4 = Unprocessed_data(m).Psi(K_locations_field{m}(n)+K_locations_field{m}(n):K_locations_field{m}(n)+window,:); % Vector containing Psi from location 2x the location of K till end of downstream 
            matrix_c_4 = flipud(matrix_b_4); % Mirroring the matrix_b_4 (flipping on horizontal axis) 
            Final_1_4 = [matrix_c_4; matrix_a_4]; % Concatenate the two vectors which contains sufficient upstream and downstream amino acid 

            matrix_a_5 = Unprocessed_data(m).Theta(1:K_locations_field{m}(n)+window,:); % Vector containing Theta from start of protein seq till 2 downstream of K
            matrix_b_5 = Unprocessed_data(m).Theta(K_locations_field{m}(n)+K_locations_field{m}(n):K_locations_field{m}(n)+window,:); % Vector containing Theta from location 2x the location of K till end of downstream 
            matrix_c_5 = flipud(matrix_b_5); % Mirroring the matrix_b_5 (flipping on horizontal axis) 
            Final_1_5 = [matrix_c_5; matrix_a_5]; % Concatenate the two vectors which contains sufficient upstream and downstream amino acid 

            matrix_a_6 = Unprocessed_data(m).Tau(1:K_locations_field{m}(n)+window,:); % Vector containing Tau from start of protein seq till 2 downstream of K
            matrix_b_6 = Unprocessed_data(m).Tau(K_locations_field{m}(n)+K_locations_field{m}(n):K_locations_field{m}(n)+window,:); % Vector containing Tau from location 2x the location of K till end of downstream 
            matrix_c_6 = flipud(matrix_b_6); % Mirroring the matrix_b_6 (flipping on horizontal axis) 
            Final_1_6 = [matrix_c_6; matrix_a_6]; % Concatenate the two vectors which contains sufficient upstream and downstream amino acid 

            F1 = transpose([Final_1_1 Final_1_2 Final_1_3 Final_1_4 Final_1_5 Final_1_6]); % Concatenate the matrices containing the 8 properties of each amino acid 
            Final_Data{k,2} = F1(:)'; % Transpose the concatenated matrix and save it. This makes up the features for Lysine K close to the start of the protein sequence
            
            matrix_a_7 = Unprocessed_data(m).seq{1}(1:K_locations_field{m}(n)+window); % Amino acid from start of protein seq till 2 downstream of K
            matrix_b_7 = Unprocessed_data(m).seq{1}(K_locations_field{m}(n)+K_locations_field{m}(n):K_locations_field{m}(n)+window); % Amino acid from location 2x the location of K till end of downstream 
            matrix_c_7 = flip(matrix_b_7, 2); % Mirroring the matrix_b_7 (flipping on horizontal axis) 
            Final_1_7 = [matrix_c_7 matrix_a_7]; % Concatenate the two vectors which contains sufficient upstream and downstream amino acid. This is peptide P
            Final_Data{k,5} = Final_1_7;
            
        elseif K_locations_field{m}(n) > (Unprocessed_data(m).len - window) % Location K close to C terminus

            matrix_d_1 = Unprocessed_data(m).ASA(K_locations_field{m}(n)-window:Unprocessed_data(m).len,:); % Vector containing ASA from 2 upstream of K till end of protein seq
            matrix_e_1 = Unprocessed_data(m).ASA(K_locations_field{m}(n)-window:Unprocessed_data(m).len-(((Unprocessed_data(m).len-K_locations_field{m}(n))*2)+1),:); % Vector containing ASA from 2 upstream of K till the value to be mirrored
            matrix_f_1 = flipud(matrix_e_1); % Mirroring the matrix_e_1 (flipping on horizontal axis)
            Final_2_1 = [matrix_d_1; matrix_f_1]; % Concatenate the two vectors which contains sufficient upstream and downstream amino acid

            matrix_d_2 = Unprocessed_data(m).SSpre(K_locations_field{m}(n)-window:Unprocessed_data(m).len,:); % Matrix containing SSpre from 2 upstream of K till end of protein seq
            matrix_e_2 = Unprocessed_data(m).SSpre(K_locations_field{m}(n)-window:Unprocessed_data(m).len-(((Unprocessed_data(m).len-K_locations_field{m}(n))*2)+1),:); % Matrix containing SSpre from 2 upstream of K till the value to be mirrored
            matrix_f_2 = flipud(matrix_e_2); % Mirroring the matrix_e_2 (flipping on horizontal axis)
            Final_2_2 = [matrix_d_2; matrix_f_2]; % Concatenate the two matrices which contains sufficient upstream and downstream amino acid

            matrix_d_3 = Unprocessed_data(m).Phi(K_locations_field{m}(n)-window:Unprocessed_data(m).len,:); % Vector containing Phi from 2 upstream of K till end of protein seq
            matrix_e_3 = Unprocessed_data(m).Phi(K_locations_field{m}(n)-window:Unprocessed_data(m).len-(((Unprocessed_data(m).len-K_locations_field{m}(n))*2)+1),:); % Vector containing Phi from 2 upstream of K till the value to be mirrored
            matrix_f_3 = flipud(matrix_e_3); % Mirroring the matrix_e_3 (flipping on horizontal axis)
            Final_2_3 = [matrix_d_3; matrix_f_3]; % Concatenate the two vectors which contains sufficient upstream and downstream amino acid

            matrix_d_4 = Unprocessed_data(m).Psi(K_locations_field{m}(n)-window:Unprocessed_data(m).len,:); % Vector containing Psi from 2 upstream of K till end of protein seq
            matrix_e_4 = Unprocessed_data(m).Psi(K_locations_field{m}(n)-window:Unprocessed_data(m).len-(((Unprocessed_data(m).len-K_locations_field{m}(n))*2)+1),:); % Vector containing Psi from 2 upstream of K till the value to be mirrored
            matrix_f_4 = flipud(matrix_e_4); % Mirroring the matrix_e_4 (flipping on horizontal axis)
            Final_2_4 = [matrix_d_4; matrix_f_4]; % Concatenate the two vectors which contains sufficient upstream and downstream amino acid

            matrix_d_5 = Unprocessed_data(m).Theta(K_locations_field{m}(n)-window:Unprocessed_data(m).len,:); % Vector containing Theta from 2 upstream of K till end of protein seq
            matrix_e_5 = Unprocessed_data(m).Theta(K_locations_field{m}(n)-window:Unprocessed_data(m).len-(((Unprocessed_data(m).len-K_locations_field{m}(n))*2)+1),:); % Vector containing Theta from 2 upstream of K till the value to be mirrored
            matrix_f_5 = flipud(matrix_e_5); % Mirroring the matrix_e_5 (flipping on horizontal axis)
            Final_2_5 = [matrix_d_5; matrix_f_5]; % Concatenate the two vectors which contains sufficient upstream and downstream amino acid

            matrix_d_6 = Unprocessed_data(m).Tau(K_locations_field{m}(n)-window:Unprocessed_data(m).len,:); % Vector containing Tau from 2 upstream of K till end of protein seq
            matrix_e_6 = Unprocessed_data(m).Tau(K_locations_field{m}(n)-window:Unprocessed_data(m).len-(((Unprocessed_data(m).len-K_locations_field{m}(n))*2)+1),:); % Vector containing Tau from 2 upstream of K till the value to be mirrored
            matrix_f_6 = flipud(matrix_e_6); % Mirroring the matrix_e_6 (flipping on horizontal axis)
            Final_2_6 = [matrix_d_6; matrix_f_6]; % Concatenate the two vectors which contains sufficient upstream and downstream amino acid

            F1 = transpose([Final_2_1 Final_2_2 Final_2_3 Final_2_4 Final_2_5 Final_2_6]); % Concatenate the matrices containing the 8 properties of each amino acid 
            Final_Data{k,2} = F1(:)'; % Transpose the concatenated matrix and save it. This makes up the features for Lysine K close to the end of the protein sequence
            
            matrix_d_7 = Unprocessed_data(m).seq{1}(K_locations_field{m}(n)-window:Unprocessed_data(m).len); % Amino acid from 2 upstream of K till end of protein seq
            matrix_e_7 = Unprocessed_data(m).seq{1}(K_locations_field{m}(n)-window:Unprocessed_data(m).len-(((Unprocessed_data(m).len-K_locations_field{m}(n))*2)+1)); % Amino acid from 2 upstream of K till the value to be mirrored
            matrix_f_7 = flip(matrix_e_7, 2); % Mirroring the matrix_e_7 (flipping on horizontal axis)
            Final_2_7 = [matrix_d_7 matrix_f_7]; % Concatenate the two vectors which contains sufficient upstream and downstream amino acid. This is peptide P
            Final_Data{k,5} = Final_2_7;           
            
        else % Location is good and does not require mirroring
            Final_3_1 = Unprocessed_data(m).ASA(K_locations_field{m}(n)-window:K_locations_field{m}(n)+window,:); % ASA vector (2 upstream and 2 downstream of K)
            Final_3_2 = Unprocessed_data(m).SSpre(K_locations_field{m}(n)-window:K_locations_field{m}(n)+window,:); % SSpre matrix (2 upstream and 2 downstream of K)
            Final_3_3 = Unprocessed_data(m).Phi(K_locations_field{m}(n)-window:K_locations_field{m}(n)+window,:); % Phi vector (2 upstream and 2 downstream of K)
            Final_3_4 = Unprocessed_data(m).Psi(K_locations_field{m}(n)-window:K_locations_field{m}(n)+window,:); % Psi vector (2 upstream and 2 downstream of K)
            Final_3_5 = Unprocessed_data(m).Theta(K_locations_field{m}(n)-window:K_locations_field{m}(n)+window,:); % Theta vector (2 upstream and 2 downstream of K)
            Final_3_6 = Unprocessed_data(m).Tau(K_locations_field{m}(n)-window:K_locations_field{m}(n)+window,:); % Tau vector (2 upstream and 2 downstream of K)

            F1 = transpose([Final_3_1 Final_3_2 Final_3_3 Final_3_4 Final_3_5 Final_3_6]); % Concatenate the matrices containing the 8 properties of each amino acid
            Final_Data{k,2} = F1(:)'; % Transpose the concatenated matrix and save it. This makes up the features for Lysine K which did not require mirroring
            
            Final_Data{k,5} = Unprocessed_data(m).seq{1}(K_locations_field{m}(n)-window:K_locations_field{m}(n)+window); % Peptide P (2 upstream and 2 downstream of K)

        end
        
        Final_Data{k,3} = Unprocessed_data(m).label{1}(K_locations_field{m}(n)); % Save class label
        Final_Data{k,4} = K_locations_field{m}(n); % Save the K's location in the protein sequence
    
    end
end

Training_Data1 = Final_Data; % Save the extracted data to new variable Training_Data1

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Separation of neg and pos samples
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Num_of_Pos  = 0;
Num_of_Neg  = 0;

for i = 1:size(Training_Data1,1)
    
    if Training_Data1{i,3} == '1'
       Num_of_Pos = Num_of_Pos + 1;
       Final_Pos(Num_of_Pos,:) = Training_Data1(i,:); 
    end
    if Training_Data1{i,3} == '0'
       Num_of_Neg = Num_of_Neg + 1;
       Neg_Samples(Num_of_Neg,:) = Training_Data1(i,:);
    end    
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Filtering of neg samples to bring class imbalance from 1:29 to 1:3
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Filtered_Neg = Neg_Samples;

for a=1:size(Neg_Samples,1)
    
    for b=1:size(Training_Data1, 1)

        Distance = pdist2(Neg_Samples{a,2}, Training_Data1{b,2}); % Euclidean distance between the neg sample and a sample in whole data
   
        D(b, 1) = Distance; % Save the 3360 distances of entire data samples into 3360x1 matrix
        
    end
    
    for c=1:70 % Number of nearest neighbors (including itself as it also calculated from itself at one point in time) to be taken into account for filtering. Number of neighbors is actually 69 
   
        [M,I] = min(D); % Find minimum from the 3360x1 matix and also its index
        
        if Training_Data1{I,3} == '1' % If the minimum distance is for a +ve sample then delete the neg sample
            
            Filtered_Neg{a,2} = [];
            break
        end
       
        D(I) = [max(D)]; % Replace the minimum value with the maximum value of the matrix so that it wont point the same index as minimum in the next loop
        c = c+1;
    end
end

% Construct the neg samples after filtering
e = 1;
for j=1:size(Filtered_Neg,1)
    if isempty(Filtered_Neg{j,2}) == false
  
        Final_Neg(e,:) = Filtered_Neg(j,:); 
  
        e = e+1;
        
    end
end

if (332 > size(Final_Neg,1)) || (size(Final_Neg,1) > 343)
   
    msg = 'Filtering is not good'; % Gives message when filtering does not result in ratio of 1:3. In this code, correct K value (c value in the code) is already provided
    error(msg)
   
end
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Dividing data into 10 parts for 10 fold cross validation
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Filtered_Data_SamplesSep = [Final_Pos; Final_Neg]; % Combine the final sets of positive and negatives samples after the filtering process

len_of_data = size(Filtered_Data_SamplesSep, 1);

extra = mod(len_of_data,10);
base_size = (len_of_data - extra)/10;

for i = 1:10
    if (i>(10-extra))
        fold_size(i) = base_size + 1;
        
    else
        fold_size(i) = base_size;
        
    end  
end

default_gap = [5 10 15 20 25 30 35 40 45 50]; % Randomly assigned numbers (Number of +ve samples in each parts)
loop = 1;

% Dividing the Dataset into 10 parts and making sure +ve and -ve samples
% are well distributed
while(loop == 1)

        Data_Shuffled1 = Filtered_Data_SamplesSep(randperm(len_of_data),:);
        Data_Shuffled = Data_Shuffled1(randperm(len_of_data),:);

        Fold1_10 = Data_Shuffled(1:fold_size(1),:); % First Part
        j1=0;
        for i=1:fold_size(1)
        if strfind(Fold1_10{i,3},'1') == true
        j1 = j1+1;
        end
        end
        default_gap(1) = j1;

        Fold2_10 = Data_Shuffled(fold_size(1)+1:sum(fold_size(1:2)),:); % Second Part
        j2=0;
        for i=1:fold_size(2)
        if strfind(Fold2_10{i,3},'1') == true
        j2 = j2+1;
        end
        end
        default_gap(2) = j2;

        Fold3_10 = Data_Shuffled(sum(fold_size(1:2))+1:sum(fold_size(1:3)),:); % Third Part
        j3=0;
        for i=1:fold_size(3)
        if strfind(Fold3_10{i,3},'1') == true
        j3 = j3+1;
        end
        end
        default_gap(3) = j3;

        Fold4_10 = Data_Shuffled(sum(fold_size(1:3))+1:sum(fold_size(1:4)),:); % Fourth Part
        j4=0;
        for i=1:fold_size(4)
        if strfind(Fold4_10{i,3},'1') == true
        j4 = j4+1;
        end
        end
        default_gap(4) = j4;

        Fold5_10 = Data_Shuffled(sum(fold_size(1:4))+1:sum(fold_size(1:5)),:); % Fifth Part
        j5=0;
        for i=1:fold_size(5)
        if strfind(Fold5_10{i,3},'1') == true
        j5 = j5+1;
        end
        end
        default_gap(5) = j5;

        Fold6_10 = Data_Shuffled(sum(fold_size(1:5))+1:sum(fold_size(1:6)),:); % Sixth Part
        j6=0;
        for i=1:fold_size(6)
        if strfind(Fold6_10{i,3},'1') == true
        j6 = j6+1;
        end
        end
        default_gap(6) = j6;

        Fold7_10 = Data_Shuffled(sum(fold_size(1:6))+1:sum(fold_size(1:7)),:); % Seventh Part
        j7=0;
        for i=1:fold_size(7)
        if strfind(Fold7_10{i,3},'1') == true
        j7 = j7+1;
        end
        end
        default_gap(7) = j7;

        Fold8_10 = Data_Shuffled(sum(fold_size(1:7))+1:sum(fold_size(1:8)),:); % Eighth Part
        j8=0;
        for i=1:fold_size(8)
        if strfind(Fold8_10{i,3},'1') == true
        j8 = j8+1;
        end
        end
        default_gap(8) = j8;

        Fold9_10 = Data_Shuffled(sum(fold_size(1:8))+1:sum(fold_size(1:9)),:); % Ninth Part
        j9=0;
        for i=1:fold_size(9)
        if strfind(Fold9_10{i,3},'1') == true
        j9 = j9+1;
        end
        end
        default_gap(9) = j9;

        Fold10_10 = Data_Shuffled(sum(fold_size(1:9))+1:sum(fold_size(1:10)),:); % Tenth Part
        j10=0;
        for i=1:fold_size(10)
        if strfind(Fold10_10{i,3},'1') == true
        j10 = j10+1;
        end
        end
        default_gap(10) = j10;
        
        smallest = min(default_gap); % Minimum number of +ve samples in the overall parts
        largest = max(default_gap); % Maximum number of +ve samples in the overall parts
        
        if ((largest - smallest) < 3) % If difference between minimum and maximum number of +ve samples is less then 3 then there is good distribution of +ves and -ves
            
            loop = 0;
            
        end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%-------------------------------------------
% Second Phase: Contruction of training sets
%-------------------------------------------
% Construction of unoptimized training sets
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Whole_Data = {'Fold1_10' 'Fold2_10' 'Fold3_10' 'Fold4_10' 'Fold5_10' 'Fold6_10' 'Fold7_10' 'Fold8_10' 'Fold9_10' 'Fold10_10'}; 

for i = 1:10
     
    st = num2str(i);
    s = strcat('Fold', st, '_10');
    
    k = 1;
    for j = 1:10
        if regexp(Whole_Data{1,j}, s) == 1 % For each part, construct the corresponding unoptimized training set composed of other parts
            % Do nothing
        else
            index_train{1,k} = j;
            k = k+1;
        
        end
        
    end
    rt = num2str(index_train{1,1});
    r = strcat('Fold', rt, '_10');
    st = num2str(index_train{1,2});
    s = strcat('Fold', st, '_10');
    tt = num2str(index_train{1,3});
    t = strcat('Fold', tt, '_10');
    ut = num2str(index_train{1,4});
    u = strcat('Fold', ut, '_10');
    vt = num2str(index_train{1,5});
    v = strcat('Fold', vt, '_10');
    wt = num2str(index_train{1,6});
    w = strcat('Fold', wt, '_10');
    xt = num2str(index_train{1,7});
    x = strcat('Fold', xt, '_10');
    yt = num2str(index_train{1,8});
    y = strcat('Fold', yt, '_10');
    zt = num2str(index_train{1,9});
    z = strcat('Fold', zt, '_10');
    
    Train{i} = [eval(r); eval(s); eval(t); eval(u); eval(v); eval(w); eval(x); eval(y); eval(z)]; % Save the other 9 parts as unoptimized Training set
    
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Optimization of Training set to bring the class imbalance to 1:2
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

for i = 1:10
      
    Filter_data = Train{i};
    Num_of_Pos  = 0;
    Num_of_Neg  = 0;
    neighbors = 31;
    clear Final_Pos Neg_Samples

    % Separate +ve and -ve samples
    for j = 1:size(Filter_data,1)

        if Filter_data{j,3} == '1'
           Num_of_Pos = Num_of_Pos + 1;
           Final_Pos(Num_of_Pos,:) = Filter_data(j,:); 
        end
        if Filter_data{j,3} == '0'
           Num_of_Neg = Num_of_Neg + 1;
           Neg_Samples(Num_of_Neg,:) = Filter_data(j,:);
        end    
    end
    
    Positive_Sample_Num{i} = Num_of_Pos;
    to_filter = 1;
    
    % Keep filtering by reducing the number of neighbors until ratio is
    % about 1:2. Initial number of neighbors is set to 30 (31-1; in the
    % code below)
    while(to_filter == 1)
        
        clear Final_Neg Filtered_Neg D
        
        Filtered_Neg = Neg_Samples;
        neighbors = neighbors - 1;

        for a=1:size(Neg_Samples,1)

            for b=1:size(Filter_data, 1)

                Distance = pdist2(Neg_Samples{a,2}, Filter_data{b,2}); % Euclidean distance between the neg sample and a sample in whole data

                D(b, 1) = Distance; % Save the distances between the -ve sample and each sample in the entire set

            end

            for c=1:neighbors % Loop to the number of nearest neighbors of neg sample to the entire samples

                [M,I] = min(D); % Find minimum and also its index

                if Filter_data{I,3} == '1' % If the min distance is for a +ve sample then delete the neg sample

                    Filtered_Neg{a,2} = [];
                    break
                end

                D(I) = [max(D)]; % Replace the minimum value with the maximum value so that it wont point the same index as minimum in the next loop
                c = c+1;
            end
        end

        % Construct the neg samples after filtering
        e = 1;
        for j=1:size(Filtered_Neg,1)
            if isempty(Filtered_Neg{j,2}) == false

                Final_Neg(e,:) = Filtered_Neg(j,:);

                e = e+1;

            end
        end
      
        % Check if the ratio of about 1:2 has been achieved. If not, apply
        % filtering again
        if (size(Final_Neg,1)/Num_of_Pos > 2)
            
            to_filter = 0;
            
            report_on_filtering(1, i) = neighbors;
            report_on_filtering(2, i) = Num_of_Pos;
            report_on_filtering(3, i) = size(Final_Neg,1);
        end
        
        Filtered_Train{i} = [Final_Pos; Final_Neg];
        
    end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Saving the optimized training set into different variables

Train1 = Filtered_Train{1};
Train2 = Filtered_Train{2};
Train3 = Filtered_Train{3};
Train4 = Filtered_Train{4};
Train5 = Filtered_Train{5};
Train6 = Filtered_Train{6};
Train7 = Filtered_Train{7};
Train8 = Filtered_Train{8};
Train9 = Filtered_Train{9};
Train10 = Filtered_Train{10};

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%-----------------------------------------------------------------------
% Third Phase: Generating arff files
%-----------------------------------------------------------------------
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

test_names = {'Test1.arff' 'Test2.arff' 'Test3.arff' 'Test4.arff' 'Test5.arff' 'Test6.arff' 'Test7.arff' 'Test8.arff' 'Test9.arff' 'Test10.arff'}; 
train_names = {'Train1.arff' 'Train2.arff' 'Train3.arff' 'Train4.arff' 'Train5.arff' 'Train6.arff' 'Train7.arff' 'Train8.arff' 'Train9.arff' 'Train10.arff'}; 

cd '/home/researcher/Desktop/arffs' % Change directory here
delete *.arff % Delete previously generated arff files

for i = 1:10
     
    st = num2str(i);
    s = strcat('Fold', st, '_10');
    
    Data = [eval(s)]; % use string name to save cell array of same name into Data
    
    filename = fullfile('/home/researcher/Desktop/arffs',test_names{1,i}); % Change directory here
    fid = fopen(filename,'w');

    fprintf(fid,'@%s\r\n\r\n', 'relation Phosphoglycerylation');

    for l=1:size(Data{1,2},2)
    fprintf(fid,'@%s%d %s\r\n', 'attribute F',l,'numeric');
    end

    fprintf(fid,'@%s\r\n', 'attribute label {0,1}');

    fprintf(fid,'\r\n@%s\r\n', 'data');

    for j=1:size(Data,1)
    comma_sep = sprintf('%f,' , Data{j,2});
    fprintf(fid,'%s%s\r\n', comma_sep, Data{j,3});
    end
    fclose(fid)
    
    t = strcat('Train', st);
    
    Data = [eval(t)]; % use string name to save cell array of same name into Data
    
    filename = fullfile('/home/researcher/Desktop/arffs',train_names{1,i}); % Change directory here
    fid = fopen(filename,'w');

    fprintf(fid,'@%s\r\n\r\n', 'relation Phosphoglycerylation');

    for m=1:size(Data{1,2},2)
    fprintf(fid,'@%s%d %s\r\n', 'attribute F',m,'numeric');
    end

    fprintf(fid,'@%s\r\n', 'attribute label {0,1}');

    fprintf(fid,'\r\n@%s\r\n', 'data');

    for j=1:size(Data,1)
    comma_sep = sprintf('%f,' , Data{j,2});
    fprintf(fid,'%s%s\r\n', comma_sep, Data{j,3});
    end
    fclose(fid)
end