Я использую Python 2.7. У меня есть два файла данных tsv, которые я читаю в двух словарях, которые я хотел бы вычислить для их recall
, поэтому мне нужно рассчитать tp
и fn
. Вот как выглядят мои словари:
gold = {'A11':'cat', 'A22':'cat', 'B3':'mouse'}
results = {'A2':'cat', 'B2':'dog'}
Мой код главным образом выполняет итерацию gold
словаря и удаляет цифры в конце словарного key
gold
а также key
results
. Затем проверяет, соответствуют ли ключи, чтобы определить, соответствуют ли их значения для вычисления tp
. Тем не менее, мой код, кажется, всегда увеличивает fn
. Вот мой исполняемый код:
from __future__ import division
import string
def eval():
tp=0 #true positives
fn=0 #false negatives
fp=0#false positives
gold = {'A11':'cat', 'A22':'cat', 'B3':'mouse'}
results = {'A2':'cat', 'B2':'dog'}
#iterate gold dictionary
for i,j in gold.items():
#remove the digits off gold keys
i_stripped = i.rstrip(string.digits)
#iterate results dictionary
for k,v in results.items():
#remove the digits off results keys
k_stripped = k.rstrip(string.digits)
# check if key match!
if i_stripped == k_stripped:
#check if values match then increment tp
if j == v:
tp += 1
#delete dictionary entries to avoid counting them again
del gold_copy[i]
del results_copy[k]
#get out of this loop we found a match!
break
continue
# NO match was found in the results, then consider it as fn
fn += 1 #<------ wrong calculations caused in this line
print 'tp = %.2f fn = %.2f recall = %.2f ' % (tp, fn, float(tp)/(tp+fn))
и это результат:
tp = 1.00 fn = 3.00 recall = 0.25
fn
неверно, оно должно быть 2
вместо 3
. Как я могу остановить fn
от увеличения на каждой итерации? Любые указания будут действительно оценены.
Спасибо,
Это звучит так, как будто вы хотите увеличивать fn
только в том случае, если в результатах не найдено совпадений. Вы можете использовать переменную, чтобы отслеживать, было ли совпадение найдено, и на основе того, что вы увеличиваете fn
. Ниже я адаптировал ваш код и использовал match_found
для этой цели.
#iterate gold dictionary
for i,j in gold.items():
# create a variable that indicates whether a match was found
match_found = False
#remove the digits off gold keys
i_stripped = i.rstrip(string.digits)
#iterate results dictionary
for k,v in results.items():
#remove the digits off results keys
k_stripped = k.rstrip(string.digits)
# check if key match!
if i_stripped == k_stripped:
#check if values match then increment tp
if j == v:
tp += 1
# now a match has been found, change variable
match_found = True
#delete dictionary entries to avoid counting them again
del gold_copy[i]
del results_copy[k]
#get out of this loop we found a match!
break
continue
# NO match was found in the results, then consider it as fn
# now, only if no match has been found, increment fn
if not match_found :
fn += 1 #<------ wrong calculations caused in this line
Если это не совсем то, что вам нужно, вы сможете изменить его, чтобы он работал.
tp = 0 #true positives
fn = 0 #false negatives
fp = 0 #false positives
gold = {'A11':'cat', 'A22':'cat', 'B3':'mouse'}
results = {'A2':'cat', 'B2':'dog'}
for gold_k, gold_v in gold.items():
# Remove digits and make lower case
clean_gold_k = gold_k.rstrip(string.digits).lower()
for results_k, results_v in results.items():
# Remove digits and make lower case
clean_results_k = results_k.rstrip(string.digits).lower()
keys_agree = clean_gold_k == clean_results_k
values_agree = gold_v.lower() == results_v.lower()
print('\n-------------------------------------')
print('Gold = ' + gold_k + ': ' + gold_v)
print('Result = ' + results_k + ': ' + results_v)
if keys_agree and values_agree:
print('tp')
tp += 1
elif keys_agree and not values_agree:
print('fn')
fn += 1
elif values_agree and not keys_agree:
print('fp')
fp += 1