我已经以不同的方式问过几次这个问题。每当我取得突破时,我都会遇到另一个问题。这也是由于我还不精通Java,并且在使用Maps这样的集合时遇到了困难。所以,请忍受我。
我有两张这样的地图:
Map1 -{ORGANIZATION=[Fulton Tax Commissioner 's Office, Grady Hospital, Fulton Health Department], LOCATION=[Bellwood, Alpharetta]}
Map2 - {ORGANIZATION=[Atlanta Police Department, Fulton Tax Commissioner, Fulton Health Department], LOCATION=[Alpharetta], PERSON=[Bellwood, Grady Hospital]}
映射定义为:
LinkedHashMap<String, List<String>> sampleMap = new LinkedHashMap<String, List<String>>();
我正在根据值比较这两个地图,并且只有3个键,即ORGANIZATION,PERSON和LOCATION。 Map1是我与Map2进行比较的黄金集。现在,我面临的问题是当我遍历Map1中的ORGANIZATION键的值并检查Map2中的匹配项时,即使我的第一项确实在Map2中具有部分匹配项(富尔顿税收专员),但因为Map2的第一项是(亚特兰大警察局)不匹配,但我得到的结果不正确(我正在寻找完全匹配和部分匹配的匹配项)。这里的结果是增加真实的肯定,错误的肯定和错误的否定计数器,这使我能够最终计算精度并为此调用(即命名实体识别)。
编辑
我期望的结果是
Organization:
True Positive Count = 2
False Negative Count = 1
False Positive Count = 1
Person:
False Positive Count = 2
Location:
True Positive Count = 1
False Negative Count = 1
我当前得到的输出是:
Organization:
True Positive Count = 1
False Negative Count = 2
False Positive Count = 0
Person:
True Positive Count = 0
False Negative Count = 0
False Positive Count = 2
Location:
True Positive Count = 0
False Negative Count = 1
False Positive Count = 0
码
private static List<Integer> compareMaps(LinkedHashMap<String, List<String>> annotationMap, LinkedHashMap<String, List<String>> rageMap)
{
List<Integer> compareResults = new ArrayList<Integer>();
if (!annotationMap.entrySet().containsAll(rageMap.entrySet())){
for (Entry<String, List<String>> rageEntry : rageMap.entrySet()){
if (rageEntry.getKey().equals("ORGANIZATION") && !(annotationMap.containsKey(rageEntry.getKey()))){
for (int j = 0; j< rageEntry.getValue().size(); j++) {
orgFalsePositiveCount++;
}
}
if (rageEntry.getKey().equals("PERSON") && !(annotationMap.containsKey(rageEntry.getKey()))){
// System.out.println(rageEntry.getKey());
// System.out.println(annotationMap.entrySet());
for (int j = 0; j< rageEntry.getValue().size(); j++) {
perFalsePositiveCount++;
}
}
if (rageEntry.getKey().equals("LOCATION") && !(annotationMap.containsKey(rageEntry.getKey()))){
for (int j = 0; j< rageEntry.getValue().size(); j++) {
locFalsePositiveCount++;
}
}
}
}
for (Entry<String, List<String>> entry : annotationMap.entrySet()){
int i_index = 0;
if (rageMap.entrySet().isEmpty()){
orgFalseNegativeCount++;
continue;
}
// for (Entry<String, List<String>> rageEntry : rageMap.entrySet()){
if (entry.getKey().equals("ORGANIZATION")){
for(String val : entry.getValue()) {
if (rageMap.get(entry.getKey()) == null){
orgFalseNegativeCount++;
continue;
}
recusion: for (int i = i_index; i< rageMap.get(entry.getKey()).size();){
String rageVal = rageMap.get(entry.getKey()).get(i);
if(val.equals(rageVal)){
orgTruePositiveCount++;
i_index++;
break recusion;
}
else if((val.length() > rageVal.length()) && val.contains(rageVal)){ //|| dataB.get(entryA.getKey()).contains(entryA.getValue())){
orgTruePositiveCount++;
i_index++;
break recusion;
}
else if((val.length() < rageVal.length()) && rageVal.contains(val)){
orgTruePositiveCount++;
i_index++;
break recusion;
}
else if(!val.contains(rageVal)){
orgFalseNegativeCount++;
i_index++;
break recusion;
}
else if(!rageVal.contains(val)){
orgFalsePositiveCount++;
i_index++;
break recusion;
}
}
}
}
......................... //(Same for person and location)
compareResults.add(orgTruePositiveCount);
compareResults.add(orgFalseNegativeCount);
compareResults.add(orgFalsePositiveCount);
compareResults.add(perTruePositiveCount);
compareResults.add(perFalseNegativeCount);
compareResults.add(perFalsePositiveCount);
compareResults.add(locTruePositiveCount);
compareResults.add(locFalseNegativeCount);
compareResults.add(locFalsePositiveCount);
System.out.println(compareResults);
return compareResults;
}
最佳答案
我想出了一个简化的版本。这是我得到的输出:
Organization:
False Positive: Atlanta Police Department
True Positive: Fulton Tax Commissioner
True Positive: Fulton Health Department
False Negative: Grady Hospital
Person:
False Positive: Bellwood
False Positive: Grady Hospital
Location:
True Positive: Alpharetta
False Negative: Bellwood
[2, 1, 1, 0, 0, 2, 1, 1, 0]
这是我创建的代码:
public class MapCompare {
public static boolean listContains(List<String> annotationList, String value) {
if(annotationList.contains(value)) {
// 100% Match
return true;
}
for(String s: annotationList) {
if (s.contains(value) || value.contains(s)) {
// Partial Match
return true;
}
}
return false;
}
public static List<Integer> compareLists(List<String> annotationList, List<String> rageList){
List<Integer> compareResults = new ArrayList<Integer>();
if(annotationList == null || rageList == null) return Arrays.asList(0, 0, 0);
Integer truePositiveCount = 0;
Integer falseNegativeCount = 0;
Integer falsePositiveCount = 0;
for(String r: rageList) {
if(listContains(annotationList, r)) {
System.out.println("\tTrue Positive: " + r);
truePositiveCount ++;
} else {
System.out.println("\tFalse Positive: " + r);
falsePositiveCount ++;
}
}
for(String s: annotationList) {
if(listContains(rageList, s) == false){
System.out.println("\tFalse Negative: " + s);
falseNegativeCount ++;
}
}
compareResults.add(truePositiveCount);
compareResults.add(falseNegativeCount);
compareResults.add(falsePositiveCount);
System.out.println();
return compareResults;
}
private static List<Integer> compareMaps(LinkedHashMap<String, List<String>> annotationMap, LinkedHashMap<String, List<String>> rageMap) {
List<Integer> compareResults = new ArrayList<Integer>();
System.out.println("Organization:");
compareResults.addAll(compareLists(annotationMap.get("ORGANIZATION"), rageMap.get("ORGANIZATION")));
System.out.println("Person:");
compareResults.addAll(compareLists(annotationMap.get("PERSON"), rageMap.get("PERSON")));
System.out.println("Location:");
compareResults.addAll(compareLists(annotationMap.get("LOCATION"), rageMap.get("LOCATION")));
System.out.println(compareResults);
return compareResults;
}
public static void main(String[] args) {
LinkedHashMap<String, List<String>> Map1 = new LinkedHashMap<>();
List<String> m1l1 = Arrays.asList("Fulton Tax Commissioner's Office", "Grady Hospital", "Fulton Health Department");
List<String> m1l2 = Arrays.asList("Bellwood", "Alpharetta");
List<String> m1l3 = Arrays.asList();
Map1.put("ORGANIZATION", m1l1);
Map1.put("LOCATION", m1l2);
Map1.put("PERSON", m1l3);
LinkedHashMap<String, List<String>> Map2 = new LinkedHashMap<>();
List<String> m2l1 = Arrays.asList("Atlanta Police Department", "Fulton Tax Commissioner", "Fulton Health Department");
List<String> m2l2 = Arrays.asList("Alpharetta");
List<String> m2l3 = Arrays.asList("Bellwood", "Grady Hospital");
Map2.put("ORGANIZATION", m2l1);
Map2.put("LOCATION", m2l2);
Map2.put("PERSON", m2l3);
compareMaps(Map1, Map2);
}
}
希望这可以帮助!
关于java - 将两个LinkedHashMap与值作为列表进行比较,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42202342/