|
1 | | -rule metrics_AUPRC: |
2 | | - input: |
3 | | - "results/dataset/{dataset}.parquet", |
4 | | - "results/prediction/{dataset}/{model}.parquet", |
5 | | - output: |
6 | | - "results/metrics/{dataset}/AUPRC/{model}.tsv", |
7 | | - wildcard_constraints: |
8 | | - dataset="|".join(get_all_datasets()), |
9 | | - run: |
10 | | - y_true = pd.read_parquet(input[0], columns=["label"]).label |
11 | | - y_pred = pd.read_parquet(input[1], columns=["score"]).score |
12 | | - AUPRC = average_precision_score(y_true, y_pred) |
13 | | - pd.DataFrame({"AUPRC": [AUPRC]}).to_csv(output[0], sep="\t", index=False, float_format="%.3f") |
| 1 | +# Metric function definitions |
| 2 | +def metric_auprc(y_true, y_pred): |
| 3 | + """Compute Area Under Precision-Recall Curve.""" |
| 4 | + return average_precision_score(y_true, y_pred) |
14 | 5 |
|
15 | 6 |
|
16 | | -rule metrics_AUROC: |
17 | | - input: |
18 | | - "results/dataset/{dataset}.parquet", |
19 | | - "results/prediction/{dataset}/{model}.parquet", |
20 | | - output: |
21 | | - "results/metrics/{dataset}/AUROC/{model}.tsv", |
22 | | - wildcard_constraints: |
23 | | - dataset="|".join(get_all_datasets()), |
24 | | - run: |
25 | | - y_true = pd.read_parquet(input[0], columns=["label"]).label |
26 | | - y_pred = pd.read_parquet(input[1], columns=["score"]).score |
27 | | - AUROC = roc_auc_score(y_true, y_pred) |
28 | | - pd.DataFrame({"AUROC": [AUROC]}).to_csv(output[0], sep="\t", index=False, float_format="%.3f") |
| 7 | +def metric_auroc(y_true, y_pred): |
| 8 | + """Compute Area Under ROC Curve.""" |
| 9 | + return roc_auc_score(y_true, y_pred) |
| 10 | + |
29 | 11 |
|
| 12 | +def metric_spearman(y_true, y_pred): |
| 13 | + """Compute Spearman correlation coefficient.""" |
| 14 | + return spearmanr(y_true, y_pred)[0] |
30 | 15 |
|
31 | | -rule metrics_Spearman: |
| 16 | + |
| 17 | +# Metric registry - maps metric names to functions |
| 18 | +METRIC_FUNCTIONS = { |
| 19 | + "AUPRC": metric_auprc, |
| 20 | + "AUROC": metric_auroc, |
| 21 | + "Spearman": metric_spearman, |
| 22 | +} |
| 23 | + |
| 24 | + |
| 25 | +def get_combined_group(dataset_name): |
| 26 | + """Return combined group name if dataset belongs to one, else None.""" |
| 27 | + for group_name, group_config in config.get("combined_dataset_groups", {}).items(): |
| 28 | + if dataset_name in group_config["datasets"]: |
| 29 | + return group_name |
| 30 | + return None |
| 31 | + |
| 32 | + |
| 33 | +def get_dataset_input(wildcards): |
| 34 | + """Get dataset input path - combined or individual.""" |
| 35 | + combined_group = get_combined_group(wildcards.dataset) |
| 36 | + if combined_group: |
| 37 | + return f"results/dataset/{combined_group}.parquet" |
| 38 | + else: |
| 39 | + return f"results/dataset/{wildcards.dataset}.parquet" |
| 40 | + |
| 41 | + |
| 42 | +def get_prediction_input(wildcards): |
| 43 | + """Get prediction input path - combined or individual.""" |
| 44 | + combined_group = get_combined_group(wildcards.dataset) |
| 45 | + if combined_group: |
| 46 | + return f"results/prediction/{combined_group}/{wildcards.model}.parquet" |
| 47 | + else: |
| 48 | + return f"results/prediction/{wildcards.dataset}/{wildcards.model}.parquet" |
| 49 | + |
| 50 | + |
| 51 | +rule metrics: |
| 52 | + """Unified metrics rule - handles AUPRC, AUROC, Spearman for all datasets.""" |
32 | 53 | input: |
33 | | - "results/dataset/{dataset}.parquet", |
34 | | - "results/prediction/{dataset}/{model}.parquet", |
| 54 | + dataset=get_dataset_input, |
| 55 | + prediction=get_prediction_input, |
35 | 56 | output: |
36 | | - "results/metrics/{dataset}/Spearman/{model}.tsv", |
| 57 | + "results/metrics/{dataset}/{metric}/{model}.tsv", |
37 | 58 | wildcard_constraints: |
38 | 59 | dataset="|".join(get_all_datasets()), |
39 | 60 | run: |
40 | | - y_true = pd.read_parquet(input[0], columns=["label"]).label |
41 | | - y_pred = pd.read_parquet(input[1], columns=["score"]).score |
42 | | - Spearman = spearmanr(y_true, y_pred)[0] |
43 | | - pd.DataFrame({"Spearman": [Spearman]}).to_csv(output[0], sep="\t", index=False, float_format="%.3f") |
| 61 | + # Load data |
| 62 | + df_dataset = pd.read_parquet(input.dataset) |
| 63 | + df_pred = pd.read_parquet(input.prediction) |
| 64 | + |
| 65 | + # Filter to specific benchmark if using combined dataset (positional filtering) |
| 66 | + if 'dataset' in df_dataset.columns: |
| 67 | + mask = df_dataset['dataset'] == wildcards.dataset |
| 68 | + df_dataset = df_dataset[mask] |
| 69 | + df_pred = df_pred[mask] # Apply same positional mask |
| 70 | + |
| 71 | + # Extract labels and scores |
| 72 | + y_true = df_dataset["label"] |
| 73 | + y_pred = df_pred["score"] |
| 74 | + |
| 75 | + # Compute metric using registry |
| 76 | + metric_func = METRIC_FUNCTIONS[wildcards.metric] |
| 77 | + value = metric_func(y_true, y_pred) |
| 78 | + |
| 79 | + # Save result |
| 80 | + pd.DataFrame({wildcards.metric: [value]}).to_csv( |
| 81 | + output[0], sep="\t", index=False, float_format="%.3f" |
| 82 | + ) |
44 | 83 |
|
45 | 84 |
|
46 | 85 | rule aggregate_metrics: |
|
0 commit comments