Skip to content
Back to skills

Exam Level Label Hierarchy Aggregation

ASecurity

Aggregate per-slice predictions into exam-level labels that satisfy a competition's mutual-exclusion hierarchy (positive vs negative vs indeterminate), using a top-down rule cascade — first decide the exam class, then conditionally rescale the dependent labels so the submission stays internally consistent

  • 61 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 12, 2026
documentationpythongo

Security analysis

A100/100

Scanned September 12, 2026

npx -y skills add wenmin-wu/ds-skills --skill exam-level-label-hierarchy-aggregation --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Exam Level Label Hierarchy Aggregation?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Exam Level Label Hierarchy Aggregation
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/wenmin-wu-exam-level-label-hierarchy-aggregation/badge)](https://www.skillsdirectory.com/skills/wenmin-wu-exam-level-label-hierarchy-aggregation)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: cv-exam-level-label-hierarchy-aggregation
description: Aggregate per-slice predictions into exam-level labels that satisfy a competition's mutual-exclusion hierarchy (positive vs negative vs indeterminate), using a top-down rule cascade — first decide the exam class, then conditionally rescale the dependent labels so the submission stays internally consistent
---

## Overview

Multi-label medical competitions usually impose constraints across labels: a study is `negative_for_pe` XOR `indeterminate` XOR `positive_for_pe`, and per-organ severity labels are only meaningful when the parent label is positive. Per-slice CNNs don't know about these rules and emit independent sigmoid scores that often violate them — `negative_exam=0.7` and `positive_exam=0.6` is contradictory and metric-penalized. The aggregation fix is a top-down cascade: first commit to the exam-level decision based on the strongest evidence (any slice above 0.5 → positive), then rescale the dependent labels conditionally — push winning labels up by `0.5 + score/2`, push losing labels down by `score/2`. The final submission satisfies the hierarchy by construction.

## Quick Start

```python
import numpy as np
import pandas as pd
from scipy.special import softmax

def aggregate_exam(preds, exam_id):
    rows = preds.loc[preds.StudyInstanceUID == exam_id]
    is_positive = (rows.pe_present_on_image >= 0.5).any()

    out = {}
    if is_positive:
        out['negative_exam_for_pe'] = 0
        out['indeterminate']        = rows.indeterminate.min() / 2
    else:
        out['negative_exam_for_pe'] = 1
        if (rows.indeterminate >= 0.5).any():
            out['indeterminate'] = rows.indeterminate.max()
        else:
            out['indeterminate'] = rows.indeterminate.min() / 2

    a, b = rows[['rv_lv_ratio_gte_1', 'rv_lv_ratio_lt_1']].mean().values
    if a > b:
        a, b = a * 2, b / 2
    out['rv_lv_ratio_gte_1'], out['rv_lv_ratio_lt_1'] = softmax([a, b])

    for k in ['leftsided_pe', 'rightsided_pe', 'central_pe']:
        s = rows[k].mean()
        out[k] = (0.5 + s / 2) if is_positive else (s / 2)
    return out
```

## Workflow

1. Group per-slice predictions by exam id (`StudyInstanceUID` or analogous)
2. Decide the top-level exam class from the strongest evidence — `(slice_score >= 0.5).any()` is the standard rule
3. Set mutually exclusive top-level labels deterministically based on the decision
4. For dependent labels (severity, location, etc.), rescale by `0.5 + mean/2` if the parent was positive, `mean/2` if negative — this guarantees they stay below 0.5 in the negative case
5. For paired labels that must softmax to 1.0 (e.g. `rv_lv_ratio_gte_1` vs `lt_1`), apply softmax to the per-exam means after asymmetric pre-amplification of the winner

## Key Decisions

- **Top-down decision first, then rescale**: bottom-up averaging never satisfies the hierarchy.
- **`0.5 + score/2` and `score/2` rescaling**: pushes confident losers below 0.5 and confident winners above 0.5 without losing fine-grained ranking inside each side.
- **`.any()` for positive detection, not `.mean()`**: a single confident positive slice should flip the exam — averaging dilutes it.
- **Asymmetric softmax pre-amplification**: doubling the winner before softmax sharpens the output distribution without distorting the ranking.
- **Persist the rule cascade with the model**: if the metric definition changes, you only update one function.

## References

- [PE Detection with Keras - Model Creation](https://www.kaggle.com/competitions/rsna-str-pulmonary-embolism-detection)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…