Feature Selection Techniques using Evolutionary Algorithms

This article describes application of Evolutionary Algorithms to the task of Feature Selection. In particular the algorithms studies in this article are Particle Swarm Algorithm (PSO) and Genetic Algorithm (GA). The results are based on particular parameters used in experimentation. Here several parameters are analyzed for this problem on two datasets:

  1. Leukemia dataset (LIBSVM Data: Classification (Binary Class) (ntu.edu.tw))
  2. Colon Cancer dataset (LIBSVM Data: Classification (Binary Class) (ntu.edu.tw))
  3. Educational data mining   data set: kdd2010 bridge-toalgebra (kddb) dataset.

The purpose of this article is to show comparative analysis of experiments and that choice of kernel depends both on datasets–the kind of problem, the number of iterations performed, parameters used and more specifically aim of the problem. Here the aim of problem is feature selection which means reducing the dataset to lesser number of features while retaining the accuracy. The fitness function for this problem is a weighted mean of accuracy and number of features. In the following experiments weights are so changed that number of features selected remains below or equal to 20. Hence a decrease in accuracy is noticed below, given the fact the the number of epocs are not changed. The following svm kernels are experimented.

Further, results depend on lot of parameters and this article is the illustration of results in one experimental setup and are not standard results. The results are not benchmarks, they are elaborated for experimental setups in labs, and to be followed by mentors teaching Machine Learning Lab Work. For benchmark results look into peer-reviewed research papers.

  1. Linear
  2. Radial Basis Function (RBF)
  3. Polynomial Function

This article just pays focus on the way experiments are to be performed and analyzed and some results and do not play a role in benchmarking results or changing existing theories. It is just for elaboration for the purpose of academicians and students to learn the art of experimentation for feature selection using SVM, GA and PSO.

Experiment 1: Leukemia Dataset, Linear SVM

Linear Kernel.

The final accuracy reached was:   100

Number of features selected: 9

The following shows the graph of fitness function versus epochs

The final accuracy reached was: 100

Experiment 2: Leukemia Dataset, RBF Kernel

Radial Basis Kernel. The accuracy attained is : 97.222. The following shows the graph of fitness function versus epochs.

The accuracy reached was 97.222 for 38 features in 2000 epocs. Best 10 features were obtained for SVM . After 1400 epocs there was no much decrease in value of optimizing function.

Experiment 3: Leukemia Dataset, Polynomial Kernel

The fitness chosen is with higher weightage to selected features than to accuracy. The final accuracy reached was:    87.5

iterations: 2000

Number of features: 10

The following shows the graph of fitness function versus epochs

Experiment 4: Colon Cancer Dataset, Linear SVM

The final accuracy reached was:  98.3871

Number of features: 19

Top best 19 features were obtained for linear SVM . After 700 epocs there was no much decrease in value of fitness function. The following shows the graph of fitness function versus epochs

The following graph shows in red the number of features, blue the accuracy, green the minimization of fitness value. It is clear that after 800 epocs no minimization of features occurs , hence the algorithm has converged to 19 features as optimal.

Experiment 5: Colon Cancer Dataset, RBF Kernel

Radial Basis Kernel. The accuracy obtained is 91.935

The fitness chosen is with higher weightage to selected features than to accuracy. The final accuracy reached was:  91.935 for 14 features. After 700 epocs there was no much decrease in value of optimizing function.

Experiment 6: Colon Cancer Dataset, Polynomial SVM

The fitness chosen is with higher weightage to selected features than to accuracy.

The final accuracy reached was:   76

iterations: 1000

Number of features obtained: 12

 Obtained best 19 features . After 900 epocs there was not much decrease in value of fitness function. The following shows the graph of fitness function versus epochs

The following graph shows in red the number of features, blue the accuracy, green the minimization of fitness value. It is clear that after 900 epocs not much minimization of features occurs , hence the algorithm has converged to 12 features as optimal.

Experiment 7: Huge Dataset of 3,00,00,000 features

Total Data Testing accuracy: = 87.4392%

Accuracy  after selecting all 30000 features with nnz  :  88.4387%

The total number of features is approximately 3 crores. It took 2 days on the given system to calculate F-Score. When looking closely at data. The data has lot of sparseness. So only those features were taken which are non zeros i.e. non sparse features as sparse features wont contribute to discriminant. This has been used as a filtering method. A lot of time was spend in calculating f scores to filter the data.

Accuracy with non sparse data arranged in increasing value of f-scores

Total  Accuracy =

   5000 features: 88.4387

   10000 features : 88.0772

   15000 features :  87.7453

   20000 features :87.4188

   25000 features :  87.1324

   30000 features : 86.9255

Results of different SVM classifiers by varying  the dimensions in the range from 1000 to 30000 in steps of 5000.

 LiblinearSvm RBFSVM polynomial
5000 features   88.438788.77288.7725
10000 features   88.077288.77288.7725
15000 features   87.745388.77288.7725
20000 features   87.418888.77288.7725
25000 features   87.132488.77288.7725
30000 features   86.925588.77288.7725

Plot of the Results of different SVM classifiers by varying  the dimensions in the range from 1000 to 30000 in steps of 5000

More reduction in data features after 5000 features using PSO

PSO with C1=3, C2=3

Min number  of  features obtained:  415

population size=5

Accuracy: 75

Iterations:500

Convergence graph is given as follows:

PSO with alpha=0.8 and beta a= 0.2 ,C1=3, C2=3

Iterations:500

popsize=5

testing accuracy: 83.66

Min number of Features Obtained= 868

More reduction in data features after 5000 features using GA

GA 500 epochs

population size=5

Accuracy reached: 88.2

Minimum no of features:  1999

More reduction in data features after 5000 features using GA two times

Double application of GA:    79.398%

min features: 199

More reduction in data features after 5000 features using GA 3000 epocs

GA 3000 epochs

Reduced Min Number of features obtained : 367, more could be reduced by more epocs

Accuarcy: 86.563%

Convergence graph is as follows:

More reduction in data features after 5000 features using Forwards Selection Wrapper Method

forward selection:-

Reduced number of minimum features: 197

testing accuracy: 88.6904

More reduction in data features after 5000 features using Backward Selection Wrapper Method

This method did not performed well in reducing the number of feature much

These results show there is a tradeoff between accuracy and number of features selected. While accuracy also depends on the epocs, fitness function optimal value changes on change of fitness function which is taken as weighted mean targeting higher accuracy and lower feature subset on the training data. Further this also shows higher complex fitting of hyperplane may take more time to converge as is considered in experimentation. Best method seem to be forward selection one for reducing after filtering. Further, results depend on lot of parameters, filtering and wrapping techniques followed as pre-processing and post-processing and this article is the illustration of results in one experimental setup and are not standard results.

Function Optimization using Genetic Algorithm and Particle Swarm Optimization-Results and Comparison

In this article some experiments and their results are discussed for minimization of Rastrigin function, a famous mathematical function used in Optimization Techniques evaluation. The experiments are performed on certain setup, parameters and system. This has been performed using Genetic Algorithm (GA) and Particle Swarm Optimization (PSO). The fitness function is the given function to be optimized. This article just pays focus on the way experiments are to be performed and analyzed in students lab and by mentors teaching Machine Learning results do not play a role in benchmarking or changing existing theories. It is just for elaboration for the purpose of academicians and students to learn the art of optimizing function with the help of GA and PSO.

This function is given by

The function is usually evaluated on xi ∈ [-5.12, 5.12], for all i = 1, …, n . This has been tried on 5 different values of n between 10 and 100 as follows. Taking N as the size of the chromosome for GA and PSO implementation and population size of 10.

The Matlab implementation of fitness function is

%Fitness function
function z= testfunction(x)
%z= (x’x);
[M,N]=size(x);
z=[];
sum =0;
for j=1:M
for i = 1:N
sum = sum + (x(j,i)x(j,i) – 10 * cos (23.14x(j,i)));
end
z= [z;sum + 10*N]
end

The following table shows the experimental results.

NGA Final Minimum Value after 500 iterationsPSO Global Minimum Value after 500 iterations with C1=1, C2=2PSO Global Minimum Value after 500 iterations with C1=3, C2=3PSO Global Minimum Value after 500 iterations with C1=3, C2=2PSO Global Minimum Value after 500 iterations with C1=2, C2=3
1027.8663(500 epochs)/ 9.1 in 1000 epochs12.723  4.00028.46097.0004
20113.9635(500 epochs)74.58413.00131.87929.679
40399.6707 (500 epochs) / 235 in 1000 epochs   191.02 43.23 127.1 115.58
60918.9643(500 epochs)/ 619 (1000 epochs)372.296.065193.74189.75
801392.1043(500 epochs)    489.16220.28314.04286.96

The general analysis of results is that PSO is performing better than GA here given the same number of iterations. Though GA solutions are gradually decreasing while PSO solutions are oscillating.  Within PSO the c1=3, c2=3 seems to perform best, c1=1 and c2=2 seem to perform the worst in achieving global minimum. More details and comments below.

Num of chromosomes : 10

One point crossover GA., with 5% mutation rate.

Maximum  number of iterations: 500.

Graphical Visualization of Results

Command for plots:

plot(ga.iters,ga.minc,’:’,pso1.iters,pso1.minc,’green’, pso2.iters, pso2.minc ,’blue’ ,pso3.iters ,pso3.minc, ‘red’,pso4.iters,pso4.minc,’black’);

Here is plot for N=80

Green: PSO1: with parameters : c1=1,c2=2 : Oscillates and convergence not as fast as other parameters.

Blue: PSO2 : with parameters : c1=3,c2=3  :  Oscillates and reaches towards minima.

Red: PSO3 : with parameters : c1=3,c2=2  : Oscillates.  Reaches towards minima

Black: PSO4 : with parameters :  c1=2,c2=3 : Oscillates.  Reaches  towards minima

