Вопрос по matlab – КНН Алго в Matlab
Я работаю над системой распознавания большого пальца. Мне нужно реализовать алгоритм KNN для классификации моих изображений. в соответствии сэтот, он имеет только 2 измерения, по которым он вычисляет расстояние, чтобы найти ближайшего соседа, но в моем случае у меня есть 400 изображений 25 х 42, из которых 200 для обучения и 200 для тестирования. Я ищу несколько часов, но не нахожу способ найти расстояние между точками.
РЕДАКТИРОВАТЬ:
Я изменил 1-е 200 изображений в 1 X 1050 и сохранил их в матрицеtrainingData
200 X 1050. аналогично я сделалtestingData
.
е используемые функции требуют набора инструментов статистики):
%# 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))
trainData = labelData;
, Затем сделайте то же самое для тестовых данных (если они у вас есть - тестовые метки требуются, только если вы хотите измерить производительность классификатора, как я делал в части кода)
labelData = zeros(200,1); labelData(1:100,:) = 0; labelData(101:200,:) = 1;
, Так как использовать это здесь?
trainingData
порядка 200 X 1050. Это означает, что 200 - это все изображения, а 1050 - это размеры изображения (что на самом деле составляет 25 X 42). мой вопрос к вам, как я могу заменитьtrainClass = randi([1 5], [numTrain 1]);
с моим кодом.
Если вы хотите вычислитьЕвклидово расстояние между векторамиa
а такжеb
, просто используйтеПифагор, В 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)
pdist2
но я обновлю свой ответ :)
Поиграйте с количеством соседей, которых вы хотите сохранить, чтобы получить лучший результат (используйте путаницу). Эта функция, конечно, заботится о расстоянии.
knnclassify
вероятно, наиболее удобная вещь для использования в OP. Так что +1 за полезную функцию и ссылку с примерами :)