Невозможно вычислить основную истину, основанную на вычислении средней средней точности отзыва с помощью 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 2

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