Dots : GA, still decreasing and is more stable though global minimum is not less than PSO.

And comparing GA and PSO , GA seems not to oscillates and be stable though its minimum not attained as fast.

PSO1 with c1=1,c2=2, seem to not be as fast in attaining minimum as compared to other parameters which are almost equivalent in attaining minimum. Here is separate result of c1=1, c2=2.

Plot of the three competing models is as follows:

Results for N=60

Green: PSO1: with parameters: c1=1,c2=2: Oscillates and convergence not as fast as other parameters.

Blue: PSO2 : with parameters : c1=3,c2=3  :  Oscillates and reaches towards minima.

Red: PSO3 : with parameters : c1=3,c2=2  : Oscillates.  Reaches towards minima

Black: PSO4 : with parameters :  c1=2,c2=3 : Oscillates.  Reaches  towards minima

Dots: GA, still decreasing and is more stable though global minimum is not less than PSO.

And comparing GA and PSO , GA seems not to oscillates and be stable though its minimum not attained as fast.

Plot of three competing models as follows

PSO1 with c1=1,c2=2, seem to not be as fast in attaining minimum as compared to other parameters which are almost equivalent in attaining minimum. Here is separate result of c1=1, c2=2.

Results for N=40

Green: PSO1: with parameters : c1=1,c2=2 : Oscillates and convergence not as fast as other parameters.

Blue: PSO2 : with parameters : c1=3,c2=3  :  Oscillates and reaches towards minima.

Red: PSO3 : with parameters : c1=3,c2=2  : Oscillates.  Reaches towards minima

Black: PSO4 : with parameters :  c1=2,c2=3 : Oscillates.  Reaches  towards minima

Dots: GA, still decreasing and is more stable though global minimum is not less than pso.

And comparing GA and PSO , GA seems not to oscillates so much and be stable though its minimum not attained as fast.

PSO1 with c1=1,c2=2, seem to not be as fast in attaining minimum as compared to other parameters which are almost equivalent in attaining minimum. Here is separate result of c1=1, c2=2.

Results for N=20

Green: PSO1: with parameters : c1=1,c2=2 : Oscillates and convergence not as fast as other parameters.

Blue: PSO2 : with parameters : c1=3,c2=3  :  Oscillates and reaches towards minima.

Red: PSO3 : with parameters : c1=3,c2=2  : Oscillates.  Reaches towards minima

Black: PSO4 : with parameters :  c1=2,c2=3 : Oscillates.  Reaches  towards minima

Dots: GA, still decreasing and is more stable though global minimum is not less than PSO.

And comparing GA and PSO , GA seems not to oscillates and be stable though its minimum not attained as fast.

PSO1 with c1=1,c2=2, seem to not be as fast in attaining minimum as compared to other parameters which are almost equivalent in attaining minimum. Here is separate result of c1=1, c2=2.

Results for N=11

Green: PSO1: with parameters : c1=1,c2=2 : Oscillates and convergence not as fast as other parameters.

Blue: PSO2 : with parameters : c1=3,c2=3  :  Oscillates and reaches towards minima.

Red: PSO3 : with parameters : c1=3,c2=2  : Oscillates.  Reaches towards minima

Black: PSO4 : with parameters :  c1=2,c2=3 : Oscillates.  Reaches  towards minima

Dots: GA, still decreasing and is more stable though global minimum is not less than PSO

And comparing GA and PSO , GA seems not to oscillates and be stable though its minimum not attained as fast.

PSO1 with c1=1,c2=2, seem to not be as fast in attaining minimum as compared to other parameters which are almost equivalent in attaining minimum. Here is separate result of c1=1, c2=2.

The experiments are performed on certain setup, parameters and system. The general impression and analysis are given at end of each experiment conducted. Changing parameters, the mutations functions, population to be performed for creating new chromosomes in case of GA drastically effects the results obtained. In a similar manner for PSO several parameters, initializations effect the results apart from C1 and C2 experimented above. The results are not benchmarks, they are elaborated for experimental setups in labs, and to be followed by mentors teaching Machine Learning Lab Work. For benchmark results look into peer-reviewed research papers.

2-class Image Recognition Task using Backpropagation, Regularized Neural Networks, Logistic Regression and Naive Bayes-Code, Results and Analysis for given Implementation

This article is for education and learning purpose. The aim is to understand how to start experimentation in the area of Neural Networks, how to compare results, what all features to consider while doign experiments. It is a handy tool for those doing self learning in the area of Machine Learning. And a good start for educators who want to impart education in these areas and want to know the art of assignments and what all to expect. Further, the results are not benchmarks, they are elaborated for explanations given ahead. For benchmark results look into peer-reviewed research papers.

Here we have implemented backpropagation algorithm and have tested on a subset of original MNIST datasets for 2-class problem of digit image recognition.

Backpropogation with MNIST Data for binary case of 3 and 8 digits

Contents

1.     Preprocessing the available data. 1

2.     Code Implementation Details. 1

i.       BackPropogation38. 2

ii.      TrainBP. 2

iii.     TestBP. 3

3.Evaluations and Results. 4

This article just pays focus on the way experiments are to be performed and analyzed and some results and do not play a role in benchmarking results or changing existing theories. It is just for elaboration for the purpose of academicians and students to learn the art of how Neural Networks can be used for two class classifications of image data. Further, the results vary with change in number of hidden layers, initial weights, and other settings.

1.     Preprocessing the available data.

I have written a script to collect subset of data from 3 and 8 digits called mnist_38_2.mat. The script takes the training data, training labels, testing data and testing labels and is combined into one data file.  This script extracts the 3 and 8 digits from training and testing data and creates a  single mat file of the whole data containing the training and the testing data along with their labels.

Note: I have performed much fewer epochs on experimentations due to constraints on my computing devise used. This is too less when GPUs are used. But all this is for illustrative purpose only. You can ask your students to perform higher iterations for reaching a higher accuracy and even testing on various number of hidden layers.

2.     Code Implementation Details

Here are details of implementation  of the backpropagation algorithm that I have written for binary case of digits 3 and digit 8 classification. I  have written the code in Matlab. The Matlab file name is backpropogation_38. Appropriate self explanatory comments are given in the code. Here is a brief summary of the algorithm that being implemented.

The methods are as follows:

i.                    BackPropogation38

This is the main method of the file from where execution starts. In this method data is read from file mnist38All.

This is for two class problem for more than two class code changes. Taking correct positive class as 3 ie 0 and the other one as ie 8 as 1. This is the main method of the file from where execution starts. In this method data is read from file mnist38.mat then 10 folds of data is created. Experiments were performed with crossvalind with a holdout of 0.1,0.2,0.3 to make number of elements in testing set as 10%  20% and 30% in testing and remaining ones in training. Further vtot is defined as a vector which stores the average values of following  quantities for the final result. The quantities stored in vtot are [ TP,TN,FP,FN, Precision, Recall, F-measure, accuracy]. We define the number of hidden and number of output neurons in this method experiments were done using varying number of hidden neurons equal to 100.

Inside the loop for ten folds call to the back propagation is made for training function on each of the training and testing set generated. Then on the same set of testing data the evaluations is performed. trainBP is for training and testBP for testing in the for loop.

ii.                   TrainBP

This is the main function that does the training of the network . It takes the following parameters and return types are discussed. Followed by the details of procedure:

—————parameters————–

trainingSet:  The training data as obtained by crossvalind                                                      

num_Hidden: The number of hidden nodes

num_Output: The number of output nides

trainingLabels:  The labels of training data, in case of one output the number of colums in data is one else is equal to number of output nodes     

—————-Return Arguments——————–

weights_1_ij:weights from input to hidden

weights_2_ij:weights from hidden to output

biasInput: the bias from input to hidden

biasHidden: the bias from hidden to output

—————-Details———————-

Here in the training the parameters such as learning rate are assigned which is set as equal to 1/sqrt(iteration). Then each  training pattern is presented in the loop one by one in each iteration.  The maximum number of iterations is set to 5000 due to computationally  large size of the datasets which takes large time to compute per  iteration. The condition of the looping of iterations is till either the  maximum number of iterations reached or and error in values computed is  less than permissible error of 0.001. Further for each  input updated weights are computed.

  1. S1(j) = S1(j) + weights_1_ij(i,j) * x(i) ; is w1.x, the net input at jth hidden neuron
  2. S2(j) = S2(j) + weights_2_ij(i,j) * h(i) ; w2.h, the net input at the jth  output neuron
  3. delta_2_weights_2_ij(j) = O(j)*(1-O(j))*(Y(k)-O(j));   delta 2 for each output neuron
  4. sum =sum = sum + delta_2_weights_2_ij(l) * weights_2_ij(j,l) ;
  5. delta_1_weights_1_ij(j) = h(j)*(1-h(j))*sum;  delta1 for each hidden neuron 
  6. weights_1_ij(i,j)  = weights_1_ij(i,j) + eta * delta_1_weights_1_ ij(j) *x(i) ; updation in weight in input to hidden layer
  7. weights_2_ij(i,j)  = weights_2_ij(i,j) + eta * delta_2_weights_2_ij(j) * % h(i) ; updation in weight in hidden layer to output layer

iii.                TestBP

This method is for testing the backpropagation algorithm written using iterative methology (non matrix based weight updation). This is the main function that does the testing of the network . It takes the following parameters and return types are discussed. Following is the detail of the procedure:

—————parameters————–

weights_1_ij:weights from input to hidden

weights_2_ij:weights from hidden to output

biasInput: the bias from input to hidden

biasHidden: the bias from hidden to output

testingSet: the testing set as creteated by 10 fold crossvalind

testLabel: the testing labes corresponding to the testingSet

num_Hidden: The number of hidden layer neurons

num_Output: number of output layer nodes

—————Return Arguments——————–

correctlyClassified

count3: The number of misclassified class 3 elements

count8: The number of misclassified class 8 elements

unclassified: the matrix containing 5 unclassified data elements of each of the given class

