Torres1980's picture
Add transaction classifier model, model card, and training code
8c5accf verified
Raw History Blame Contribute Delete
1.64 kB
"""
Classify statement line items and route them: straight-through or human review.
Usage:
python predict.py "CAP CALL #3 Lakeshore Growth Fund II DUE 10/24/2026"
python predict.py --file statement_lines.txt
"""
import argparse
import json
from pathlib import Path
import skops.io as sio
HERE = Path(__file__).parent
# Production default. The threshold tuned on the synthetic test set (see metrics.json) is
# optimistic for real feeds, where out-of-taxonomy items appear; 0.90 keeps them in review.
THRESHOLD = 0.90
def load(path=HERE / "model.skops"):
# skops only loads types you approve; review the list before trusting a file.
untrusted = sio.get_untrusted_types(file=path)
return sio.load(path, trusted=untrusted)
def classify(model, lines, threshold=THRESHOLD):
proba = model.predict_proba(lines)
out = []
for text, p in zip(lines, proba):
top = p.argsort()[::-1][:3]
conf = float(p[top[0]])
out.append({
"text": text,
"label": model.classes_[top[0]],
"confidence": round(conf, 4),
"route": "straight_through" if conf >= threshold else "human_review",
"alternatives": [{"label": model.classes_[i], "confidence": round(float(p[i]), 4)} for i in top[1:]],
})
return out
if __name__ == "__main__":
ap = argparse.ArgumentParser()
ap.add_argument("text", nargs="*")
ap.add_argument("--file")
args = ap.parse_args()
lines = Path(args.file).read_text().splitlines() if args.file else args.text
for r in classify(load(), [l for l in lines if l.strip()]):
print(json.dumps(r))