def calc_conditional_entropy(joint_prob: np.ndarray, p_marginal_truth: np.ndarray, p_marginal_alg: np.ndarray, idx_truth: np.ndarray, idx_alg: np.ndarray, evaluation: Evaluation, is_subgraph: bool = False) -> Evaluation: """Calculates the conditional entropy metrics between the algorithmic and truth partitions. The following metrics are calculated: entropy of the truth partition given the algorithm partition entropy of the algorithm partition given the truth partition the mutual information between the algorithm and truth partitions Parameters --------- Returns ------ evaluation : Evaluation the evaluation object, updated with the entropy-based goodness of partition metrics is_subgraph : bool True if evaluation is for a subgraph. Default = False """ conditional_prob_b2_b1 = np.zeros(joint_prob.shape) conditional_prob_b1_b2 = np.zeros(joint_prob.shape) conditional_prob_b2_b1[idx_truth, :] = joint_prob[idx_truth, :] / p_marginal_truth[idx_truth, None] conditional_prob_b1_b2[:, idx_alg] = joint_prob[:, idx_alg] / p_marginal_alg[None, idx_alg] # compute the conditional entropies idx = np.nonzero(joint_prob) H_b2_b1 = -np.sum(np.sum(joint_prob[idx] * np.log(conditional_prob_b2_b1[idx]))) H_b1_b2 = -np.sum(np.sum(joint_prob[idx] * np.log(conditional_prob_b1_b2[idx]))) # compute the mutual information (symmetric) marginal_prod = np.dot(p_marginal_truth[:, None], np.transpose(p_marginal_alg[:, None])) MI_b1_b2 = np.sum(np.sum(joint_prob[idx] * np.log(joint_prob[idx] / marginal_prod[idx]))) if is_subgraph: evaluation.subgraph_entropy_truth_given_algorithm = H_b1_b2 evaluation.subgraph_entropy_algorithm_given_truth = H_b2_b1 evaluation.subgraph_mutual_info = MI_b1_b2 else: evaluation.entropy_truth_given_algorithm = H_b1_b2 evaluation.entropy_algorithm_given_truth = H_b2_b1 evaluation.mutual_info = MI_b1_b2 print('Conditional entropy of truth partition given alg. partition: {}'.format(abs(H_b1_b2))) print('Conditional entropy of alg. partition given truth partition: {}'.format(abs(H_b2_b1))) print('Mutual informationion between truth partition and alg. partition: {}'.format(abs(MI_b1_b2))) return evaluation