v: This is a vector returning the TP, TN, FP, FN ie the confusion matrix , it also returns precision, recall, F-Value and accuracy

—————-Details———————-

In this method each pattern in the testingSet is tested for its accuracy. Here the net input in hidden layer is calculated and the activation function applied on net input and the outputs at hidden layer are evaluated. Further, the net input at the output layer is computed and activation function is applied to get the net output. The results are compared, the net output with the the expected output to evaluate the TP, FP, TN, FN, precision, recall and accuracy.

3.Evaluations and Results

The results are evaluated as explained above under the maximum number of epoch equal to 50 as it was taking long time to compute the results. The above three functions are executed and results computed. 100 hidden neurons were taken

The following are experiments conducted. Experiment results are as follows:

 Number of EpochsTPTNFPFNPrecisionRecallF-ValueAccuracy
0.1 holdout300068207140.48851.48850.4885
Average of 10 folds, for each fold10068207140.48851.48850.4885

Only these many experiments were conducted due to constraint on time it is taking to run for large number of epochs.

Once settings of  initial weights, training and testing data values are changed, it drastically changed the number of epocs required as well as accuracy increased considerably. Here are the results.

 Number of EpochsTPTNFPFNPrecisionRecallF-ValueAccuracy
Average over all  folds and 100 epocs with hundred hidden layer neurons1006794862283.74.99.8460.83

The following accuracy was obtained, but since it was taking too much  time its ten folds could not be computed. This accuracy was  computed 2 times, 350 epochs. I have attached the final weights of this accuracy with the code.  

 TPTNFPFNPrecisionRecallF-ValueAccuracy
BackPropagation with 100 hidden layer neurons682697170.9757 1.9877.9878

Code

function BackPropogation38()
disp(‘..Starting BackPropogation38 Algorithm….’);

%reading data    

A = load('mnist38All.mat');

%v=[ TP,TN,FP,FN, Precision, Recall, F-measure, accuracy] 
vtot=[0,    0,     0,     0,  0, 0,0 ,0];

data =[A.train;A.test];

 %10 folds with 10-90 ratio of testing and training
  for i = 1:10

    P=.1;        
    groups=data(:,785);
    [train,test] = crossvalind('holdout',groups, P);
    train1= data(train, 1: 785);
    test1=data(test, 1: 785);               
    num_Hidden = 100;
    num_Output = 1;  % two for binary case else 10.


    [rowtrain,coltrain]=size(train1);
    [rowtest,coltest]= size(test1);

    %initilizating weights

    trainingLabels(1:rowtrain) = train1(:,coltrain);
    trainingSet(1:rowtrain,1:coltrain-1)=0;
    trainingSet(1:rowtrain,1:coltrain-1) = 
    train1(1:rowtrain,1:coltrain-1);
    trainingLabels(1:rowtrain)= train1(1:rowtrain,coltrain);

    testSet(1:rowtest,1:coltest-1)=0;
    testLabels(1:rowtest)=test1(:,coltrain);
    testSet(1:rowtest,1:coltest-1) = test1(1:rowtest,1:coltest-1);
    testLabels(1:rowtest)= test1(1:rowtest,coltest);

    for n1=1:rowtrain
        for n2=1:coltrain-1
            if trainingSet(n1,n2) >0
            trainingSet(n1,n2)=1;
            end
        end
    end


   for n1=1:rowtest
        for n2=1:coltest-1
            if testSet(n1,n2) >0
            testSet(n1,n2)=1;
            end
        end
    end


    [weights_1_ij, weights_2_ij, biasInput, biasHidden] = trainBP(trainingSet, num_Hidden,num_Output, trainingLabels,testLabels,testSet);


    [correctlyClassified,count3,count8,unClassified,v] =    testBP(testSet,weights_1_ij, weights_2_ij,biasInput, biasHidden, testLabels, num_Hidden,num_Output);

    %v stores the output containg TP.FP etc , vtot the total of all
    %such over 10 folds
    vtot = vtot + v;

    correctlyClassified

    count3
    count8


  end
%computing average of 10 folds
vtot = vtot ./i

end

%learning rate    
eta =1;
maxEpochs=100;
errorBound=0.001;

[trainLengthRow, trainLengthCol] = size(trainingSet);
num_Input = trainLengthCol;       

Y = trainingLabels;

%assingning initial weights
weights_1_ij(1:num_Input,1:num_Hidden) = 0.01  ;
weights_2_ij(1:num_Hidden,1:num_Output) = 0.01 ;                    
biasInput(1:num_Hidden) = 0.01  ;
biasHidden(1:num_Output) = 0.01  ;

delta_1_weights_1_ij(1:num_Hidden)= 0;
delta_2_weights_2_ij(1:num_Output)= 0;

epochs =1;
error = 1;

while((epochs < maxEpochs) && (error > errorBound))

    eta=1/sqrt(epochs);
    error=0;
    epochs = epochs+1 

for k =( 1: trainLengthRow )
x = trainingSet(k,:) ;

S1(1:num_Hidden)=0;
S2(1:num_Output)=0;

    %calculating weights
    for j =(1:num_Hidden)        
        for i =(1:num_Input)
            S1(j) = S1(j) + weights_1_ij(i,j) * x(i) ;
        end;    
        S1(j) = S1(j) + biasInput(j) * 1;
    end;

    h(1:num_Hidden) = 0;

    for j =(1:num_Hidden)
    h(j)= 1/(1+exp(-1*S1(j)));
    end;


    for j =(1:num_Output)        
        for i =(1:num_Hidden)
            S2(j) = S2(j) + weights_2_ij(i,j) * h(i) ;
        end;    
        S2(j) = S2(j) + biasHidden(j) * 1;
    end;


    O(1:num_Output) = 0;
    for j =(1:num_Output)
    O(j)= 1/(1+exp(-1*S2(j)));
    end;        

    %calculating weights
    for j =(1:num_Output)
    delta_2_weights_2_ij(j) = O(j)*(1-O(j))*(Y(k)-O(j));
    end;


    for j =(1:num_Hidden)
        sum = 0;
        for l=(1:num_Output)
            sum = sum + delta_2_weights_2_ij(l) * weights_2_ij(j,l) ;
        end;
    delta_1_weights_1_ij(j) = h(j)*(1-h(j))*sum;        
    end;


    %updating weights
    %calculating new weights        
    for i =(1:num_Input)
         for j =(1:num_Hidden)                        
            weights_1_ij(i,j)  = weights_1_ij(i,j) + eta * delta_1_weights_1_ij(j) * x(i) ;
        end;    
    end;        

    %computing bias
    for j =(1:num_Output)                        
            biasHidden(j)  = biasHidden(j) +  delta_2_weights_2_ij(j) * 1 ;
    end;            


    %updating weights
    %calculating new weights
    for i =(1:num_Hidden)        
        for j =(1:num_Output)
            weights_2_ij(i,j)  = weights_2_ij(i,j) + eta * delta_2_weights_2_ij(j) * h(i) ;
        end;    
    end; 

   %computing bias
    for j =(1:num_Hidden)                        
            biasInput(j)  = biasInput(j) +  delta_1_weights_1_ij(j) * 1 ;
    end;            

% error as output approaching target
error = error + sqrt( (O(1)- Y(k)) * (O(1)- Y(k)) );

end 
if epochs % 10 == 0
save('weights.mat','weights_1_ij','weights_2_ij','biasInput','biasHidden','testLabels','testSet','trainingSet','trainingLabels');
end

end
end

function [correctlyClassified,count3,count8,unClassified,v] = testBP(testingSet,weights_1_ij, weights_2_ij,biasInput, biasHidden, testLabel, num_Hidden,num_Output)

correctlyClassified = 0;
count3 = 0; count8=0;   TP=0;    TN=0;     FP=0;     FN =0; P=0; R=0; F=0;

[testLengthRow,testLengthCol]=size(testingSet);
unClassified(1:10 ,1: testLengthCol) = 0;

% checking accuracy by  number of correctly classified

for k=(1: testLengthRow )
    x=testingSet(k,:);
    S1(1:num_Hidden)=0;
    S2(1:num_Output)=0;
    num_Input =testLengthCol;

    %calculating
    for j =(1:num_Hidden)
        for i =(1:num_Input)
            S1(j) = S1(j) + weights_1_ij(i,j) * x(i) ;
        end;
        S1(j) = S1(j) + biasInput(j) * 1;
    end;

    h(1:num_Hidden) = 0;
    for j =(1:num_Hidden)
        h(j)= 1/(1+exp(-1*S1(j)));
    end;

    for j =(1:num_Output)
        for i =(1:num_Hidden)
            S2(j) = S2(j) + weights_2_ij(i,j) * h(i) ;
        end;
        S2(j) = S2(j) + biasHidden(j) * 1;
    end;


    O(1:num_Output) = 0;
    for j =(1:num_Output)
        O(j)= 1/(1+exp(-1*S2(j)));
    end;


    %    error as output approaching target
    if sqrt( (round(O(1))- (testLabel(k))) * (round(O(1))- (testLabel(k)) )) == 0
        % correctly classified examples
        correctlyClassified=correctlyClassified+1;

        %compute  TP, TN
        if(testLabel(k)==1)
            TP = TP+1;
        else
            TN = TN +1;
        end

    else
        % wrongly classified examples
        if(testLabel(k)==1)
            FN = FN+1;
        else
            FP = FP +1;
        end
        %storing 5 misclassified  classes from each class
        if(count8<5 && testLabel(k)==0)
            count8 = count8 + 1;
            unClassified(count8,1: testLengthCol) = testingSet(k,1: testLengthCol);
        end
        if(count3<5 && testLabel(k)==1 )
            count3 = count3 + 1;
            unClassified(count3+5,1: testLengthCol) = testingSet(k,1: testLengthCol);                
        end
    end

