在使用Matlab计算平均查全率时,无法计算基础真实数据
假设我有一个大小如下的数据集:在使用Matlab计算平均查全率时,无法计算基础真实数据,matlab,image-processing,feature-extraction,nearest-neighbor,precision-recall,Matlab,Image Processing,Feature Extraction,Nearest Neighbor,Precision Recall,假设我有一个大小如下的数据集: 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
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
真值\u nn
以
预先计算的k
最近邻及其平方欧氏距离。因此,真值_nn的列表示k=100
最近邻。我发现很难在代码片段中应用最近邻搜索。有人能演示一下如何应用基本真值邻域真值\u 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);
会找到两个最近的邻居
问题1:如何创建包含地面真值邻域和预先计算的k最近邻距离的真值数据?
这称为平均查全率。我尝试实现knearest邻居搜索和平均精度召回,如下所示,但无法理解(不确定)如何应用地面真值表
问题2:
我试图通过将第一个实值特征转换为二进制来应用k
最近邻搜索
我无法应用k-最近邻搜索的概念来搜索k=10,20,50的不同值,也无法使用GIST数据库检查正确调用了多少数据。在GIST truth_nn()文件中,当我为查询向量I指定truth_nn(I,1:k)
时,函数AveragePrecision抛出错误。因此,如果有人能够使用任何与GIST结构相似的样本基础真理,说明如何正确指定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
更新:根据解决方案,我尝试使用给出的公式和a计算平均精度。但是,我不确定我的方法是否正确,因为理论上说我需要根据索引对返回的查询进行排序。我不完全理解这一点。为了判断检索算法的质量,需要平均精度
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()根本不起作用。我认为您正在做额外的工作。这个过程在matlab中非常简单,您也可以对整个阵列进行操作。这应该比for循环更快,并且更易于阅读 如果没有错误,您的
真相\u nn
和邻居应该有相同的数据。每行有一个条目。Matlab已经按升序对kmeans结果进行排序,因此列1是最近的邻居,第二个最近的是列2,第三个最近的是3,。。。。无需再次对数据进行排序
只需将truth\u nn
与neights
进行比较,即可获得您的统计数据。这是一个简单的示例,向您展示程序应该如何运行。如果不进行一些修改,它将无法处理您的数据
%在您提供的示例中,我创建了自己的
真理_nn=[1,2;
1,3;
4,3];
B_基=[11;22;32;44;56];
查询=[11;21;62];
%k均值
num_集群=2;
[Neights distances]=knnsearch(B_base,Query,'k',num_clusters);
%---输出---
%邻居=[1,2;
%1,2;注意这与真理1,3不匹配
% 4,3]
%距离=[0 1.4142;
% 1.0000 1.0000;
% 2.8284 3.0000];
%计算统计信息,nnz统计第一个
%对匹配的每一条数据进行大小写
%注1:truth_nn(:,1:num_clusters)上的索引表示所有行
%但仅使用第一个num_clusters列。这应该
%防止您得到的维度不匹配错误
正数=nnz(邻域==真值=nn(:,1:num_簇));%结果=5
否定=nnz(邻居~=truth_nn(:,1:num_簇));%结果=1
%注1:我已将此从真相切换到邻居,这很有帮助
%当你拥有一个新的世界
总数据=numel(邻域);%结果=6
不正确百分比=100*(否定/总数据);%16.6666
正确率=100*(正/总数据);%93.3333
这与您在这个主题上的其他问题有何不同?@bicker:在我的另一个问题中,我曾问过如何为alogirhtm位置敏感哈希创建多个哈希表。然后我问我如何使用GIST数据库。特别是,我正在努力研究如何应用由实际标签和距离组成的地面真值表。因为,这是一个非常具体的问题,我想问一个一般性的问题,在这里我创建了一个简单的查询和基础数据。现在,我不知道如何创建地面真值表。我的目标是应用最近邻搜索并使用平均精度召回度量评估质量。为了应用平均精度召回,我相信我们需要地面真值表。GIST数据库确实有一个,但我不知道如何使用它。因此,我在这里请求帮助展示如何在最近邻中应用基本事实,并借助于与t具有相同结构的任何样本基本表来计算平均查全率