我正在研究拇指识别系统。我需要实现KNN算法来分类我的图像。根据{{3}},它只有2个测量,通过它计算找到最近邻居的距离,但在我的情况下,我有400张25 X 42的图像,其中200个用于训练,200个用于测试。我正在寻找几个小时,但我找不到找到两点之间距离的方法。
编辑:
我将前200幅图像重新塑造为1 X 1050并将其存储在200 X 1050的矩阵trainingData
中。同样我制作了testingData
。
答案 0 :(得分:7)
以下是k近邻分类的示例代码(使用的某些函数需要统计工具箱):
%# image size
sz = [25,42];
%# training images
numTrain = 200;
trainData = zeros(numTrain,prod(sz));
for i=1:numTrain
img = imread( sprintf('train/image_%03d.jpg',i) );
trainData(i,:) = img(:);
end
%# testing images
numTest = 200;
testData = zeros(numTest,prod(sz));
for i=1:numTest
img = imread( sprintf('test/image_%03d.jpg',i) );
testData(i,:) = img(:);
end
%# target class (I'm just using random values. Load your actual values instead)
trainClass = randi([1 5], [numTrain 1]);
testClass = randi([1 5], [numTest 1]);
%# compute pairwise distances between each test instance vs. all training data
D = pdist2(testData, trainData, 'euclidean');
[D,idx] = sort(D, 2, 'ascend');
%# K nearest neighbors
K = 5;
D = D(:,1:K);
idx = idx(:,1:K);
%# majority vote
prediction = mode(trainClass(idx),2);
%# performance (confusion matrix and classification error)
C = confusionmat(testClass, prediction);
err = sum(C(:)) - sum(diag(C))
答案 1 :(得分:2)
如果您想计算向量a
和b
之间的Euclidean distance,请使用Pythagoras。在Matlab中:
dist = sqrt(sum((a-b).^2));
但是,您可能希望使用pdist
一次为矩阵中的所有矢量组合计算它。
dist = squareform(pdist(myVectors, 'euclidean'));
我将列解释为实例以进行分类,并将行解释为潜在邻居。这是任意的,你可以切换它们。
如果有一个单独的测试集,您可以使用pdist2
计算训练集中实例的距离:
dist = pdist2(trainingSet, testSet, 'euclidean')
您可以使用此距离矩阵对矢量进行分类,如下所示。我将生成一些随机数据作为示例,这将导致低(机会水平)精度。但是,当然你应该插入你的实际数据,结果可能会更好。
m = rand(nrOfVectors,nrOfFeatures); % random example data
classes = randi(nrOfClasses, 1, nrOfVectors); % random true classes
k = 3; % number of neighbors to consider, 3 is a common value
d = squareform(pdist(m, 'euclidean')); % distance matrix
[neighborvals, neighborindex] = sort(d,1); % get sorted distances
查看neighborvals
和neighborindex
矩阵,看看它们是否对您有意义。第一个是早期d
矩阵的排序版本,后者给出相应的实例编号。请注意,自我距离(在d
的对角线上)已浮动到顶部。我们对此并不感兴趣(总是为零),所以我们将跳过下一步的第一行。
assignedClasses = mode(neighborclasses(2:1+k,:),1);
所以我们在k个最近邻居中分配最常见的类!
您可以将指定的类与实际类进行比较,以获得准确度分数:
accuracy = 100 * sum(classes == assignedClasses)/length(classes);
fprintf('KNN Classifier Accuracy: %.2f%%\n', 100*accuracy)
或制作混淆矩阵以查看分类的分布:
confusionmat(classes, assignedClasses)
答案 2 :(得分:1)
是的,有一个knn函数:knnclassify
利用您想要保留的邻居数量来获得最佳结果(使用混淆矩阵)。当然,这个功能可以处理距离。