2016-01-24 14 views
0

Я работаю над проектом, и я хочу использовать классификацию k-NN для набора данных диафрагмы для рыбаков. Я представляю мой к-NN классификационный код MATLAB ниже:MATLAB: Мой классификатор k-NN работает правильно?

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 одинакова для всех к = 1,3,5.

Это состояние принятия или оно должно отличаться при k = 1,3,5? Если да, то что мне нужно изменить для моего кода, чтобы выполнить мою задачу?

ответ

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, ошибка рассчитывается на основе этой матрицы. Если вы не повторно инициализировать его после каждого цикла, статистические данные для последующих экспериментов добавляются с результатами предыдущих экспериментов (я взял только три строки из матрицы):

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'); 
Смежные вопросы