Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Snakefile
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ rule evaluation_ensemble_pr_curve:
run:
node_table = Evaluation.from_file(input.gold_standard_file).node_table
node_ensemble_dict = Evaluation.edge_frequency_node_ensemble(node_table, input.ensemble_file, input.dataset_file)
Evaluation.precision_recall_curve_node_ensemble(node_ensemble_dict, node_table, output.pr_curve_png, output.pr_curve_file)
Evaluation.precision_recall_curve_node_ensemble(node_ensemble_dict, node_table, input.dataset_file,output.pr_curve_png, output.pr_curve_file)

# Returns list of algorithm specific ensemble files per dataset
def collect_ensemble_per_algo_per_dataset(wildcards):
Expand All @@ -544,7 +544,7 @@ rule evaluation_per_algo_ensemble_pr_curve:
run:
node_table = Evaluation.from_file(input.gold_standard_file).node_table
node_ensembles_dict = Evaluation.edge_frequency_node_ensemble(node_table, input.ensemble_files, input.dataset_file)
Evaluation.precision_recall_curve_node_ensemble(node_ensembles_dict, node_table, output.pr_curve_png, output.pr_curve_file, include_aggregate_algo_eval)
Evaluation.precision_recall_curve_node_ensemble(node_ensembles_dict, node_table, input.dataset_file,output.pr_curve_png, output.pr_curve_file, include_aggregate_algo_eval)


# Remove the output directory
Expand Down
30 changes: 29 additions & 1 deletion spras/evaluation.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ def edge_frequency_node_ensemble(node_table: pd.DataFrame, ensemble_files: list[
return node_ensembles_dict

@staticmethod
def precision_recall_curve_node_ensemble(node_ensembles: dict, node_table: pd.DataFrame, output_png: str | PathLike,
def precision_recall_curve_node_ensemble(node_ensembles: dict, node_table: pd.DataFrame, dataset_file: str, output_png: str | PathLike,
output_file: str | PathLike, aggregate_per_algorithm: bool = False):
"""
Plots precision-recall (PR) curves for a set of node ensembles evaluated against a gold standard.
Expand Down Expand Up @@ -387,6 +387,34 @@ def precision_recall_curve_node_ensemble(node_ensembles: dict, node_table: pd.Da
if not node_ensemble.empty:
y_true = [1 if node in gold_standard_nodes else 0 for node in node_ensemble['Node']]
y_scores = node_ensemble['Frequency'].tolist()

# TODO: add a new one here for y_scores_baseline where the sources and targets frequency are set to 1
# set the scores for nodes in node_ensemble that are in both the gold_standard_nodes and sources/targets/prizes to 1.0
# then make that into a new node_ensemble with altered values that are then plotted.

pickle = Evaluation.from_file(dataset_file)
prizes_df = pickle.get_node_columns(["sources", "targets", "prize"])
prizes = set(prizes_df['NODEID'])
prize_gold_intersection = prizes & gold_standard_nodes
prize_node_ensemble_df = node_ensemble.copy()

# TODO what if the node_ensemble is all frequency = 0.0, that will be the new source/target/prize/ baseline?

# Set frequency to 1.0 for matching nodes
prize_node_ensemble_df.loc[
Copy link
Collaborator Author

@ntalluri ntalluri Aug 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make the baseline 1 baseline per dataset not per algorithm. All the sources/prizes/targest/active = 1.0 and everything else is 0. But still calculate the precision and recall.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will be algorithm agnostic.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another option also maybe needed is to only evaluate the internal nodes (set the source/target/prizes to 0.0).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we might need both of these. One will be a baseline on the current ensemble pr. New figures for all the evaluation for only evaluating the internal nodes.

prize_node_ensemble_df['Node'].isin(prize_gold_intersection),
'Frequency'
] = 1.0
print(prize_node_ensemble_df)

y_scores_prizes = prize_node_ensemble_df['Frequency'].tolist()

precision_prizes, recall_prizes, thresholds_prizes = precision_recall_curve(y_true, y_scores_prizes)
plt.plot(recall_prizes, precision_prizes, color=color_palette[label], marker='o', linestyle=':',
label=f'{label.capitalize()} with prizes')



precision, recall, thresholds = precision_recall_curve(y_true, y_scores)
# avg precision summarizes a precision-recall curve as the weighted mean of precisions achieved at each threshold
avg_precision = average_precision_score(y_true, y_scores)
Expand Down
Loading