Невозможно вычислить основную истину, основанную на вычислении средней средней точности отзыва с помощью Matlab
Предполагая, что у меня есть набор данных следующего размера:
train = 500,000 * 960 %number of training samples (vector) each of 960 length
B_base = 1000000*960 %number of base samples (vector) each of 960 length
Query = 1000*960 %number of query samples (vector) each of 960 length
truth_nn = 1000*100
truth_nn
содержит основание истины соседей в виде
предварительно вычисленные k
ближайшие соседи и их квадратное евклидово расстояние. Итак, столбцы truth_nn представляют ближайших соседей k = 100
. Я нахожу трудным применить поиск ближайшего соседа в фрагменте кода. Может кто-нибудь, пожалуйста, показать, как применять основные соседи истины truth_nn
в поиске средней средней точности-вспомнить?
Это будет очень полезно, если кто-нибудь сможет показать на любом маленьком примере, создав любую матрицу данных, матрицу запросов и соседей основной истины в виде предварительно вычисленных k ближайших соседей и их квадратного евклидова расстояния. Я попытался создать образец базы данных.
Предположим, что исходными данными являются
B_base = [1 1; 2 2; 3 2; 4 4; 5 6];
Данные запроса-это
Query = [1 1; 2 1; 6 2];
[neighbors distances] = knnsearch(a,b,'k',2);
Нашел бы 2 ближайших соседа.
Вопрос 1: Как я создаю данные истины, содержащие основные соседи истины и предварительно вычисленные k ближайших соседних расстояний? Это называется средней точностью припоминания. Я попытался реализовать поиск наиболее близкого соседа и среднюю точность припоминания следующим образом, но не могу понять (не уверен), как применить таблицу истинности основания
Вопрос 2:
Я пытаюсь применить k
поиск ближайших соседей путем преобразования сначала вещественных объектов в двоичные.
Я не могу применить концепцию K-ближайшего соседа для поиска различных значения k = 10,20,50 и проверить, сколько данных было правильно отозвано с помощью базы данных GIST. В файле GiST truth_nn (), когда я указываю truth_nn(i,1:k)
для вектора запроса i, функция AveragePrecision выдает ошибку. Таким образом, если кто-то может показать с помощью любого образца наземной истины, которая имеет аналогичную структуру, как правильно указать k и вычислить среднюю точность отзыва, то я смогу применить решение к базе данных GIST. На данный момент, это мой подход и будет окажите огромную помощь, если правильный способ будет предоставлен с помощью любого примера,который будет легче для меня связать с базой данных GIST. Проблема в том, как я могу найти соседей с земли истину и сравнить ее с соседями, полученными после сортировки расстояний?
pdist2()
вместо нынешнего вычисления расстояния, поскольку это занимает много времени.
numQueryVectors = size(Query,1);
%Calculate distances
for i=1:numQueryVectors,
queryMatrix(i,:)
dist = sum((repmat(queryMatrix(i,:),numDataVectors,1)-B_base ).^2,2);
[sortval sortpos] = sort(dist,'ascend');
neighborIds(i,:) = sortpos(1:k);
neighborDistances(i,:) = sqrt(sortval(1:k));
end
%Sorting calculated nearest neighbor distances for k = 50
%HOW DO I SPECIFY k = 50 in the ground truth, truth_nn
for i=1:numQueryVectors
AP(i) = AveragePrecision(neighborIds(i,:),truth_nn(i,:));
end
mAP = mean(AP);
function ap = AveragePrecision(rank_id, truth_id)
truth_num = length(truth_id);
truth_pos = zeros(truth_num,1);
for j=1:50 %% for k = 50 nearest neighbors
truth_pos(j) = find(rank_id == truth_id(j));
end
truth_pos = sort(truth_pos, 'ascend');
% compute average precision as the area below the recall-precision curve
ap = 0;
delta_recall = 1/truth_num;
for j=1:truth_num
p = j/truth_pos(j);
ap = ap + p*delta_recall;
end
end
end
UPDATE: основываясь на решении, я попытался вычислить среднее значение точность с использованием формулы, приведенной здесь формула и опорный код. Но, не уверен, что мой подход верен, потому что теория говорит, что мне нужно ранжировать возвращенные запросы на основе индексов. Я не понимаю этого полностью. Для оценки качества алгоритма поиска требуется средняя точность.
precision = positives/total_data;
recal = positives /(positives+negatives);
precision = positives/total_data;
recall = positives /(positives+negatives);
truth_pos = sort(positives, 'ascend');
truth_num = length(truth_pos);
ap = 0;
delta_recall = 1/truth_num;
for j=1:truth_num
p = j/truth_pos(j);
ap = ap + p*delta_recall;
end
ap
Значение ap = бесконечность , значение положительных = 0 и отрицательных = 150. Это означает, что функция knnsearch() не работает вообще.
1 ответ:
Я думаю, что вы делаете дополнительную работу. Этот процесс очень прост в matlab,вы также можете работать с целыми массивами. Это должно быть быстрее, чем для циклов, и немного легче читать.
Ваши
Просто сравнитеtruth_nn
иneighbors
должны иметь одинаковые данные, если нет ошибок. В каждой строке есть одна запись. Matlab уже сортирует результат KME в порядке возрастания, поэтому столбец 1-ближайший сосед, второй ближайший-столбец 2, третий ближайший - 3,.... Нет необходимости сортировать данные снова.truth_nn
сneighbors
, чтобы получить статистику. Это простой пример, чтобы показать вам, как должна работать программа. Он не будет работать с вашими данными без некоторой модификации%in your example this is provided, I created my own truth_nn = [1,2; 1,3; 4,3]; B_base = [1 1; 2 2; 3 2; 4 4; 5 6]; Query = [1 1; 2 1; 6 2]; %performs k means num_clusters = 2; [neighbors distances] = knnsearch(B_base,Query,'k',num_clusters); %--- output--- % neighbors = [1,2; % 1,2; notice this doesn't match truth_nn 1,3 % 4,3] % distances = [ 0 1.4142; % 1.0000 1.0000; % 2.8284 3.0000]; %computes statistics, nnz counts number of nonzero elements, in the first %case every piece of data that matches %NOTE1: the indexing on truth_nn (:,1:num_clusters ) it says all rows % but only use the first num_clusters columns. This should % prevent the dimension mistmatch error you were getting positives = nnz(neighbors == truth_nn(:,1:num_clusters )); %result = 5 negatives = nnz(neighbors ~= truth_nn(:,1:num_clusters )); %result = 1 %NOTE1: I've switched this from truth_nn to neighbors, this helps % when you cahnge num_neghbors total_data = numel(neighbors); %result = 6 percent_incorrect = 100*(negatives / total_data); % 16.6666 percent_correct = 100*(positives / total_data); % 93.3333