%% knn.m
%%
%% CSS 581 Introduction to Machine Learning, Winter 2014
%% Computing & Software Systems, University of Washington Bothell
%% written by J. Jeffry Howbert, 2012-02-02
%% modified by J. Jeffry Howbert, 2014-01-31

%% demo of nearest neighbor classification on MNIST dataset
clear all;
close all;
load mnistabridged;

trainData = double( train );
testData = double( test );
trainLabel = double( trainlabels );
testLabel = double( testlabels );
nTrain = length( trainlabels );
nTest = length( testlabels );

k = 1;
testPredIdx = knnsearch( trainData, testData, 'K', k );   %%&& knnsearch() doesn't exist in R2009a!!
testPredAll = trainLabel( testPredIdx );    % get labels of all k-nearest neighbors for each test sample
testPred = zeros( nTest, 1 );
for te = 1 : nTest
    % get label(s) which occurs most often among neighbors
    [ modeLabel, modeCount, allMode ] = mode( testPredAll( te, : ) );
    % if there is a tie for most frequent label, pick one at random
    allMode = allMode{ 1 };
    nMode = length( allMode );
    if ( nMode > 1 )
        RandStream.setDefaultStream( RandStream( 'mt19937ar', 'Seed', te ) );
        rp = randperm( nMode );
        modeLabel = allMode( rp( 1 ) );
    end
    testPred( te ) = modeLabel;    
end

nTestCorrect = sum( testLabel == testPred );
fprintf( 1, 'correct predictions on test set     :   %d / %d,  %5.2f%%\n', ...
    nTestCorrect, nTest, 100 * nTestCorrect / nTest );
[ mat, order ] = confusionmat( testLabel, testPred );
disp( ' ' );
disp( order' );
disp( mat );
