广义上的
召回率和精度是评估信息检索结果的常用指标,它们反映了检索结果的质量和完备性。在信息检索中,通常会使用查询集和检索集。查询集是需要进行检索的一组数据,而检索集是存储在数据库或文件库中的所有数据。下面简要介绍召回率和精度之间的关系以及它们与查询集和检索集之间的关系。
召回率(Recall)是指检索出的相关文档数与查询集中所有相关文档数的比例。它反映了检索结果的完备性,即检索结果中包含的相关文档数与查询集中所有相关文档数之间的比例。召回率越高,说明检索结果中包含的相关文档越多,检索结果的完备性越好。
精度(Precision)是指检索出的相关文档数与检索出的所有文档数的比例。它反映了检索结果的质量,即检索结果中包含的相关文档数与检索出的所有文档数之间的比例。精度越高,说明检索结果中包含的非相关文档比例越低,检索结果的质量越好。
召回率和精度之间存在一种负相关关系。当召回率很高时,精度往往较低;当精度很高时,召回率往往较低。这是因为召回率和精度的计算方式不同,它们对检索结果中的相关文档和非相关文档的权重不同,因此在不同的场合下需要选择适当的指标来评估检索结果的质量。
召回率和精度与查询集和检索集之间的关系如下:
- 查询集中的相关文档数和非相关文档数是召回率和精度的计算基础。
- 检索集是进行信息检索的所有数据集合,它包含了所有可能的相关文档和非相关文档。
- 在信息检索中,我们需要从检索集中检索出与查询集相关的文档,然后使用召回率和精度指标来评估检索结果的质量。
- 召回率和精度可以根据查询集和检索集之间的匹配程度来计算,从而评估检索结果的完备性和质量。
图像检索中
在图像检索任务中,相关文档通常指与查询图像相关的图像。具体来说,如果查询图像和某个检索图像具有相似的视觉特征或内容,那么这个检索图像就可以被认为是相关文档。
例如,假设您想要使用图像检索技术来搜索与某个给定图像相似的图像。您可以将这个给定图像作为查询图像,并将其与检索集中的所有图像进行比较。如果某个检索图像与查询图像具有相似的颜色、纹理、形状等视觉特征,那么这个检索图像就可以被认为是相关文档。
在这个例子中,查询图像是相关文档的基础。召回率的计算方式是检索出的相关文档数与查询集中所有相关文档数的比例。在图像检索中,这意味着召回率是检索出的与查询图像相似的图像数量与查询图像在检索集中所有相似图像数量的比例。如果检索出的图像数量与查询图像在检索集中所有相似图像数量相等,那么召回率为1,说明检索结果完全包含了所有与查询图像相似的图像。
def plot_pr_curve(query_binary, retrieval_binary, query_label, retrieval_label):
"""
绘制检索评价的精度-召回率曲线(PR曲线)
Args:
query_binary (numpy.ndarray): 一个大小为 (num_query, num_bit) 的 numpy 数组,
包含查询图像的二进制哈希码。
retrieval_binary (numpy.ndarray): 一个大小为 (num_retrieval, num_bit) 的 numpy 数组,
包含检索图像的二进制哈希码。
query_label (numpy.ndarray): 一个大小为 (num_query,) 的 numpy 数组,
包含查询图像的真实标签。
retrieval_label (numpy.ndarray): 一个大小为 (num_retrieval,) 的 numpy 数组,
包含检索图像的真实标签。
Returns:
None
"""
这段代码定义了一个名为plot_pr_curve的函数,该函数用于绘制检索评价的精度-召回率曲线(PR曲线)。函数接受四个参数:
- query_binary:一个大小为 (num_query, num_bit) 的numpy数组,包含查询图像的二进制哈希码。
- retrieval_binary:一个大小为 (num_retrieval, num_bit) 的numpy数组,包含检索图像的二进制哈希码。
- query_label:一个大小为 (num_query,) 的numpy数组,包含查询图像的真实标签。
- retrieval_label:一个大小为 (num_retrieval,) 的numpy数组,包含检索图像的真实标签。
函数不返回任何值。
# 将标签转换为 int32 类型,以避免索引错误
query_label = query_label.astype(np.int32)
retrieval_label = retrieval_label.astype(np.int32)
这段代码将查询图像和检索图像的标签转换为int32类型,以避免在后续的索引操作中出现错误。
# 计算查询图像和检索图像之间的汉明距离
hamming_dist = np.count_nonzero(query_binary[:, np.newaxis, :]
!= retrieval_binary[np.newaxis, :, :], axis=2)
这段代码计算查询图像和检索图像之间的汉明距离。汉明距离是二进制码之间的距离度量,它表示两个二进制码中不同位的数量。使用numpy库的count_nonzero函数,可以计算查询图像和检索图像之间的汉明距离矩阵。
# 将检索图像按汉明距离排序
idx = np.argsort(hamming_dist, axis=1)
这段代码将检索图像按照汉明距离排序,从小到大排列。使用numpy库的argsort函数,可以返回按照汉明距离排列的检索图像的索引。
# 初始化精度和召回率数组
num_query = query_binary.shape[0]
num_retrieval = retrieval_binary.shape[0]
precision = np.zeros((num_query, num_retrieval))
recall = np.zeros((num_query, num_retrieval))
这段代码初始化精度和召回率数组。num_query和num_retrieval分别表示查询图像和检索图像的数量。precision和recall分别是大小为(num_query, num_retrieval)的二维数组,用于存储每个查询图像和检索图像之间的精度和召回率。
# 计算每个查询图像的精度和召回率
for i in range(num_query):
# 计算检索图像的真实标签
gnd = (query_label[i] == retrieval_label[idx[i]])
# 计算真正例和假正例的累积和
tp_cumsum = np.cumsum(gnd)
fp_cumsum = np.cumsum(~gnd)
# 计算精度和召回率
precision[i] = tp_cumsum / (tp_cumsum + fp_cumsum)
recall[i] = tp_cumsum / np.count_nonzero(gnd)
这段代码计算每个查询图像的精度和召回率。对于每个查询图像,先计算它和所有检索图像之间的真实标签,然后根据真实标签计算真正例和假正例的累积和,最后计算精度和召回率。
# 计算所有查询图像的平均精度和召回率
mean_precision = np.mean(precision, axis=0)
mean_recall = np.mean(recall, axis=0)
这段代码计算所有查询图像的平均精度和召回率。使用numpy库的mean函数,可以计算每个检索图像的平均精度和召回率。
# 绘制PR曲线
plt.plot(mean_recall, mean_precision, 'b-')
plt.xlabel('Recall')
plt.ylabel('Precision')
plt.title('精度-召回率曲线')
plt.show()
这段代码绘制PR曲线。使用matplotlib库的plot函数,可以绘制平均精度和召回率之间的PR曲线。