我正在尝试通过将输出与金集输出进行比较来计算我们的命名实体识别器的精度和召回率。 annotationMap是黄金集合地图,myMap是我的NER的输出。为了给你一个感觉,地图包含如下数据:
{ORGANIZATION=[Pearl Williams Hartsfield, Fulton Superior Court],
DATE=[Friday], PERSON=[William B. Hartsfield]}
根据我在堆栈溢出时读到的答案,我们计算精度和召回的方式是(从那里复制粘贴):
[Microsoft Corp.] CEO [Steve Ballmer] announced the release of [Windows 7] today
这有3个实体。
假设您的实际提取具有以下
[Microsoft Corp.] [CEO] [Steve] Ballmer announced the release of Windows 7 [today]
完全匹配: True Positives = 1(Microsoft Corp.,唯一完全匹配),False Positives = 3(CEO,今天和Steve,这不是完全匹配) ,假阴性= 2(史蒂夫鲍尔默和Windows 7)
Precision = True Positives / (True Positives + False Positives) = 1/(1+3) = 0.25
Recall = True Positives / (True Positives + False Negatives) = 1/(1+2) = 0.33
任何重叠确定:真实肯定= 2(微软公司,史蒂夫与史蒂夫鲍尔默重叠),误报= 2(CEO,今天),假阴性= 1(Windows 7)
Precision = True Positives / (True Positives + False Positives) = 2/(2+2) = 0.55
Recall = True Positives / (True Positives + False Negatives) = 2/(2+1) = 0.66
我已经使用相同的逻辑对我的代码进行了建模,但对我来说误报的值总是为零,因此我的精度和召回值分别为1和0。
我认为我计算误报的方式是不正确的。但我遵循相同的逻辑并检查我是否在myMap中有任何实体未包含在annotatioMap中并将其称为误报(如上面的示例中的CEO和今天)。结果我对问题的确切位置感到困惑!
private static List<Integer> compareMaps(LinkedHashMap<String, Vector<String>> annotationMap, LinkedHashMap<String, Vector<String>> myMap)
{
List<Integer> compareResults = new ArrayList<Integer>();
if (annotationMap != null && myMap != null){
for (String key: annotationMap.keySet()){
if (key.equals("ORGANIZATION")){
if (annotationMap.get(key).equals(myMap.get(key))){
orgTruePositiveCount++;
continue;
}
if (annotationMap.get(key).contains(myMap.get(key))){
orgFalseNegativeCount++;
continue;
}
if (!annotationMap.get(key).contains(myMap.get(key))){
orgFalseNegativeCount++;
continue;
}
if (!myMap.get(key).contains(annotationMap.get(key))){
orgFalsePositiveCount++;
continue;
}
}