end

  k

  %for storing 'TP,    TN,     FP,     FN,   Precision,  Recall,
  %F value , accuracy
v=[TP,    TN,     FP,     FN,     TP/(TP+FP),      TP/P,      2*P*R / (P+R) , correctlyClassified/testLengthRow]
disp('TP,    TN,     FP,     FN,     TP/(TP+FP),      TP/P,      2*P*R / (P+R) , correctlyClassified/trainLengthRow');


 unClassified;
 accuracy = correctlyClassified/testLengthRow  ;   
 accuracy

end

Backpropagation algorithm for 10 digits learning

Applying BPNN classifier on original multiclass data with the same experimental settings as in the binary case above. The results are not as high, and only upto few epocs could be performed, again due to limits on computing capacity of systems for experimentation. This is due to the fact that the complete Neural Network, initial weights have to change with the change in problem. The outputs are 10 classes represented in form of 1’s and 0’s  of ten digits combinations. Conclusion, experiments of parameters for 10 class data need to be performed.

Misclassified Images for 2 class digit recognition problem

Code was written in each of the algorithm that stores 5 misclassified samples from each class in a mat file. And a script that is in this folder to read each of the misclassified row from this mat file and convert it in a 28 x 28 matrix in image form. The script is as follows:

%This is a script that reads data which was unclassified and stored in a
%mat file and displays the image file corresponding to that data.

data = load('mat38unclassified.mat');
A = data.unClassified;
[r,c] = size(A);
%read all r data that are present in unclassified mat   file
for t=1 : r
 k=1;   
 x(1:c)=A(t,1:c);
a(1:28,1:28)=0;

%convert it back to matrix form
for i=1: 28
        for j =1: 28
            a(i,j)= x(k);
            k=k+1;
        end
end

% display each of the figure separately
figure(t); 
imshow(a);
end

The following are misclassified ones from 3 and 8 digits  backpropagation for 2 class program

Following are misclassified “3” digit.

Comparison with other ML Techniques

MethodTPTNFPFNPrecisionRecallF-ValueAccuracy
Logistic regression9369902038.9791.9610.9699.9708
Naïve Bayes9389037271.928.928.928.92

Comment:  Logistic Regression is performing the best and Naïve Bayes is also performing good.

RNN takes high amount of time to learn. So the execution time for RNN is very high.

Naïve Bayes require and extra overhead of discretizing the data. Otherwise Naïve Bayes is a fast algorithm in terms of execution time as its output is direct output that does not require iterations.

The accuracy in these experiments is execution time and system restrictions, which prevented optimization of error and hence increase in accuracy. This does not say than a particular do not perform well-it is just an experimental setup for education and learning purpose for how to go ahead with experimentations.

Weka was used for Naïve Bayes. And the settings cant be changed the true positive rate and false positive  rate is coming out to be 0.92 and 0.926 respectively. Which is upper right hand column of the ROC graph.

Naive Bayes ROC Curve: Since using Weka GUI it is not possible to create ROC curve though the TPR and FPR is given by  (.926,.92). Also see the screen shoot below for details. Only two point plots possible.

ROC for implemented Logistic Regression:

Note again: Much fewer epochs were performed on experimentations due to constraints on computing devise used. This is too less when GPUs are used. But all this is for illustrative purpose only. Also iterative approach for implementation has been used in the code implemented for illustration. Modern day approach do use matrix computations for efficiency in processing, given the advent in processors and computing facilities used for matrix computations.

Some Graphical Comparison and Results (with fitted polynomials) of Naive Bayes, Logistic Regression and Linear Regression

This article provides results, graphical plots and analysis of Linear, Logistic Regression, Naive Bayes for three kinds of datasets, namely, (i) Linearly Seperable, (ii) Non-Linearly Seperable and (iii) Banana Data. This article plays a good role for new mentors, academicians and students to understand the process of experimentations and analysis, result presentation in a Machine Learning tasks. It also plots the classifier hyperplane along with the distinct class in this 2-class problem. The results are not benchmarks, they are elaborated for experimental setups in labs, and to be followed by mentors teaching Machine Learning Lab Work. For benchmark results look into peer-reviewed research papers.

RESULTS & PLOTS

Here some results obtained after the dividing the data into 30-70 ratio of testing and training respectively. This was done for 5 folds. Finally, average was taken. This has been done for all thre classifiers who’s results are discussed below.

The following table shows results for linearly seperable data for the three classifiers (i) Linear Regression (ii) Logistic Regression and (iii) Naïve Bayes.  The results are averages over 5 folds and are comparable.

Plots of original Data

Following are the plots of given data.

Linearly Separable Data

Non Linearly Seperable Data plot

Banana Data

LS Data Results  (Note the data are averages of 5 fold data)

 TPTNFPFNPrecisionRecallF-ValueAccuracy
Linear Regression750750001111
Logistic regression749.6 750     0    0.410.9995   0.9997   0.9997
Naïve Bayes750750001111

The following table shows results for non  linearly seperable data for the three classifiers (i) Linear Regression (ii) Logistic Regression and (iii) Naïve Bayes.  The best results are with Linear and logistic regression.

NLS Data Results (Note the data are averages of 5 fold data)

 TPTNFPFNPrecisionRecallF-ValueAccuracy
Linear Regression735.5  734.8000    15.2000  14.6000   0.97970.9805   0.9801   0.9801
Logistic regression733.8733.2000  16.8000  16.2000   0.97760.9784   0.9780   0.9780
Naïve Bayes72172629240.9650.9650.8880.96

The following table shows results for banana data for the three classifiers (i) Linear Regression (ii) Logistic Regression and (iii) Naïve Bayes.  The results are averages over 5 folds and Naive Bayes gives the best results.

 TPTNFPFNPrecisionRecallF-ValueAccuracy
Linear Regession 626.4000  633.8000  122.2000  116.6000    0.8370 0.8431          0.8399          0.8407
Logistic Regression66551524078    0.74250.8950  0.8094  0.7876
Naïve Bayes66666696720.880.880.8880.88

The Surface and figures

The surfaces and figures of the discriminant are given below.

The surface for Linearly Seperable Data using linear regression

Below are the two plots of linearly separable data surface generated by linear regression. The two plots have different axis coordinates.

The surface for  Non Linearly Seperable data using linear regression

Below are the two plots of non linearly separable data surface generated by linear regression. The two plots have different axis coordinates.

The surface for Banana Data using linear regression

Below are the two plots of banana  data surface generated by linear regression. The two plots have different axis coordinates.

The Surface of LS Data uisng Logistic regression

Below are the two plots of linearly separable data surface generated by logistic regression. The two plots with different runs and different training and testing data.

The following are surface generated over two runs.

The Surface of NLS Data with Logistic Regression

Below are the two plots of non linearly separable data surface generated by logistic regression.  

The Surface of BananaData with Logistic Regression

Below are the two plots of banana data surface generated by logistic regression. The two plots with different runs and different training and testing data.

(The outputs are over two runs)

More Results: On Segmented Data

Now the samples of training sizes (500, 1000, 1500,….,4500) and {{5000}-{training-size}} as the testing size is being analyzed here. I iterate over with incrementing each time the partition(train-test ratio) percentage by  0.1% of 5000 to .2% of 5000 and so on to -9% of 5000, remaining to be for testing. This is how we will get the training size of (500, 1000, 1500, ……,4500)and testing ratio as 5000-{training-size}.

Average time over 5 such samples of each of  the given training size. Following are the experiment results of execution times. Of different algorithms and different data sets.

                                 

RESULTS

Logistic Regression

I have converted data to 1 and 0 class instead of 1 and -1 class before using logit. Following are the results of logistic regression of all the three data samples (i)Banana Data (ii) NLS Data and (iii) LS Data.

In the below table the training sizes are given and the corresponding testing sizes are 5000-{training size}

Testing Sample45004000350030002500200015001000500
Banana Data3.5992     2.7031     2.8467     2.6833    1.46481.1170   1.0087    0.6808   0.4955   
NLS Data3.5631     3.3242     3.4129     3.1384     3.3511  1.5047        1.4308   0.8716   0.5782  
LS Data0.4260     0.3063     0.1808  0.6101     0.3813  0.0842   0.2085     0.0642     0.0364

Linear Regression

Following are the results of linear regression of all the three data samples (i)Banana Data (ii) NLS Data and (iii) LS Data

Training Sample45004000350030002500200015001000500
Banana Data  000000.0633000
NLS Data  00.0989000.19000.0570000
LS Data0          0          0          0          0  0.0566        000

Naïve Bayes

To use Naïve Bayes I have used discretizer present in weka before applying Naïve Bayes. Following are the results of Nayes Bayes of all the three data samples (i)Banana Data (ii) NLS Data and (iii) LS Data.

Training Sample45004000350030002500200015001000500
Banana Data  000.020.020.02000.020
NLS Data  0000.020.020.0200.020.02
LS Data00.02000.020000.02

First Order Polynomial Fitting for NLS Data:-

I have used polyfit and polyval for this part

Each is linear in number of Samples . ie O(N).

  1. Linear Regression for degree 1 polynomial fitting with NLSData

I have computer x = x1*x1+y1*y1

And used polyfit the parameter with 1 degree polyfit are:-

-0.0237x+ 1.4974. Graph Below

With x1 I am getting the parameter with 1 degree polyfit are:-

-0.2301 x+ 1.5416. Graph below

With x2 I am getting the parameter with 1 degree polyfit are:-

  1. X+  2.0415  .
  • Logistic Regression  with degree 1 polynomial fitting for NLSData

I have computer x = x1*x1+y1*y1

And used polyfit the parameter with 1 degree polyfit are:-

 -0.0081x+ 1.2010

With x1 I am getting the parameter with 1 degree polyfit are:-

-0.1628x+ 1.4918

With x2 I am getting the parameter with 1 degree polyfit are:-

-0.1684x+ 1.4518

  • Logistic Regression  with degree 2 polynomial fitting for NLSData

