相对于我从两个不同的文本集中提取的重要关键字的排名列表,我试图确定用于评估词典(单词列表)的“覆盖率”的度量标准。这两个列表没有通用的术语。重要的是,只有排名靠前的n个单词才被视为“正确”,而排名靠后的m单词则被视为“不正确”。
下面是一个虚拟示例,其中具有排名关键字列表和4个不同的词典,每个词典都包含列表中的某些单词。
rank keyword lexicon_1 lexicon_2 lexicon_3 lexicon_4
1 apple False True True False
2 orange False True True False
3 banana False False True False
4 pear False False True False
5 kiwifruit True False True False
6 watermelon True False True False
-----------------------------------------------------------
7 car False False False True
8 bus False False False True
9 truck True False False True
10 bike False True False True
因此,直觉是词典中包含的排名较高的关键字(1-6)越好,而包含的排名较低的关键字(7-10)越少越好。
计算精度(P),召回率(R)和F分数(F)是量化和比较覆盖率的一种方法。为此,当词典包含正确的单词时为真肯定词(TP),当词典包含错误的单词时为假肯定词(FP),当词典排除不正确的单词时为真否定词(TN),而当单词排除一个错误词时为假否定词(FN)。正确的单词。考虑到这一点,例如对于lexicon_1
,这给出了:
TP=2, FP=1, TN=3, FN=4
P = 2 / (2 + 1) R = 2 / (2 + 4) F = 2 * 0.67 * 0.33 / (0.67 + 0.33)
= 0.67 = 0.33 = 0.44
对于lexicon_2
,我们还会得到F=0.44
。对于lexicon_3
,我们得到F=1.00
;对于lexicon_4
,我们得到F=0
(未定义)。因此,我们可以看到词典1
和2
位于3
(最佳)和4
(最差)之间,但这没有考虑到{{ 1}}的单词排名比lexicon_2
高,因此应该得到更好的评价。
在这些情况下,是否有任何度量标准会考虑单词的排名?我知道lexicon_1
和average precision
,它们对检索结果进行排名,但是我不确定这些指标是否适合这种情况。
编辑1:
对于这种情况,我已经实现了对average precision的理解:
mean average precision
这给了我以下结果:
def avep(df, lexicon_names):
"""
Calculate average precision for each lexicon from
pre-calculated precision and recall scores stored
in a DataFrame.
"""
aveps = {}
for l in lexicon_names:
ap = 0.0
for i in range(len(df)):
p_i = df.iloc[i]['p_' + l]
if i > 0:
dr_i = df.iloc[i]['r_' + l] - df.iloc[i - 1]['r_' + l]
else:
dr_i = 0.0
ap += p_i * dr_i
aveps[l] = ap
return aveps
但是,Lexicon p r f AP
------- - - - --
lexicon_1 : 0.6666666666666666 0.2857142857142857 0.4 0.2857142857142857
lexicon_2 : 0.6666666666666666 0.2857142857142857 0.4 0.14285714285714285
lexicon_3 : 1.0 1.0 1.0 0.8571428571428571
lexicon_4 : 0.0 0.0 0.0 0.0
比lexicon_1
的效果更好,这与我想要的相反(AP可疑地等同于lexicon_2
和lexicon_1
的召回率2 x recall
)。此外,不确定在召回率差异未定义的第一行(使用0)该怎么办。这样,“完美” lexicon_2
的值小于1.0。
任何更好的建议将不胜感激!
编辑2:
这是RobertBaron提供的解决方案的我的Python实现:
lexicon_3
这是RobertBaron解决方案所需的数字转换的实现(据我了解):
def coverage_metric(df, lexicon_names):
scores = {}
max_score = int(''.join([str(x) for x in df.index]))
for l in lexicon_names:
correct_score = int(''.join([str(x) for x in df.loc[df[l] == True].index]))
incorrect_score = int(''.join([str(x) for x in df.loc[df[l] == False].index]))
scores[l] = (correct_score - incorrect_score) / max_score
scores = sorted(scores.items(), key=lambda x: x[1], reverse=True)
return scores
答案 0 :(得分:0)
这是一个指标。有n + m个等级。因此,请为每个关键字分配一个以n + m + 1为底的数字,为排名最高的关键字提供最大的数字。在您的示例中,我们有10个关键字,因此数字以11为底,从A到1(使用十六进制数字),如下所示。
rank digit keyword lexicon_1 lexicon_2 lexicon_3 lexicon_4
1 A apple False True True False
2 9 orange False True True False
3 8 banana False False True False
4 7 pear False False True False
5 6 kiwifruit True False True False
6 5 watermelon True False True False
------------------------------------------------------------------
7 4 car False False False True
8 3 bus False False False True
9 2 truck True False False True
10 1 bike False True False True
对于每个词典,覆盖率度量计算如下。对于正确的关键字,从最高排名开始,通过连接词典中关键字的数字来构建数字。例如,对于我们的4个词典,我们分别具有65
,A9
,A98765
和0
。对不正确的关键字执行相同的操作。这给了我们2
,1
,0
和4321
。通过减去为每个词典建立的两个数字来获得最终度量,即65
-1
= 64
,A9
-1
= {{ 1}},A8
-A98765
= 0
和A98765
-0
= 4321
。
如果您希望指标在-4321
范围内,则可以除以[0 1]
,这是该示例中词典可以具有的最大值。
为方便起见,可以将n + m + 1的底数转换为10的底数进行计算。参见Number Conversion Algorithms。
在以11为基础的示例中,对于词典1,我们需要将A98765
,65
和1
转换为以10为基础。
6 x 11 1 + 5 x 11 0 = 71
1 x 11 0 = 1
10 x 11 5 + 9 x 11 4 + 8 x 11 3 + 7 x 11 2 + 6 x 11 1 + 5 x 11 0 = 1753845
词典1的量度为(71-1)/ 1753845 = 0.000039912307
该示例中有一个小错误。因为我们可以有负值,所以可能的值范围从A98765
到-4321
。因此,要获得A98765
中的指标,我们需要移动[0 1]
并除以4321
+ A98765
。