MATLAB:我的k-NN分类器是否正常工作?

时间:2016-01-24 10:59:33

标签: matlab classification knn

我正在研究一个项目,我想在fisher的虹膜数据集上使用k-NN分类。我在下面介绍我的k-NN分类MATLAB代码:

rng default;

% k-NN classifier

indices = crossvalind('Kfold',species);
cp = classperf(species);

% k = 1
for i = 1:5
    test = (indices == i); 
    train = ~test;
    class = knnclassify(meas(test,:),meas(train,:),species(train,:));
    classperf(cp(:),class,test);
end
fprintf('The k-NN classification error rate for k = 1 is: %f\n', cp.ErrorRate);

fprintf('Program paused. Press enter to continue.\n');
pause

% k = 3
for i = 1:5
    test = (indices == i); 
    train = ~test;
    class = knnclassify(meas(test,:),meas(train,:),species(train,:),3);
    classperf(cp(:),class,test);
end
fprintf('The k-NN classification error rate for k = 3 is: %f\n', cp.ErrorRate);

fprintf('Program paused. Press enter to continue.\n');
pause

% k = 5
for i = 1:5
    test = (indices == i); 
    train = ~test;
    class = knnclassify(meas(test,:),meas(train,:),species(train,:),5);
    classperf(cp(:),class,test);
end
fprintf('The k-NN classification error rate for k = 5 is: %f\n', cp.ErrorRate);

fprintf('Program paused. Press enter to continue.\n');
pause

我怀疑cp.ErrorRate对于所有k = 1,3,5都是相同的。

这是接受状态还是k = 1,3,5会不同? 如果是这样,我需要更改为我的代码才能完成我的任务?

1 个答案:

答案 0 :(得分:1)

你的观察实际上并不是真的。如果你看一下Iris数据集的图,你会发现数据真的很好分离:

3D scatter plot Fisher's Iris

因此,如果您选择一个数据项,您几乎总能将其精确地分类为1,3和5个邻居。在这些情况下,错误率将非常小。使用更多邻居时,费率会增长:

error rate KNN

...但是如果您尝试仅使用一个功能对数据进行分类,尤其是那个无法通过自身分离数据的功能,则情节看起来会有所不同(此处我仅根据第二个功能对数据进行分类) :

error rate KNN one feature

但是!首先,您需要更正一些代码。

每次执行classperf(cp(:),class,test);时,都会更新先前的cp结构。只要您处于折叠循环中就可以了,但是当您转到下一个实验获得另一个K值时,您需要再次重新初始化cp结构!否则,每个下一个实验的结果都会受到先前统计数据的影响。

查看矩阵cp.CountingMatrix。它包含有关已分类数据点的confusion信息,同时迭代折叠。当您致电cp.ErrorRate时,会根据此矩阵计算错误。如果你没有在每次循环后重新初始化它,那么下一个实验的统计数据会被添加到之前实验的结果中(我只从矩阵中取出3行):

k = 1; i = 1;

    10     0     0
     0    10     0
     0     0    10

k = 1; i = 2;

    20     0     0
     0    19     0
     0     1    20

k = 1; i = 3;

    30     0     0
     0    28     0
     0     2    30

k = 1; i = 4;

    40     0     0
     0    37     1
     0     3    39

k = 1; i = 5;

    50     0     0
     0    47     3
     0     3    47

k = 3; i = 1;

    60     0     0
     0    57     3
     0     3    57   % is biased by the first experiment

以下是我的代码,您可以在其中看到cp的重新初始化:

rng default;
load fisheriris;
fold_number = 5;
indices = crossvalind('Kfold',species, fold_number);

val = 1:2:100;

err_arr = [];

for k=val

    cp = classperf(species); %!!! reinitialize the cp-structure

    for i = 1:fold_number
        test = (indices == i); 
        train = ~test;
        class = knnclassify(meas(test,:),meas(train,:),species(train), k);
        %class = knnclassify(meas(test,2),meas(train,2),species(train), k); %to experiment only with the 2nd feature

        classperf(cp,class,test);
    end

    err_arr = [err_arr; cp.ErrorRate];
end    

plot(val, err_arr, 'LineWidth', 2);
grid on;
xlabel('K');
ylabel('ErrorRate');