MATLAB:我的 k-NN 分类器是否正常工作?
MATLAB: Does my k-NN classifier works correctly?
我正在做一个项目,我想对 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 应该不同?
如果是这样,我必须更改我的代码才能完成我的任务?
您的观察实际上与事实相去不远。如果你看一下 Iris 数据集的图,你会发现数据真的很好分离:
因此,如果您选择一个数据项,您几乎总是可以通过 1、3 和 5 个相邻项对其进行非常精确的分类。在这些情况下错误率会非常小。当使用更多的邻居时,速率会增加:
...但是如果您尝试仅使用一个特征对数据进行分类,尤其是不能单独很好地分离数据的特征,则绘图看起来会有所不同(这里我仅根据第二个特征对数据进行分类功能):
但是! 首先,您需要稍微更正您的代码。
每次执行 classperf(cp(:),class,test);
之前的 cp
结构都会更新。只要你在你的折叠中循环就可以了,但是当你进入下一个实验以获得另一个 K
值时,你需要再次 re-initialize cp
结构!否则每次下一次实验的结果都会受到之前统计数据的影响。
看看矩阵cp.CountingMatrix
。它包含 confusion
有关已分类数据点的信息,同时遍历折叠。当你调用 cp.ErrorRate
时,错误是根据这个矩阵计算的。如果你在每次循环后不 re-initialize 它,下一个实验的统计数据将添加到以前实验的结果中(我只从矩阵中取了 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
的 re-initialization:
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');
我正在做一个项目,我想对 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 应该不同? 如果是这样,我必须更改我的代码才能完成我的任务?
您的观察实际上与事实相去不远。如果你看一下 Iris 数据集的图,你会发现数据真的很好分离:
因此,如果您选择一个数据项,您几乎总是可以通过 1、3 和 5 个相邻项对其进行非常精确的分类。在这些情况下错误率会非常小。当使用更多的邻居时,速率会增加:
...但是如果您尝试仅使用一个特征对数据进行分类,尤其是不能单独很好地分离数据的特征,则绘图看起来会有所不同(这里我仅根据第二个特征对数据进行分类功能):
但是! 首先,您需要稍微更正您的代码。
每次执行 classperf(cp(:),class,test);
之前的 cp
结构都会更新。只要你在你的折叠中循环就可以了,但是当你进入下一个实验以获得另一个 K
值时,你需要再次 re-initialize cp
结构!否则每次下一次实验的结果都会受到之前统计数据的影响。
看看矩阵cp.CountingMatrix
。它包含 confusion
有关已分类数据点的信息,同时遍历折叠。当你调用 cp.ErrorRate
时,错误是根据这个矩阵计算的。如果你在每次循环后不 re-initialize 它,下一个实验的统计数据将添加到以前实验的结果中(我只从矩阵中取了 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
的 re-initialization:
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');