File size: 1,727 Bytes
2736d05
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
"""Score the business PII detector on text from a different generator (the HIPAA test set), 2026-10-29.

Its own test set comes from the same generators as its training data, so it scores perfectly; this shows how it does
on sentences written another way. Only the types both sets share are counted.
    python models/cross_test.py
"""

import json
from pathlib import Path

from transformers import pipeline

ROOT = Path(__file__).resolve().parent
SAME = {"NAME": "PERSON", "PHONE": "PHONE", "EMAIL": "EMAIL", "DATE": "DATE", "IP_ADDRESS": "IP_ADDRESS", "URL": "URL"}
tagger = pipeline("token-classification", model=str(ROOT / "business-pii-detector/out"), aggregation_strategy="simple", device=0)
rows = [json.loads(l) for l in open(ROOT / "hipaa-phi-detector/data/test.jsonl", encoding="utf-8")]
tp = fp = fn = 0
for r in rows:
    gold = {(SAME[e["label"]], e["start"], e["end"]) for e in r["entities"] if e["label"] in SAME}
    pred = set()
    for p in tagger(r["text"]):
        if p["entity_group"] in SAME.values():
            s = p["start"] + (len(r["text"][p["start"]:p["end"]]) - len(r["text"][p["start"]:p["end"]].lstrip()))
            pred.add((p["entity_group"], s, p["end"]))
    tp += len(gold & pred)
    fp += len(pred - gold)
    fn += len(gold - pred)
out = {"test": "hipaa-phi-detector test set, shared types only", "rows": len(rows), "precision": round(tp / (tp + fp), 3),
       "recall": round(tp / (tp + fn), 3), "f1": round(2 * tp / (2 * tp + fp + fn), 3)}
print(json.dumps(out))
s = json.loads((ROOT / "business-pii-detector/scores.json").read_text(encoding="utf-8"))
s["cross_test"] = out
(ROOT / "business-pii-detector/scores.json").write_text(json.dumps(s, indent=2) + "\n", encoding="utf-8")