|
|
|
|
|
|
|
def hierarchical_precision_recall_fmeasure( |
|
true_labels, predicted_labels, ancestors, beta=1.0 |
|
): |
|
|
|
true_positive_sum = predicted_sum = true_sum = 0 |
|
|
|
|
|
for true, predicted in zip(true_labels, predicted_labels): |
|
|
|
extended_true = true.union( |
|
*[ancestors[label] for label in true if label in ancestors] |
|
) |
|
extended_predicted = predicted.union( |
|
*[ancestors[label] for label in predicted if label in ancestors] |
|
) |
|
|
|
|
|
true_positive_sum += len(extended_true.intersection(extended_predicted)) |
|
predicted_sum += len(extended_predicted) |
|
true_sum += len(extended_true) |
|
|
|
|
|
hP = true_positive_sum / predicted_sum if predicted_sum else 0 |
|
hR = true_positive_sum / true_sum if true_sum else 0 |
|
|
|
|
|
hF = ((beta**2 + 1) * hP * hR) / (beta**2 * hP + hR) if (hP + hR) else 0 |
|
|
|
return hP, hR, hF |
|
|
|
|
|
|
|
true_labels = [{"G"}] |
|
predicted_labels = [{"F"}] |
|
ancestors = { |
|
"G": {"B", "C", "E"}, |
|
"F": {"C"}, |
|
} |
|
|
|
|
|
hP, hR, hF = hierarchical_precision_recall_fmeasure( |
|
true_labels, predicted_labels, ancestors |
|
) |
|
print(f"Hierarchical Precision (hP): {hP}") |
|
print(f"Hierarchical Recall (hR): {hR}") |
|
print(f"Hierarchical F-measure (hF): {hF}") |
|
|