x = x1*x1+y1*y1

And used polyfit the parameter with 1 degree polyfit are:-

 0+-0.0151 x+1.4139

This is almost linear

With x1 I am getting the parameter with 1 degree polyfit are:-

-0.0041x^2+-0.1254x + 1.4189

This is almost linear

With x2 I am getting the parameter with 1 degree polyfit are:-

0.0003x^2 -0.17702x+ 1.5425

This is also almost straight line

So polynomial of degree 1 fits in Logistic regression and similar results were coming for linear regression

Linear RegressionParameters of polyfit for degree 1 with x = x1*x1+y1*y1Parameters of polyfit for degree 1 with x = x1Parameters of polyfit for degree 1 with x = x2
NLS Data-0.0237x+ 1.4974-0.2301x+ 1.54161.709x+2.0415 
LS Data -0.0018x+ 1.2346-0.1477x+ 1.5013-0.1794x+1.9014
Banana Data-0.0129x+ 2.2202-0.2264x+ -1.40320.9265x+ -1.6075
Logistic RegressionParameters of polyfit for degree 1 with x = x1*x1+y1*y1Parameters of polyfit for degree 1 with x = x1Parameters of polyfit for degree 1 with x = x2
NLS Data-0.0081x+ 1.2010  -0.1628x+ 1.4918-0.1684x+1.4518  
LS Data -0.0020x+ 1.0548-0.0794x+ 1.2986-0.0785x+1.2847
Banana Data-0.0021x+ 0.85050.0438x+ 0.55580.0191x+ 0.5530

Newtons Logistic Regression

The following are results obtained using the logistic regression using Newton’s method  classifier. I have split the datasets into 70% training and 30% testing randomly in 5 folds. Below are the details of how we choose these 5 folds.

Here the first weight represent the bias

    sum = sum + W_Old(j+1)*trainingSet(t,j);           

    P(t) = 1/(1+ exp(-1*sum));                          

    Z= (X’) * (Y-P)’;

    W = diag(P.* (1-P));

    Hessian =  X’ * W * X;

    etaMatrix(1:3) = eta;

    W_New = W_Old + etaMatrix .* (Hessian \ Z)’  ;

Its derivation and complete form in two ways is given as:

    Parameters used for computations:

    Maximum Number of  numIteration =10000;

    eta = 0.5 and 0.2;  // both tested         

    errorBound = 0.0001;

The following are the final weights for the three data:-

 W0W1W2
 LS Data 8.4137 -0.4298 -0.4125
NLS Data26.2879-2.2458-2.1134
Banana Data0.64950.3533-0.1829

The following are the TP, TN , FP, FN, Precision, recall, accuracy  for the three data:

 TPTNFPFNPrecisionRecallF-ValueAccuracy
 LS Data750750001111
NLS Data737.6732.817.212.40.97720.98350.98350.9803
Banana Data630.6647.4108.6112.40.85310.84870.85090.8526

The Decision Boundaries of the three data sets are as follows:-

The following are the figues showing (i) the decision surface and (ii) decision surface and dat both. Note different colored are used to show different classes.

  1. Linearly Seperable  Data(Green is with + sign the positive and blue with –ve)

This following figure is for the plane of the Newtons method for linearly seperable data. Red dots shows the predicted line projected in 2D

This following  figure is for data for linearly separable data. 

This  following figure is for the plane of the Newtons method for linearly seperable data plotted in 3D

  1. NLS Data   (Green is with + sign the positive and blue with –ve)

This  following figure is for the data  for non linearly seperable data.

This  following figure is of the Newtons method for NLS seperable data. Red dots shows the predicted line projected in 2D.

This  figure is for the plane of the Newtons method for non linearly seperable data over two runs.

  1. Banana Data

This following  figure is for the separating plane of the Newtons method for banana data.

This  following figure is for the plane of the Newtons method for banana data projected to 2D.

This  figure is for the plane of the Newtons method for banana data. Red dots shows the predicted line projected in 2D

The results are self explanatory with the help of image data and are not benchmarks, they are elaborated for experimental setups in labs, and to be followed by mentors teaching Machine Learning Lab Work. For benchmark results look into peer-reviewed research papers.

Logistic Regression Matlab Code-Iterative

% this is for two class problem for more than two class code changes

% % this is for two class problem for more than two class code changes
% % ————-Parameters————-
% numIteration =1000; The Number of maximum iterations
% % errorBound = 0.0001; This is the permissible error.
% The experiments have been done keep in view both the error condition
% reached or maximum iteration reached whichever comes first.
% % eta = 0.5; This is the learning rate, experiments have been
% done on various learning rates

function logisticRegression2Class()
disp(‘..Starting logistic regression Algorithm….’);

%reading the data

A = load('BananaData.mat');
data = A.data;    
[N,col]= size(data);

vtot=[0, 0, 0, 0,0, 0,  0 , 0];

%5 folds with 70-30 ratio

for i = 1:5

    P=.3;
    groups=data(:,3);
    [train,test] = crossvalind('holdout',groups, P);
    train1= data(train, 1: 3);
    test1=data(test, 1:3);
    [trainLengthRow, trainLengthCol]=size(train1);
    [rowtest,coltest]= size(test1);

    trainingSet = train1(1:trainLengthRow, 1 : trainLengthCol -1 );
    trainingLabels = train1(1:trainLengthRow, trainLengthCol );

    testSet = test1(1:rowtest, 1 : coltest -1 );
    testLabels = test1(1:rowtest, coltest );

%initilizating weights
weights(1:trainLengthCol) = 0;
weight0=0;

[weight0, weights] = trainLogReg(weight0, weights, trainingSet,trainingLabels);

[correctlyClassified,count0,count1,unClassified,v] = testLogReg(testSet,testLabels, weight0, weights)
vtot = vtot +v ;
end

disp(‘TP, TN, FP, FN, TP/(TP+FP), TP/P, 2PR / (P+R) , correctlyClassified/trainLengthRow’);
vtot = vtot ./ 5

end

%This mathod is for tarining the logestic regression problem
% —–Parameters—-
%trainingSet: the training set
%trainingLabels: the labels corresponding to the traiining set
%weights: the initial weights obtained from traiining
%weight0: The initial bias weight
%—–Return Types——
%weights: the final weights obtained from traiining
%weight0: The bias weight
%
function [weight0, weights] = trainLogReg(weight0, weights, trainingSet,trainingLabels)

numIteration =100000;
eta = 0.5;            
errorBound = 0.0001;
error =1.0;
[trainLengthRow, trainLengthCol] = size(trainingSet); 
del_l_by_del_w_i(1:trainLengthCol) = 0;
weightsFinal(1:trainLengthCol) = 0;
k=0
while ((k < numIteration) && (error > errorBound))        
    error=0.0;
for i=1:trainLengthCol
    Y1_X = 0;
    del_l_by_del_w_i(i) = 0;                
    del_l_by_del_w_0 = 0;

    for t=1: trainLengthRow        
        sum = weight0;

        for j=1: trainLengthCol
        sum = sum +  weights(j)*trainingSet(t,j);
        end;

        Y1_X = 1/(1+ exp(-1*sum));

        del_l_by_del_w_i(i) = del_l_by_del_w_i(i) + trainingSet(t,i) *(trainingLabels(t) - Y1_X ) ;        
        del_l_by_del_w_0 = del_l_by_del_w_0 + 1 *(trainingLabels(t) - Y1_X ) ;        
    end;        

end;

for i=1:trainLengthCol
weightsFinal(i)= weights(i) + eta *  del_l_by_del_w_i(i);  
error = error + (weightsFinal(i)-weights(i))*(weightsFinal(i)-weights(i));
end;

weight0new = weight0 +    eta *  del_l_by_del_w_0;
error = error + (weight0new-weight0)*(weight0new-weight0);
error=sqrt(error);
weights=weightsFinal;
weight0 = weight0new;
k=k+1;
end

k
%Now computing the final y using the final weights

y1(1:trainLengthRow)=0;
y0(1:trainLengthRow)=0;

for i =1: trainLengthRow

    sum = weight0;

    for j=1: trainLengthCol
    sum = sum +  weightsFinal(j)*trainingSet(i,j);
    end;

    y1(i) = 1/(1+ exp(-1*sum));
    y0(i) = 1/(1+ exp(sum));

 end;

% Following is the code for plotting the data
% data(1:trainLengthRow, 1:trainLengthCol+1)=0;
% data(1:trainLengthRow, 1:trainLengthCol)= trainingSet;
% for p=1:trainLengthRow
% data(p, trainLengthCol+1)= y1(p);
% end;
%
% %figure
% % parallelcoords(data,’Labels’,labels);
%
% for p=1:trainLengthRow
% x1(p)= trainingSet(p,1);
% end;
%
% for p=1:trainLengthRow
% x2(p)= trainingSet(p,2);
% end;
%
%
% for p=1:trainLengthRow
% yOrginal(p)= trainingLabels(p);
% end;
%
%
% size(x1)
% size(x2)
% size(trainingLabels)
%
% figure
% scatter3(x1,x2,trainingLabels,10);
% axis([-10,10,-10,10,-10,10])
%
% figure
% plot3(x1,x2,y1);
% axis([-10,10,-10,10,-10,10])
%
%
% xx=[-10:1:10];
% yy=[-10:1:10];
% [xx1,yy1]=meshgrid(xx,yy);
%
% sum = -1 .* (weight0+weightsFinal(1).xx1+weightsFinal(2).yy1);
% zz= 1 ./(1 + expm(sum));
% figure
% surf(xx1,yy1,zz);
% title(‘title’);
% xlabel(‘x’);
% ylabel(‘y’)
% zlabel(‘z’);

end

