我正在尝试使用点击数据构建精确度和召回率的图表。我有两个数据源。
- 第一个数据源包含基于给定查询ID的所有用户点击的项目ID。
- 第二个数据源包含给定查询ID的所有相关项目ID。
我使用Python将这两个数据源放入字典中,如下所示:
>>> print clicked_data{101: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 103: [20, 21, 22, 23, 24, 25, 26, 27, 28, 29]}>>> print all_relevant_data{101: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17], 103: [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]}
我在scikit-learn网站上阅读了一篇文章(http://scikit-learn.org/stable/auto_examples/plot_precision_recall.html),并尝试按照公式进行操作,但对于设置假阳性和假阴性感到非常困惑。
根据scikit-learn中的公式:根据上述示例,项目101
的精确度为
P = T_positive/ (T_positive + F_positive)>>> float(len(clicked_data[101]))/float(len(all_relevant_data[101]))0.5555555555555556
但当我试图计算召回率时,我在获取点击数据的假阴性项目上遇到了麻烦。理论上,假阴性意味着错误标记。我只有给定ID的用户点击数据和与该ID相关的所有项目。
R = T_positive / (T_positive + F_negative)
我如何正确计算精确度和召回率,以便构建图表?
另外,如果这不是评估结果的好指标,考虑到我只有上述提到的数据,什么样的指标会更好?
回答:
您可以根据您的数据集计算精确度@k和召回率@k。但您需要对文档进行排序才能计算这些指标。
数据集
一个著名的数据集是AOL搜索查询日志,您可以使用它来构建基于检索的系统(您只需要一个数据集和一个检索函数)来计算精确度、召回率、平均精确度和平均平均精确度。我简要解释一下上面提到的术语。
文档排序/检索函数
Okapi BM25(BM代表最佳匹配)是搜索引擎用来根据其与给定搜索查询的相关性对匹配文档进行排序的排序函数。它基于概率检索框架。BM25是一种词袋检索函数,根据查询词在每个文档中的出现情况对一组文档进行排序,而不考虑文档内查询词之间的相互关系(例如,它们的相对接近度)。有关更多详细信息,请参阅维基百科页面。
精确度和召回率
精确度衡量的是“在我们检索到的所有相关文档中,实际相关文档的数量是多少?”
精确度 = 检索到的相关文档数量 / 检索到的总文档数量
召回率衡量的是“在所有实际相关的文档中,我们检索到的相关文档的数量是多少?”
召回率 = 检索到的相关文档数量 / 总相关文档数量
假设,当一个查询“q”被提交到一个信息检索系统(例如,搜索引擎)时,系统检索到了与查询“q”相关的100个文档中的68个文档,总共从600个文档中检索出68个文档。在检索到的68个文档中,有40个文档是相关的。因此,在这种情况下:
精确度 = 40 / 68 = 58.8%
和 召回率 = 40 / 100 = 40%
F分数/F度量是精确度和召回率的加权调和平均数。传统的F度量或平衡的F分数是:
F分数 = 2 * 精确度 * 召回率 / 精确度 + 召回率
平均精确度
您可以这样想:您在Google
中输入一些内容,它会显示10个结果。如果所有结果都是相关的,那就最好了。如果只有一些是相关的,比如说五个,那么如果相关的那些首先显示出来会更好。如果前五个都是不相关的,而好的结果从第六个开始,那就很糟糕,对吗?AP分数反映了这一点。
下面给出一个例子:
两个排名的平均精确度:
排名#1: (1.0 + 0.67 + 0.75 + 0.8 + 0.83 + 0.6) / 6 = 0.78
排名#2: (0.5 + 0.4 + 0.5 + 0.57 + 0.56 + 0.6) / 6 = 0.52
平均平均精确度(MAP)
MAP是多个查询/排名的平均精确度的平均值。下面给出一个示例来说明。
两个查询的平均平均精确度:
对于查询1,平均精确度: (1.0+0.67+0.5+0.44+0.5) / 5 = 0.62
对于查询2,平均精确度: (0.5+0.4+0.43) / 3 = 0.44
因此,MAP = (0.62 + 0.44) / 2 = 0.53
有时候,人们使用精确度@k
、召回率@k
作为检索系统的性能度量。您应该为此类测试构建一个检索系统。如果您想用Java编写程序,您应该考虑使用Apache Lucene来构建您的索引。