MATLAB Answers

Y. K.
0

In the following code, Why is the classification accuracy (acc1, acc2) calculated differently?

Asked by Y. K.
on 7 Nov 2019
Latest activity Edited by michio
on 18 Nov 2019 at 1:09
The following function (knn_test) takes the following parameters: X indicates dataset sampels, Y indicates dataset labels, and filterindex corresponds column filter. If I want to filter the data, filterIndex is set to 1, whichever column is to be filtered.
I want to validate two holdout method. One with crossval function, and the other with cvpartition function. But when I call this method, acc1 and acc2 variables show different values.
I added break point to the code and debugged the code. I examined CVKNNModels' partition property and it was the same with the c particion in the Model 2.
What could have gone wrong with the following code?
Why did these two accuracy variables take different values?
If I want to use this function for holdout classification, which model should I choose?
Thanks.
function [acc1,acc2]=knn_test(X,Y,filterIndex)
columnfilterIndex = find(filterIndex==1);
%Model 1
tra1Data = X(:,[columnfilterIndex]);
tra1Label=Y;
KNNModel1=fitcknn(tra1Data, tra1Label, 'Distance', 'Euclidean', 'NumNeighbors', 3, 'DistanceWeight', 'Equal', 'Standardize', true);
rng('default');
CVKNNModel = crossval(KNNModel1,'holdout',0.3);
loss=kfoldLoss(CVKNNModel);
acc1=1-loss;
%Model 2
rng('default');
c = cvpartition(Y,'HoldOut',0.3);
tra2Data=X(c.training,[columnfilterIndex]);
tra2Label=Y(c.training,:);
test2Data=X(c.test,[columnfilterIndex]);
test2Label=Y(c.test,:);
KNNModel2 = fitcknn(tra2Data,tra2Label,'Distance', 'Euclidean','NumNeighbors',3, 'DistanceWeight', 'Equal','Standardize', true);
pre_test = predict(KNNModel2,test2Data);
correctPredictions = (pre_test == test2Label);
acc2 = sum(correctPredictions)/length(correctPredictions);
%perf=classperf(uint8(test2Label),uint8(pre_test));
%acc2=perf.CorrectRate;

  2 Comments

Could you provide a script that can reproduce the issue? I run the following and acc1 and acc2 are the same.
load ionosphere
[acc1,acc2]=knn_test(X,Y,ones(size(X,2),1))
where (note the line: correctPredictions = (string(pre_test) == string(test2Label)); to avoid error)
function [acc1,acc2]=knn_test(X,Y,filterIndex)
columnfilterIndex = find(filterIndex==1);
%Model 1
tra1Data = X(:,[columnfilterIndex]);
tra1Label=Y;
KNNModel1=fitcknn(tra1Data, tra1Label, 'Distance', 'Euclidean', 'NumNeighbors', 3, 'DistanceWeight', 'Equal', 'Standardize', true);
rng('default');
CVKNNModel = crossval(KNNModel1,'holdout',0.3);
loss=kfoldLoss(CVKNNModel);
acc1=1-loss;
%Model 2
rng('default');
c = cvpartition(Y,'HoldOut',0.3);
tra2Data=X(c.training,[columnfilterIndex]);
tra2Label=Y(c.training,:);
test2Data=X(c.test,[columnfilterIndex]);
test2Label=Y(c.test,:);
KNNModel2 = fitcknn(tra2Data,tra2Label,'Distance', 'Euclidean','NumNeighbors',3, 'DistanceWeight', 'Equal','Standardize', true);
pre_test = predict(KNNModel2,test2Data);
% correctPredictions = (pre_test == test2Label);
correctPredictions = (string(pre_test) == string(test2Label));
acc2 = sum(correctPredictions)/length(correctPredictions);
%perf=classperf(uint8(test2Label),uint8(pre_test));
%acc2=perf.CorrectRate;
I couldn't add test data. Because it size exceeds 5mb. I send the data to you with e-mail.
Thanks for your interest.

Sign in to comment.

2 Answers

Answer by michio
on 18 Nov 2019 at 1:08
Edited by michio
on 18 Nov 2019 at 1:09
 Accepted Answer

The two ways of hold-out cross-validation that you described have some subtle differences. For Model 1, when calling the crossval method on the KNNModel1, the prior is based on the whole dataset. For Model 2, the prior is based on the training partition tra2Data. If you specify the same prior, you should get the same results.
KNNModel2 = fitcknn(tra2Data,tra2Label,...
'Distance', 'Euclidean','NumNeighbors',3, ...
'DistanceWeight', 'Equal','Standardize', true, 'Prior', KNNModel1.Prior);

  0 Comments

Sign in to comment.


Answer by Y. K.
on 12 Nov 2019

In addition, this code gave the same results for small datasets. But when the number of features increases, it produces different results, especially in my dataset.

  0 Comments

Sign in to comment.