Token Classification
Transformers
ONNX
Safetensors
English
distilbert
pii
privacy
experimental
datafog
Instructions to use DataFog/pii-en-65m with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use DataFog/pii-en-65m with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("token-classification", model="DataFog/pii-en-65m")# pip install -U transformers accelerate # Load model directly from transformers import AutoTokenizer, AutoModelForTokenClassification tokenizer = AutoTokenizer.from_pretrained("DataFog/pii-en-65m") model = AutoModelForTokenClassification.from_pretrained("DataFog/pii-en-65m", device_map="auto") - Notebooks
- Google Colab
- Kaggle
Download reproduction/scripts/regex_baseline.py from DataFog/pii-en-65m: direct link, hf CLI and curl.
- Browser
- Download file 4.15 kB
-
https://huggingface.co/DataFog/pii-en-65m/resolve/5683ef559df6618f563375b632fdab7352ac1628/reproduction/scripts/regex_baseline.py
- Command line
-
hf download hf://DataFog/pii-en-65m@5683ef559df6618f563375b632fdab7352ac1628/reproduction/scripts/regex_baseline.py
-
curl -L -o regex_baseline.py https://huggingface.co/DataFog/pii-en-65m/resolve/5683ef559df6618f563375b632fdab7352ac1628/reproduction/scripts/regex_baseline.py
4.15 kB
| #!/usr/bin/env python3 | |
| """Pinned official DataFog regex baseline on shared email/phone scope.""" | |
| import argparse | |
| import hashlib | |
| import importlib.metadata | |
| import json | |
| import sys | |
| import time | |
| from pathlib import Path | |
| sys.path.insert(0, str(Path(__file__).resolve().parents[1])) | |
| from pii.evaluation import evaluate, read_jsonl, write_json | |
| VERSION = '4.8.1' | |
| MAPPING = {'EMAIL': 'email', 'PHONE': 'phone_number'} | |
| def scoped_gold(records): | |
| return [{**r, 'spans':[s for s in r['spans'] if s['label'] in MAPPING.values()]} for r in records] | |
| def predict(records): | |
| import datafog | |
| if importlib.metadata.version('datafog') != VERSION: | |
| raise RuntimeError(f'Baseline requires datafog=={VERSION}') | |
| for r in records: | |
| result = datafog.scan(r['text'], engine='regex', entity_types=list(MAPPING)) | |
| findings = [] | |
| byte_offsets = [0] | |
| for ch in r['text']: | |
| byte_offsets.append(byte_offsets[-1] + len(ch.encode('utf-8'))) | |
| for e in result.entities: | |
| if r['text'][e.start:e.end] != e.text: | |
| raise ValueError('Upstream span/source mismatch') | |
| findings.append(dict(label=MAPPING[e.type], start=byte_offsets[e.start], end=byte_offsets[e.end], raw_score=1.0, confidence=None)) | |
| yield dict(id=r['id'], text=r['text'], findings=findings, contains_pii=bool(findings), score_semantics='Constant match indicator from DataFog regex, not calibrated confidence') | |
| def write_jsonl(path, records): | |
| with open(path, 'w') as f: | |
| for record in records: | |
| f.write(json.dumps(record, ensure_ascii=False)+'\n') | |
| if __name__ == '__main__': | |
| parser = argparse.ArgumentParser(description=__doc__) | |
| parser.add_argument('--gold', required=True) | |
| parser.add_argument('--output-dir', required=True) | |
| parser.add_argument('--model-predictions') | |
| parser.add_argument('--model-calibration') | |
| args = parser.parse_args() | |
| output = Path(args.output_dir) | |
| output.mkdir(parents=True, exist_ok=True) | |
| gold = scoped_gold(read_jsonl(args.gold)) | |
| started = time.perf_counter() | |
| predictions = list(predict(gold)) | |
| elapsed = time.perf_counter()-started | |
| write_jsonl(output/'gold-email-phone.jsonl', gold) | |
| write_jsonl(output/'regex-predictions.jsonl', predictions) | |
| metrics = evaluate(gold, predictions) | |
| # A regex match flag is not a probability; do not imply a calibration comparison. | |
| for key in ('raw_reliability','confidence_reliability','reliability_population','confidence_semantics'): | |
| metrics.pop(key, None) | |
| metrics['score_semantics'] = 'Regex match indicator, no probability calibration evaluated' | |
| metrics['comparison_scope'] = ['email','phone_number'] | |
| metrics['unsupported_labels'] = ['first_name','last_name','street_address','customer_id','account_number'] | |
| write_json(output/'regex-metrics.json', metrics) | |
| provenance = dict(package='datafog', version=VERSION, official_repository='https://github.com/DataFog/datafog-python', | |
| release='https://pypi.org/project/datafog/4.8.1/', input_sha256=hashlib.sha256(Path(args.gold).read_bytes()).hexdigest(), | |
| documents=len(gold), elapsed_seconds=elapsed, API="datafog.scan(text, engine='regex', entity_types=['EMAIL','PHONE'])", | |
| offset_conversion='Python character offsets converted to original UTF-8 byte offsets', dependencies={d.metadata['Name']:d.version for d in importlib.metadata.distributions()}) | |
| write_json(output/'regex-provenance.json', provenance) | |
| if args.model_predictions: | |
| model = read_jsonl(args.model_predictions) | |
| model = [{**r, 'findings':[s for s in r['findings'] if s['label'] in MAPPING.values()]} for r in model] | |
| calibration = json.loads(Path(args.model_calibration).read_text()) if args.model_calibration else None | |
| model_metrics = evaluate(gold, model, calibration=calibration) | |
| model_metrics['comparison_scope'] = ['email','phone_number'] | |
| write_json(output/'model-email-phone-metrics.json', model_metrics) | |
| print(json.dumps({'documents':len(gold), 'seconds':elapsed, 'output_dir':str(output)})) | |