%This is the method that is called to test the accuracy of the methods
%———————–Parameters————————–
%testSet: the set of samples to be considered for testing
%testLabels: the labels corresponding to testset
%weight0, weight: the weights corresponding to logistic regression
%———————–Return Values————————
%correctlyClassified: The number of correctly classified samples
%unClassified: The array containing 5 unclassified data samples from each
%classification type
%v: The vecor that returns the computed values of TP;TN; FP; FN ,P; R; F, accuracy
function [correctlyClassified,count0,count1,unClassified,v] = testLogReg(testSet,testLabels, weight0, weights)

correctlyClassified = 0;
count0 = 0; count1=0;   TP=0;    TN=0;     FP=0;     FN =0; P=0; R=0; F=0;

[testLengthRow,testLengthCol]=size(testSet);
unClassified(1:10 ,1: testLengthCol) = 0;

% checking accuracy by  number of correctly classified   

for k=(1: testLengthRow )
    x=[1, testSet(k,1:testLengthCol)];
    w =[weight0,weights];
    O1=    x' .* w' ;

    %computing the value of vector with plane
    sum =0;
    for p=1:length(O1)
        sum = sum +O1(p);
    end

     y1x = 1/(1+ exp(-1*sum));
     if(y1x>=0.5)
         %disp('class 1');
         O =1;
     else
         %disp('class 0');
         O =-1;
     end

     %    error as output approaching target
    if (O == testLabels(k))
        % correctly classified examples
        correctlyClassified=correctlyClassified+1;

        %compute  TP, TN
        if(testLabels(k)==1)
            TP = TP+1;
        else
            TN = TN +1;
        end

    else
        % wrongly classified examples
        if(testLabels(k)==1)
            FN = FN+1;
        else
            FP = FP +1;
        end
        %storing 5 misclassified  classes from each class
        if(count1<5 && testLabels(k)==1)
            count1 = count1 + 1;
            unClassified(count1,1: testLengthCol) = testSet(k,1: testLengthCol);
        end
        if(count0<5 && testLabels(k)==-1 )
            count0 = count0 + 1;
            unClassified(count0,1: testLengthCol) = testSet(k,1: testLengthCol);                
        end
    end

end

  k
P= TP/(TP+FP)
R=  TP/(TP+FN)
v=[TP,    TN,     FP,     FN,     P,     R,      2*P*R / (P+R) , correctlyClassified/testLengthRow]
disp('TP,    TN,     FP,     FN,     TP/(TP+FP),      TP/P,      2*P*R / (P+R) , correctlyClassified/trainLengthRow');


 unClassified;
 accuracy = correctlyClassified/testLengthRow  ;   
 accuracy

end

Glimpse of Regression Codes in Matlab

Preprocessing: I have created three .mat files from the given input in form of a text file. I first imported it in xls and then copied it to .mat files.

NOTE: The derivation for linear and logistic regression is added at the end of the document.

Linear Regression Classifier

I  have split the datasets into 70% training and 30% testing randomly in 5 folds. I have used matlab method crossvalind to create 70-30 ratio of training and testing and did this 5 times. Finally I calculated the average over the five runs.

Brief discussion about Linear Regression Classifier

Now the details of form I have used for linear classifier are as follows:-

    Y=trainingLabels

    X(1:trainLengthRow, 1)= 1;

    X(1:trainLengthRow, 2:trainLengthCol+1) = trainingSet;

    Z= X’* X;

    weights = (inv(Z)) *(X’ * Y);

Here the first weight represent the bias.

Code Decription

The code for classification using linear regression is written in Matlab. Here I am creating 5 folds randomly  with 70-30 ratio of training to testing.

Methods in code are as follows:-

  The processing starts by reading the data from mat file and creating  5 folds    . in 70-30 ratio for training and testing.

  1. train1LinearReg

Method to do train the Linear Regression Model

——-Parameter’s————

trainingSet: The training set

trainingLabels: The traingin labels corresponding to training Set

————Return Type——————-

weights: weights computed by linear regression as explained above

  • testLinearReg

This function tests the test set with testlabels and the computed outputs

———–paramaters———–

testSet: The Test Set for testing

testLables: Corresponding test labels

weights: weights computed from the training

—————Return—————–

correctlyClassified: correctly classified number of samples

unClassified: 10 unclassified samples

v: vector that stores  TP ;TN;FP; FN ; P; R; F; Accuracy

count0: Number of class -1 unclassified upto max val of 5

count1: Number of class +1 unclassified upto max val of 5

Logistic Regression

The data are trained for logistic regression with following standard parameters:-

     Maximum number of numIteration =1000;

     eta = 0.5;           

     errorBound = 0.0001;

I tested over various values of eta. The following are results with eta value of 0.5.

Also I have written two codes for logistic regression one using the expanded approach and another using the shortned matrix manipulations. Results are similar for both the codes. Code is for two class problem. Here is brief description of both:-

