# After review with respect to equations def hierarchical_precision_recall_fmeasure( true_labels, predicted_labels, ancestors, beta=1.0 ): # Initialize counters for true positives, predicted, and true conditions true_positive_sum = predicted_sum = true_sum = 0 # Process each instance for true, predicted in zip(true_labels, predicted_labels): # Extend the sets with ancestors 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] ) # Update counters true_positive_sum += len(extended_true.intersection(extended_predicted)) predicted_sum += len(extended_predicted) true_sum += len(extended_true) # Calculate hierarchical precision and recall hP = true_positive_sum / predicted_sum if predicted_sum else 0 hR = true_positive_sum / true_sum if true_sum else 0 # Calculate hierarchical F-measure hF = ((beta**2 + 1) * hP * hR) / (beta**2 * hP + hR) if (hP + hR) else 0 return hP, hR, hF