AsamAce's picture
Upload README.md with huggingface_hub
dd4a61e verified
|
Raw History Blame Contribute Delete
6.14 kB
---
license: mit
tags:
- pharmaceutical-supply-chain
- traceability
- anomaly-detection
- tabular-classification
- logistic-regression
pipeline_tag: tabular-classification
---
# ZigoTrace Pharma β€” Diversion Anomaly Model
A locked, validated logistic model that scores **grey-market diversion** on a
pharmaceutical serialization graph β€” engine: [zigo-pharma](https://github.com/Davedave001/zigo-pharma).
## Intended use β€” read this first
- **Advisory only.** This model outputs a suspicion score that is fused as **one
reliability-capped evidence source** into a larger Dempster-Shafer authenticity
confidence, alongside deterministic rule-based gaps. **It never gates a
dispense/release decision by itself** β€” the deterministic layer (recall, expiry,
cold-chain, cloned-serial, aggregation, mass-balance) is the authoritative safety
path, always.
- **Scope: diversion only.** Trained to catch route/ring diversion β€” units that are
*individually* unremarkable but statistically anomalous in their custody path or
their aggregation-case neighbourhood. It is **not** trained to catch expired,
recalled, or cold-chain-excursion stock; those are deterministic gaps, on purpose
(rules validate cleanly; this model is the layer for what rules cannot express).
- **Abstains under uncertainty.** Low model certainty collapses its contribution toward
"unknown" rather than guessing β€” see `uncertainty` in the output.
- **Not (yet) validated on real data.** Trained and evaluated on the synthetic dataset
`zigotrace/pharma-serialized-events`. See Limitations.
## How to use
Input is an **already-extracted 8-feature vector** β€” this model does not accept or
parse a raw event graph. Feature extraction is intentionally single-sourced in the TS
engine (`packages/intelligence/src/features.ts`) to avoid two implementations of graph
traversal silently drifting apart; see `docs/huggingface-model-plan.md` Β§0.
```python
from huggingface_hub import hf_hub_download
import json, sys
sys.path.insert(0, ".") # scorer.py ships alongside model.json in this repo
from scorer import load_model, score_features
model = load_model(hf_hub_download("zigotrace/pharma-authenticity-model", "model.json"))
features = [0.83, 1, 1, 1, 1, 1, 4, 0.0] # route_rarity, num_receives, num_dispenses,
# distinct_receive_locations, aggregation_consistent,
# attestation_ok, hop_count, case_dispense_anomaly
out = score_features(model, features)
print(out) # AnomalyOutput(score=..., uncertainty=..., explanation="...")
```
Or via an Inference Endpoint running `handler.py`:
```json
POST / {"inputs": {"features": [0.83, 1, 1, 1, 1, 1, 4, 0.0]}}
```
## Training
- **Algorithm:** logistic regression, full-batch gradient descent, fixed
initialization and iteration count β†’ **deterministic** (same events produce an
identical artifact β€” required for GxP change control; see
`packages/intelligence/src/train.ts`).
- **Labels:** **weak supervision** β€” labeling functions over model-observable signals
(rare custody route, duplicate dispense, weak attestation, case-sibling funnelling),
not ground truth. Realistic for a domain where confirmed-counterfeit labels are
scarce.
- **Data:** `zigotrace/pharma-serialized-events` (synthetic, seed 7, 420 train / 180
test rows).
## Evaluation (this artifact, `test.jsonl`, standalone at a raw 0.5 threshold)
| Metric | Value |
|---|---|
| Diversion detection (route + ring) | 7/7 β€” **100%** |
| Brier score | **0.021** |
| False-positive rate (standalone, 0.5 threshold) | 2.3% (4/173) |
Reproduce: `python hf/local_dry_run.py` (after `node hf/generate_fixtures.mjs`).
> **The false-positive rate above is a property of this model scored in isolation.**
> In the shipped engine it is capped by a reliability weight inside the
> Dempster-Shafer fusion and can only ever *add suspicion*, never override a
> deterministic "authentic" verdict β€” so it does not translate into a real
> false-quarantine rate. The shipped engine's actual false-quarantine rate (with this
> model fused in, evaluated by `intel-validate`) is **0%**. See
> `validation/model-card.md` in the source repo for the fused-system numbers.
## Model internals (inspectable β€” this is why logistic-first)
```
featureNames: route_rarity, num_receives, num_dispenses, distinct_receive_locations,
aggregation_consistent, attestation_ok, hop_count, case_dispense_anomaly
weights: [1.596, 0.026, 0.567, 0.026, 2.117, -0.567, 0.2, 1.095]
bias: -2.329
```
Weights act on **standardized** features (`(x - mean) / std`, per-feature `mean`/`std`
shipped in `model.json`). `case_dispense_anomaly` (the relational feature) and
`route_rarity` carry meaningful weight, consistent with the model's diversion-specific
training signal.
## Limitations
- Synthetic training/eval data only β€” real-world generalization is unverified pending
a lighthouse distributor dataset (planned, gated dataset repo).
- Linear model β€” cannot capture more complex relational patterns (e.g. multi-hop
laundering rings); a GNN track exists (`ml/` in the source repo) for that, not yet
outperforming this baseline on available data.
- `aggregation_consistent`'s weight sign should not be over-interpreted causally β€” it
has low variance in the synthetic generator (aggregation mismatches are a separate,
rare injected pattern), so its fitted coefficient is not strongly constrained by this
dataset.
## Governance
- **Change control:** training is deterministic; any retrain is a new artifact with a
new sha256, which is the locked version id (anchored on Hedera in the deployed
engine). No silent model updates.
- **Human authority:** a pharmacist/QP/auditor retains override, with recorded
provenance, regardless of this model's output.
- Full GxP validation pack: `validation/` in the
[source repo](https://github.com/Davedave001/zigo-pharma).
## License
MIT (this model + code). The synthetic dataset it's trained on is MIT-licensed
generated data β€” see the dataset card for details.