The matrix version is as follows:-

         P(1:trainLengthRow) = 0;

    Y =  trainingLabels’;

    X(1:trainLengthRow , 1:trainLengthCol+1) = 0;

    X(1:trainLengthRow ,1) = 1;

    X(1:trainLengthRow ,2:trainLengthCol+1) =   trainingSet(1:trainLengthRow,    .    .       .                                                                       1:trainLengthCol); 

           sum = sum + W_Old(j+1)*trainingSet(t,j);

           P(t) = 1/(1+ exp(-1*sum( over values) )

    Z= (X’) * (Y-P)’;

    %computing the new weights

    W_New = W_Old + eta * Z’;

 

Code Details

The code settings are as described in the previous code details for linear regression. The ratio is 70-30 for training and I have used crossvalind with holdout parameter  of .3 for 30% testing and 70 % training data and then I have taken 5 folds of it. Following are the methods for training and testing the logistic regression.

Both the code that I have implemented have the same method interface with a slight difference of how weights are stored . The formulas are given above and in Appendix.

Method  TrainLogRegr:-

This mathod is for tarining the logestic regression problem

 —–Parameters—-

trainingSet: the training set

trainingLabels: the labels corresponding to the traiining set

weights: the initial weights obtained from traiining

weight0: The initial bias weight

—–Return Types——

weights: the final weights obtained from traiining

weight0: The bias weight

Method  TestLogRegr:-

This is the method that is called to test the accuracy of the methods

———————–Parameters————————–

testSet: the set of samples to be considered for testing

testLabels: the labels corresponding to testset

weight0, weight: the weights corresponding to logistic regression

———————–Return Values————————

correctlyClassified: The number of correctly classified samples

unClassified: The array containing 5 unclassified data samples from each

classification type

v: The vecor that returns the computed values of  TP;TN; FP; FN ,P; R; F, accuracy

Matlab code for Newtons optimization for Logistic Regression

% % this is for two class problem for more than two class code changes
% % ————-Parameters————-
% numIteration =1000; The Number of maximum iterations
% % errorBound = 0.0001; This is the permissible error.
% The experiments have been done keep in view both the error condition
% reached or maximum iteration reached whichever comes first.
% % eta = 0.5; This is the learning rate, experiments have been
% done on various learning rates
% % ————-Parameters————-
% %

function logit_Newton_1()
disp(‘..Starting logistic regression Algorithm….’);

%reading data

A = load('BananaData.mat');
data = A.data;    
[N,col]= size(data);

vtot=[0, 0, 0, 0,0, 0,  0 , 0];

%5 folds with 70-30 ratio
for i = 1:5

    P=.3;
    groups=data(:,3);
    [train,test] = crossvalind('holdout',groups, P);
    train1= data(train, 1: 3);
    test1=data(test, 1:3);
    [trainLengthRow, trainLengthCol]=size(train1);
    [rowtest,coltest]= size(test1);

    trainingSet = train1(1:trainLengthRow, 1 : trainLengthCol -1 );
    trainingLabels = train1(1:trainLengthRow, trainLengthCol );

    %converting data to 1 and 0 class instead of 1 and -1 class as
    %using logit
    for p=1:trainLengthRow
        if trainingLabels(p)== -1
            trainingLabels(p) = 0;
        end
    end


    testSet = test1(1:rowtest, 1 : coltest -1 );
    testLabels = test1(1:rowtest, coltest );

    %converting data to 1 and 0 class instead of 1 and -1 class as
    %using logit        
    for p=1:rowtest
        if testLabels(p)== -1
            testLabels(p) = 0;
        end
    end

[weights] = trainLogReg( trainingSet,trainingLabels);

[correctlyClassified,count0,count1,unClassified,v] = testNewton(testSet,testLabels, weights) ;
vtot = vtot +v ;
end

% taking average of all such entries
disp(‘TP, TN, FP, FN, TP/(TP+FP), TP/P, 2PR / (P+R) , correctlyClassified/trainLengthRow’);
vtot = vtot ./ 5

end

function [weights] = trainLogReg( trainingSet,trainingLabels)

numIteration =1000;
eta = 0.5;            
errorBound = 0.0001;

[trainLengthRow, trainLengthCol] = size(trainingSet); 
errorVec=ones(trainLengthCol+1);

weightsFinal = zeros(trainLengthCol+1);

W_Old(1:trainLengthCol+1) = 0;
W_New(1:trainLengthCol+1) = 0;

P(1:trainLengthRow) = 0;
Y =  trainingLabels';
X(1:trainLengthRow , 1:trainLengthCol+1) = 0;
X(1:trainLengthRow ,1) = 1;
X(1:trainLengthRow ,2:trainLengthCol+1) = trainingSet(1:trainLengthRow,1:trainLengthCol);

error=1.0;
k=1;

while ((error >= errorBound ) && (k < numIteration))
error=0;
    for t=1: trainLengthRow
        sum = W_Old(1);

        for j=1: trainLengthCol
        sum = sum + W_Old(j+1)*trainingSet(t,j);
        end;

        P(t) = 1/(1+ exp(-1*sum));

    end;


Z= (X') * (Y-P)';
W = diag(P.* (1-P));
Hessian =  X' * W * X;
etaMatrix(1:3) = eta;
W_New = W_Old + etaMatrix .* (Hessian \ Z)'  ;

% errorVec = 0.5* (Y’-XW_New’).(Y’-X*W_New’);
%
% for i = 1: trainLengthCol+1
% error=error+errorVec(i);
% end

error= 0;
W_New  
k
error


k=k+1;
W_Old = W_New;

y1(1:trainLengthRow)=0;    

for i =1: trainLengthRow

    sum = W_Old(1);

    for j=1: trainLengthCol
    sum = sum +  W_Old(j+1)*trainingSet(i,j);
    end;

    y1(i) = 1/(1+ exp(-1*sum));                
    error = 0.5 * (y1(i) -Y(i) ) * (y1(i) - Y(i) );
 end;

error
end

weights = W_Old;

%Now computing the final y using the final weights
 disp('final weights :  number of iterations : error');
 W_Old
 k
 error



%The following is for figure generation
%Now computing the final y using the final weights
 disp('final weights :  number of iterations : error');
 W_Old
 k
 error

y1(1:trainLengthRow)=0;
y0(1:trainLengthRow)=0;

for i =1: trainLengthRow

    sum = W_Old(1);

    for j=1: trainLengthCol
    sum = sum +  W_Old(j+1)*trainingSet(i,j);
    end;

    y1(i) = 1/(1+ exp(-1*sum));
    y0(i) = 1/(1+ exp(sum));

 end;

 data(1:trainLengthRow, 1:trainLengthCol+1)=0;
 data(1:trainLengthRow, 1:trainLengthCol)= trainingSet;
 for p=1:trainLengthRow
   data(p, trainLengthCol+1)= y1(p);
 end;

 %figure
% parallelcoords(data,'Labels',labels);

 for p=1:trainLengthRow
   x1(p)= trainingSet(p,1);
 end;

 for p=1:trainLengthRow
   x2(p)= trainingSet(p,2);
 end;


 for p=1:trainLengthRow
   yOrginal(p)= trainingLabels(p);
 end;

%
% figure(1)
% hold on;
% scatter3(x1,x2,trainingLabels,10,’g’);
% axis([-5,5,-5,5,-5,5])

 %figure(1)     
 %plot3(x1,x2,y1); 
 %axis([-5,5,-5,5,-5,5])

 figure(1)     
 hold on;     
 uniqueClasses=unique(trainingLabels)
 positive = uniqueClasses(1);
 index=find(trainingLabels==positive);
  plot3(x1(index),x2(index),trainingLabels(index), ['r','o'],'MarkerFaceColor','r')
 negative = uniqueClasses(2);
 index2=find(trainingLabels==negative);
 plot3(x1(index2),x2(index2),trainingLabels(index2), ['g','o'],'MarkerFaceColor','g')


 xx=(-10:1:10);
 yy=(-10:1:10);
 [xx1,yy1]=meshgrid(xx,yy);

 sum1 = -1 .* (W_Old(1)+W_Old(2).*xx1+W_Old(3).*yy1);

 zz= 1 ./(1 + expm(sum1));     
 [p1,m1]=size(zz);

 for p=1: p1
     for m=1:m1
              expVal = exp(sum1(p,m));
             zz(p,m) = 1 / (1+ expVal);
            end
     end
 end


 figure(2)
 surf(xx1,yy1,zz);
 title('title');
 xlabel('x');
 ylabel('y')
 zlabel('z');

end

function [correctlyClassified,count0,count1,unClassified,v] = testNewton(testSet,testLabels, weights)

correctlyClassified = 0;
count0 = 0; count1=0;   TP=0;    TN=0;     FP=0;     FN =0; P=0; R=0; F=0;

[testLengthRow,testLengthCol]=size(testSet);
unClassified(1:10 ,1: testLengthCol) = 0;

% checking accuracy by  number of correctly classified   

for k=(1: testLengthRow )
    x=[1, testSet(k,1:testLengthCol)];
    O1=    x' .* weights' ;

    %computing the value of vector with plane
    sum =0;
    for p=1:length(O1)
        sum = sum +O1(p);
    end

     y1x = 1/(1+ exp(-1*sum));
     if(y1x>=0.5)
         %disp('class 1');
         O =1;
     else
         %disp('class 0');
         O =0;
     end

     %    error as output approaching target
    if (O == testLabels(k))
        % correctly classified examples
        correctlyClassified=correctlyClassified+1;

        %compute  TP, TN
        if(testLabels(k)==1)
            TP = TP+1;
        else
            TN = TN +1;
        end

    else
        % wrongly classified examples
        if(testLabels(k)==1)
            FN = FN+1;
        else
            FP = FP +1;
        end
        %storing 5 misclassified  classes from each class
        if(count1<5 && testLabels(k)==1)
            count1 = count1 + 1;
            unClassified(count1,1: testLengthCol) = testSet(k,1: testLengthCol);
        end
        if(count0<5 && testLabels(k)==0 )
            count0 = count0 + 1;
            unClassified(count0,1: testLengthCol) = testSet(k,1: testLengthCol);                
        end
    end

end

  k
P= TP/(TP+FP)
R=  TP/(TP+FN)
v=[TP,    TN,     FP,     FN,     P,     R,      2*P*R / (P+R) , correctlyClassified/testLengthRow]
disp('TP,    TN,     FP,     FN,     TP/(TP+FP),      TP/P,      2*P*R / (P+R) , correctlyClassified/trainLengthRow');


 unClassified;
 accuracy = correctlyClassified/testLengthRow  ;   
 accuracy

end

Matlab Code for Logistic Regression

% % this is for two class problem for more than two class code changes
% % ————-Parameters————-
% numIteration =1000; The Number of maximum iterations
% % errorBound = 0.0001; This is the permissible error.
% The experiments have been done keep in view both the error condition
% reached or maximum iteration reached whichever comes first.
% % eta = 0.5; This is the learning rate, experiments have been
% done on various learning rates

% I have written two codes for logistic regression one using matrices other
% using array indexes.

function logisticRegression_Matrix_LSData()
disp(‘..Starting logistic regression Algorithm….’);

%reading data

A = load('BananaData.mat');
data = A.data;    
[N,col]= size(data);

vtot=[0, 0, 0, 0,0, 0,  0 , 0];

%5 folds with 70-30 ratio
for i = 1:5

    P=.3;
    groups=data(:,3);
    [train,test] = crossvalind('holdout',groups, P);
    train1= data(train, 1: 3);
    test1=data(test, 1:3);
    [trainLengthRow, trainLengthCol]=size(train1);
    [rowtest,coltest]= size(test1);

    trainingSet = train1(1:trainLengthRow, 1 : trainLengthCol -1 );
    trainingLabels = train1(1:trainLengthRow, trainLengthCol );

    %converting data to 1 and 0 class instead of 1 and -1 class as
    %using logit
    for p=1:trainLengthRow
        if trainingLabels(p)== -1
            trainingLabels(p) = 0;
        end
    end


    testSet = test1(1:rowtest, 1 : coltest -1 );
    testLabels = test1(1:rowtest, coltest );

    %converting data to 1 and 0 class instead of 1 and -1 class as
    %using logit        
    for p=1:rowtest
        if testLabels(p)== -1
            testLabels(p) = 0;
        end
    end

[weights] = trainLogReg( trainingSet,trainingLabels);

[correctlyClassified,count0,count1,unClassified,v] = testLogReg(testSet,testLabels, weights) ;
vtot = vtot +v ;
end

% taking average of all such entries
disp(‘TP, TN, FP, FN, TP/(TP+FP), TP/P, 2PR / (P+R) , correctlyClassified/trainLengthRow’);
vtot = vtot ./ 5

end

%This mathod is for tarining the logestic regression problem
% —–Parameters—-
%trainingSet: the training set
%trainingLabels: the labels corresponding to the traiining set
%—–Return Types——
%weights: the final weights obtained from traiining
%
function [weights] = trainLogReg( trainingSet,trainingLabels)

numIteration =1000;
eta = 0.5;            
errorBound = 0.0001;

[trainLengthRow, trainLengthCol] = size(trainingSet); 
errorVec=ones(trainLengthCol+1);

weightsFinal = zeros(trainLengthCol+1);

W_Old(1:trainLengthCol+1) = 0;
W_New(1:trainLengthCol+1) = 0;

P(1:trainLengthRow) = 0;
Y =  trainingLabels';
X(1:trainLengthRow , 1:trainLengthCol+1) = 0;
X(1:trainLengthRow ,1) = 1;
X(1:trainLengthRow ,2:trainLengthCol+1) = trainingSet(1:trainLengthRow,1:trainLengthCol);

error=1.0;
k=1;

while ((error >= errorBound ) && (k < numIteration))
error=0;
    for t=1: trainLengthRow
        sum = W_Old(1);

        for j=1: trainLengthCol
        sum = sum + W_Old(j+1)*trainingSet(t,j);
        end;

        P(t) = 1/(1+ exp(-1*sum));

    end;


Z= (X') * (Y-P)';

%computing the new weights
W_New = W_Old + eta * Z';

W_New  ;

errorVec =   (W_New - W_Old).*(W_New - W_Old)

for i = 1: trainLengthCol+1
error=error+errorVec(i); 
end

error= sqrt(error);

k=k+1;
W_Old = W_New;

end

%Now computing the final y using the final weights
 disp('final weights :  number of iterations : error');
 W_Old
 k
 error

y1(1:trainLengthRow)=0;
y0(1:trainLengthRow)=0;

for i =1: trainLengthRow

    sum = W_Old(1);

    for j=1: trainLengthCol
    sum = sum +  W_Old(j+1)*trainingSet(i,j);
    end;

    y1(i) = 1/(1+ exp(-1*sum));
    y0(i) = 1/(1+ exp(sum));

 end;

 data(1:trainLengthRow, 1:trainLengthCol+1)=0;
 data(1:trainLengthRow, 1:trainLengthCol)= trainingSet;
 for p=1:trainLengthRow
   data(p, trainLengthCol+1)= y1(p);
 end;

 labels={'x1','x2','y'}; 

 %figure
% parallelcoords(data,'Labels',labels);

 for p=1:trainLengthRow
   x1(p)= trainingSet(p,1);
 end;

 for p=1:trainLengthRow
   x2(p)= trainingSet(p,2);
 end;


 for p=1:trainLengthRow
   yOrginal(p)= trainingLabels(p);
 end;


 figure(1)     
 scatter3(x1,x2,trainingLabels,10);     
 axis([-5,5,-5,5,-5,5])

 figure(1)     
 plot3(x1,x2,y1); 
 axis([-5,5,-5,5,-5,5])


 xx=(-10:1:10);
 yy=(-10:1:10);
 [xx1,yy1]=meshgrid(xx,yy);

 sum1 = -1 .* (W_Old(1)+W_Old(2).*xx1+W_Old(3).*yy1);

 zz= 1 ./(1 + expm(sum1));     
 [p1,m1]=size(zz);

 for p=1: p1
     for m=1:m1
             % if (zz(p,m)== NaN)
             % zz(p,m) = 1; % as we are using logit function
             expVal = exp(sum1(p,m));
             zz(p,m) = 1 / (1+ expVal);
        % end
     end
 end


 figure(1)
 surf(xx1,yy1,zz);
 title('title');
 xlabel('x');
 ylabel('y')
 zlabel('z');

 weights =W_Old;

end

function [correctlyClassified,count0,count1,unClassified,v] = testLogReg(testSet,testLabels, weights)

correctlyClassified = 0;
count0 = 0; count1=0;   TP=0;    TN=0;     FP=0;     FN =0; P=0; R=0; F=0;

[testLengthRow,testLengthCol]=size(testSet);
unClassified(1:10 ,1: testLengthCol) = 0;

% checking accuracy by  number of correctly classified   

for k=(1: testLengthRow )
    x=[1, testSet(k,1:testLengthCol)];
    O1=    x' .* weights' ;

    %computing the value of vector with plane
    sum =0;
    for p=1:length(O1)
        sum = sum +O1(p);
    end

     y1x = 1/(1+ exp(-1*sum));
     if(y1x>=0.5)
         %disp('class 1');
         O =1;
     else
         %disp('class 0');
         O =0;
     end

     %    error as output approaching target
    if (O == testLabels(k))
        % correctly classified examples
        correctlyClassified=correctlyClassified+1;

        %compute  TP, TN
        if(testLabels(k)==1)
            TP = TP+1;
        else
            TN = TN +1;
        end

    else
        % wrongly classified examples
        if(testLabels(k)==1)
            FN = FN+1;
        else
            FP = FP +1;
        end
        %storing 5 misclassified  classes from each class
        if(count1<5 && testLabels(k)==1)
            count1 = count1 + 1;
            unClassified(count1,1: testLengthCol) = testSet(k,1: testLengthCol);
        end
        if(count0<5 && testLabels(k)==0 )
            count0 = count0 + 1;
            unClassified(count0,1: testLengthCol) = testSet(k,1: testLengthCol);                
        end
    end

end

  k
P= TP/(TP+FP)
R=  TP/(TP+FN)
v=[TP,    TN,     FP,     FN,     P,     R,      2*P*R / (P+R) , correctlyClassified/testLengthRow]
disp('TP,    TN,     FP,     FN,     TP/(TP+FP),      TP/P,      2*P*R / (P+R) , correctlyClassified/trainLengthRow');


 unClassified;
 accuracy = correctlyClassified/testLengthRow  ;   
 accuracy

end

Matlab Linear Regression Sample Code

Three type of datasets have been analyzed for this technique:

(1) Linearly separable data(LS)

(2) Inseparable data(NLS)

(3) Banana data (BD)

For a binary classification problem. Split the datasets into 70% training and 30% testing randomly in five folds. This is a old code done as a part of an assignment. Compatibility with newer versions may happen.

% This is for binary class problem, where we are fitting in k dimension.

%This is the code for classification using linear regression.

function linearRegression_LSData()
disp(‘..Starting linear regression Algorithm….’);

%reading data

A = load('BananaData.mat');
data = A.data;    
[N,col]= size(data);

vtot=[0, 0, 0, 0,0, 0,  0 , 0];

%5 folds with 70-30 ratio

for i = 1:5

    P=.3;
    groups=data(:,3);
    [train,test] = crossvalind('holdout',groups, P);
    train1= data(train, 1: 3);
    test1=data(test, 1:3);
    [trainLengthRow, trainLengthCol]=size(train1);
    [rowtest,coltest]= size(test1);

    trainingSet = train1(1:trainLengthRow, 1 : trainLengthCol -1 );
    trainingLabels = train1(1:trainLengthRow, trainLengthCol );

    testSet = test1(1:rowtest, 1 : coltest -1 );
    testLabels = test1(1:rowtest, coltest );


    disp('training length');
    disp(trainLengthCol);
    disp(trainLengthRow);
    disp(rowtest);
    disp(coltest);       

    weights(1:trainLengthCol)=0;
    [weights] = train1LinearReg(trainingSet,trainingLabels);
    disp(weights);

    [correctlyClassified,count0,count1,unClassified,v] =  testLinearReg(testSet,testLabels, weights);
    vtot = vtot +v ;

end
disp(‘TP, TN, FP, FN, TP/(TP+FP), TP/P, 2PR / (P+R) , correctlyClassified/trainLengthRow’);
%taking average of all quantaties of TP, TN, FP, FN etc.
vtot = vtot ./ 5
end

%Method to do train the Linear Regression Model
%——-Paramaeters————
%trainingSet: The training set
%trainingLabels: The traingin labels corresponding to training Set
%————Return Type——————-
%weights: weights computed by linear regression
function [weights] = train1LinearReg(trainingSet,trainingLabels)

[trainLengthRow, trainLengthCol] = size(trainingSet);
weights(1:trainLengthCol+1)=0;
Y=trainingLabels;
X(1:trainLengthRow, 1:trainLengthCol+1) = 0;
X(1:trainLengthRow, 1)= 1;
X(1:trainLengthRow, 2:trainLengthCol+1) = trainingSet;
disp(X);
disp(Y);
Z= X'* X;
weights = (inv(Z)) *(X' * Y);    


%the following is for display of plots and surfaces 
y1=weights' * X';

%Plotting the regression line
 for p=1:trainLengthRow
   x1(p)= trainingSet(p,1);
 end;

 for p=1:trainLengthRow
   x2(p)= trainingSet(p,2);
 end;


 for p=1:trainLengthRow
   yOrginal(p)= trainingLabels(p);
 end;

     k=5;

 figure     
 scatter3(x1,x2,trainingLabels,10);     
 axis([-1*k,k,-1*k,k,-1*k,k])

 figure     
 plot3(x1,x2,y1); 
 axis([-1*k,k,-1*k,k,-1*k,k])


 xx=(-1*k:1:k);
 yy=(-1*k:1:k);
 [xx1,yy1]=meshgrid(xx,yy);

 %drawing the surface
 sum = -1 .* (weights(1)+weights(2).*xx1+weights(3).*yy1);
 zz= 1 ./(1 + expm(sum));     
 figure
 surf(xx1,yy1,zz);
 title('Surface');
 xlabel('x');
 ylabel('y')
 zlabel('z');

end

%This function tests the test set with testlabels and the computed outputs
%———–paramaters———–
%testSet: The Test Set for testing
%testLables: Corresponding test labels
%weights: weights computed from the training
%—————Return—————–
% correctlyClassified: correctly classified number of samples
% unClassified: 10 unclassified samples
%v: vector that stores TP ;TN;FP; FN ; P; R; F; Accuracy
%count0: Number of class -1 unclassified upto max val of 5
%count1: Number of class +1 unclassified upto max val of 5
function [correctlyClassified,count0,count1,unClassified,v] = testLinearReg(testSet,testLabels, weights)

correctlyClassified = 0;
count0 = 0; count1=0;   TP=0;    TN=0;     FP=0;     FN =0; P=0; R=0; F=0;

[testLengthRow,testLengthCol]=size(testSet);
unClassified(1:10 ,1: testLengthCol) = 0;

% checking accuracy by  number of correctly classified   

for k=(1: testLengthRow )
    x=[1, testSet(k,1:testLengthCol)];
    O1=    x' .* weights ;

    %computing the value of vector with plane
    sum =0;
    for p=1:length(O1)
        sum = sum +O1(p);
    end

    % setting the outputs
    if(sum > 0)
        O=1;
    else 
        O=-1;
    end


     %    error as output approaching target
    if (O == testLabels(k))
        % correctly classified examples
        correctlyClassified=correctlyClassified+1;

        %compute  TP, TN
        if(testLabels(k)==1)
            TP = TP+1;
        else
            TN = TN +1;
        end

    else
        % wrongly classified examples
        if(testLabels(k)==1)
            FN = FN+1;
        else
            FP = FP +1;
        end
        %storing 5 misclassified  classes from each class
        if(count1<5 && testLabels(k)==1)
            count1 = count1 + 1;
            unClassified(count1,1: testLengthCol) = testSet(k,1: testLengthCol);
        end
        if(count0<5 && testLabels(k)==-1 )
            count0 = count0 + 1;
            unClassified(count0,1: testLengthCol) = testSet(k,1: testLengthCol);                
        end
    end

end

  k
P= TP/(TP+FP)
R=  TP/(TP+FN)
v=[TP,    TN,     FP,     FN,     P,     R,      2*P*R / (P+R) , correctlyClassified/testLengthRow]
disp('TP,    TN,     FP,     FN,     TP/(TP+FP),      TP/P,      2*P*R / (P+R) , correctlyClassified/trainLengthRow');


 unClassified;
 accuracy = correctlyClassified/testLengthRow  ;   
 accuracy

end