# Precision-Recall for CNN place recognition problem

Given 3450 query and 3450 reference images in a place recognition problem, I plot the Euclidean distance of feature vectors from convolutional neural network model as follows:

Ground Truth is recognized images from query and reference images:

frame_(i) - 2 in Reference <= frame_i in Query <= frame_(i) + 2 in Reference


I would like to plot precision-recall curve using this code:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import inset_axes

def draw_CM(cm_gt, cm_pred):
fig, (ax, ax1) = plt.subplots(ncols=2, figsize=(10,4))
im = ax.matshow(cm_gt)
im = ax1.matshow(cm_pred)
ax.set_title('Ground Truth')

ax.set_xlabel('Reference')
ax.set_ylabel('Query')
ax.tick_params(labelsize=5)

ax1.set_xlabel('Reference')
ax1.set_ylabel('Query')
ax1.tick_params(labelsize=5)
ax1.set_title('Prediction')
#ax1.yaxis.set_visible(False)

cax = inset_axes(ax1, width="5%", height="100%", loc='lower left',
bbox_to_anchor=(1.05, 0., 1, 1),
fig.colorbar(im, ax=[ax,ax1], cax=cax, ticks=[0.0, .2, .4, .6, .8, 1.0])

def draw_PR(cm_gt, cm_pred):
pr_curve = []
for th in np.arange(0,.2,5e-4):
similar         = (cm_pred<th) & (cm_gt==1)
all_pos         = (cm_pred<th)
try:
precision   = float(np.sum(similar))/float(np.sum(all_pos))
recall      = float(np.sum(similar))/float(np.sum(cm_gt==1))
pr_curve.append([th, precision, recall])
except Exception as e:
print 'WARNING:\t'+ str(e)
pass
pr_curve = np.array(pr_curve)

if pr_curve.size>0:
plt.figure()
plt.plot(pr_curve[:, 2], pr_curve[:, 1], 'k-')
plt.ylabel('Precision', fontsize=14)
plt.xlabel('Recall', fontsize=14)
plt.title('PR')
plt.grid()
plt.tight_layout()


The PR_curve looks as follows:

Questions:

1. Is this code a correct way of plotting precision-recall for such problems, since I do not have y_true and y_predicted to use sklearn.metrics.precision_recal_curve?

2. Does anybody know a more efficient way of plotting precision recall? my code takes almost 3 minutes to finish!