Skip to content

Commit 1663688

Browse files
authored
docs: fix list rendering and filename link text for Zensical (#190)
1 parent 00fc2ac commit 1663688

6 files changed

Lines changed: 12 additions & 2 deletions

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ python -m spacy download en_core_web_lg # for NER
3737
#### From source
3838

3939
To install the package:
40+
4041
1. Clone the repo
4142
2. Install all dependencies:
4243

@@ -90,6 +91,7 @@ analyzing, modeling and evaluating data and models. Specifically,
9091
see [data_objects.py](presidio_evaluator/data_objects.py).
9192

9293
The standardized structure, `List[InputSample]`, can be translated into different formats:
94+
9395
- CoNLL
9496
- To CoNLL:
9597
```python

docs/adr/ADR-002-entity-mapping.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ The core use case is **comparing multiple models against the same dataset**. The
1818
the evaluation contract; models are the variable.
1919

2020
A flat `dict[str, str]` mapping is insufficient because:
21+
2122
- Many labels are aliases for the same concept (`FIRST_NAME`, `NAME_GIVEN`, `GIVENNAME``NAME`). Maintaining a hand-crafted dict for hundreds of model vocabularies is burdensome.
2223
- Labels exist in a hierarchy — `NAME` is a sub-type of `PERSON`. A model predicting `PERSON` on a `NAME`-annotated token is partially correct, not wrong. A flat dict cannot express this.
2324
- Unresolved labels need to be surfaced and triaged before evaluation; a dict silently drops or mismaps them.
@@ -76,6 +77,7 @@ By default, issues at WARNING level and above are surfaced. The user can control
7677

7778
`get_mapped_results_dataframe()` raises `IncompleteMapping` only if `UNRESOLVED` issues remain.
7879
To resolve:
80+
7981
- `mapper.map({"MY_LABEL": "CANONICAL"})` — map to a known hierarchy entity
8082
- `mapper.map({"MY_LABEL": None})` — suppress from evaluation entirely
8183

docs/adr/ADR-003-hierarchical-evaluation.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,15 @@ At each level L, for each token:
7272
4. The prediction is **FP** if it is non-`O` when the annotation is `O`.
7373

7474
This means:
75+
7576
- A token annotated at depth 2 (`PERSON`) is evaluated at L2 using the depth-2 label — any prediction of `PERSON` or a descendant (`NAME`, `TITLE`, etc.) counts as TP.
7677
- A token annotated at depth 3 (`TITLE`) requires the prediction to be `TITLE` or a descendant to score TP at L2; a prediction of `PERSON` (ancestor) is FP+FN.
7778

7879
Standard precision / recall / F1 apply at each level without modification. No new metric
7980
definitions are needed.
8081

8182
The levels correspond to the natural structure of `EntityHierarchy`:
83+
8284
- **L0**: PII vs. non-PII (binary)
8385
- **L1**: depth-2 branch node (PERSON, LOCATION, CONTACT, …)
8486
- **L2**: the annotation's own depth (depth-3 for depth-3 annotations; depth-2 for depth-2 annotations)

docs/entity_hierarchy.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@ If you compare these labels directly, everything looks like a mismatch — even
1111
Presidio Evaluator solves this with a **shared vocabulary** of canonical entity names. Every label — from any model or dataset — gets mapped to one of these canonical names before evaluation using a **two-phase process**:
1212

1313
**Phase 1 — Identify:** each label is matched to a canonical entity through five tiers (in priority order):
14+
1415
1. Exact match in the alias map
1516
2. Country-prefix strip (e.g. `GERMANY_PASSPORT_NUMBER``PASSPORT`)
1617
3. Country-prefix fallback (tries removing leading country code)
1718
4. Fuzzy string match (≥0.80 similarity by default)
1819
5. `UNRESOLVED` — flagged for manual resolution
1920

2021
Examples:
22+
2123
- `EMAIL`, `email_address`, `EMAILADDRESS` → all become `EMAIL_ADDRESS`
2224
- `B-PERSON`, `PERSON-I` → BIO tags are stripped, both become `NAME`
2325
- `GERMANY_PASSPORT_NUMBER` → country prefix is recognized, becomes `PASSPORT`
@@ -51,7 +53,7 @@ The **evaluation depth is data-driven**: `CanonicalMapper` computes a weighted m
5153
annotation labels in your results DataFrame and selects depth 2 or 3 (capped at 3). Depth 3 is the most
5254
common outcome when a dataset uses fine-grained entity types like `EMAIL_ADDRESS`, `NAME`, or `SSN`.
5355

54-
For more on why this approach was chosen over alternatives, see [why_canonical_entity_mapping.md](why_canonical_entity_mapping.md).
56+
For more on why this approach was chosen over alternatives, see [Why canonical entity mapping](why_canonical_entity_mapping.md).
5557

5658
## Typical workflow
5759

docs/mapping_scenarios.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ The same string alias appears under multiple canonical entities in the hierarchy
111111
| `MRN` / `MEDICAL_RECORD_NUMBER` | `PHI → MRN` | alias of `PATIENT_ID` | Same concept, two canonical targets |
112112

113113
**Issue types produced:**
114+
114115
- `COLLISION_CROSS_BRANCH` (WARNING) — blocking. Raised when a label resolves to a canonical entity that has co-occurring labels on the same tokens mapping to a different hierarchy branch. Must be resolved with `map()` before extracting results.
115116
- `COLLISION_AMBIGUOUS` (WARNING) — blocking. Raised when a depth-2 ancestor maps to multiple depth-3 entities on the canonical surface (the top co-occurring candidate is shown in `overlap_counts`). Use `map({'LABEL': 'CANONICAL'})` to pick the right one.
116117

@@ -131,6 +132,7 @@ The model finds PII types the dataset creators never labeled — every detection
131132
**Real example (Notebook 5):** After mapping, several Presidio predictions had no dataset counterpart.
132133

133134
**Issue type produced:** `PREDICTION_ONLY` (WARNING) — blocking. These labels inflate precision with false positives. You have three resolution options:
135+
134136
1. **Suppress**`mapper.map({'CREDIT_CARD': None})` excludes the label from evaluation entirely
135137
2. **Remap**`mapper.map({'CREDIT_CARD': 'FINANCIAL'})` counts detections against the `FINANCIAL` annotation set
136138
3. **Keep as FP** — if you want these counted as false positives deliberately, this isn't directly supported; suppression is the recommended path

docs/why_canonical_entity_mapping.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Why canonical entity mapping?
22

3-
This document explains the design decisions behind the canonical entity mapping approach used in Presidio Evaluator. For the taxonomy structure and usage guide, see [entity_hierarchy.md](entity_hierarchy.md).
3+
This document explains the design decisions behind the canonical entity mapping approach used in Presidio Evaluator. For the taxonomy structure and usage guide, see [Entity hierarchy](entity_hierarchy.md).
44

55
## Approaches to entity label mapping
66

0 commit comments

Comments
 (0)