Instructions to use Torres1980/alts-transaction-classifier with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Scikit-learn
How to use Torres1980/alts-transaction-classifier with Scikit-learn:
# β οΈ Model filename not specified in config.json
- Notebooks
- Google Colab
- Kaggle
Alternatives & Insurance Transaction Classifier
Classifies free-text activity from GP capital account statements, fund administrator notices, custodian files, and carrier statements into 18 standardized transaction types, and reports a confidence score that decides whether each item posts automatically or goes to a person.
"CAP CALL #3 Lakeshore Growth Fund II DUE 10/24/2026" β capital_call 0.99 straight-through
"Halcyon Buyout Partners IV - distribution, return of capital" β distribution_return_of_capital 0.99 straight-through
"Northstar Life PPLI Policy #44120 COI charge Q3 2026" β policy_charge 0.99 straight-through
"WIRE IN Tidewater Credit Fund equalization interest" β index_credit 0.50 human review
Why this matters
Wealth platforms that consolidate alternatives and insurance (Addepar, iCapital, Orion, and others) take in activity as unstructured text from hundreds of GPs, administrators, and carriers. Every sponsor words things differently: "CAP CALL", "Drawdown notice", "Contribution - Call 4", "Paid-in capital". Someone has to turn each line into the right transaction type before it can be booked. If they get it wrong, the reporting goes wrong with it: a return-of-capital distribution booked as income overstates yield and misstates cost basis, and a recallable distribution booked as final understates unfunded commitment.
Today most of that mapping is done by people or by brittle keyword rules. This model does the mapping and, just as important, knows when it isn't sure.
Labels
| Alternatives | Insurance | Structured notes | Other |
|---|---|---|---|
capital_call |
insurance_premium |
note_coupon |
valuation_update |
distribution_income |
policy_charge (COI, M&E, admin, riders) |
note_call_maturity (autocall, maturity) |
|
distribution_return_of_capital |
policy_loan |
||
distribution_capital_gain |
withdrawal_surrender (incl. RMDs) |
||
recallable_distribution |
index_credit (FIA / RILA crediting) |
||
management_fee |
|||
incentive_fee (carry, performance) |
|||
fund_expense |
|||
subscription |
|||
redemption (incl. tender offers) |
Results
Test set: 2,700 items whose fund sponsors, carriers, and note issuers never appear in training. Half also use phrasings never seen in training (for example, "Promote paid" for carry, or "Cash-out of contract" for a surrender).
| v1: training data only | v2: + one review cycle | |
|---|---|---|
| Accuracy, all | 81.7% | 98.9% |
| Accuracy, unseen entities | 99.9% | 99.9% |
| Accuracy, unseen phrasings | 62.1% | 97.8% |
| Straight-through at β₯ 99% precision | 61.6% of items | 98.9% of items |
v2 adds 180 items (1.4% of the training data), the kind a reviewer labels while working v1's exception queue. That is the automation story in one number: one review cycle takes straight-through processing from about 62% to about 99% without lowering precision.
v1 shows the model fails safe. On phrasings it had never seen it was only 62% accurate, but at a 0.93 confidence threshold the 17% of those items it handled on its own were 99% correct, and the rest went to a person.
Production default threshold: 0.90. On the test set this sends 75% of items straight through at 99.95% precision. The thresholds tuned on the test set (0.42 to 0.56) are optimistic, because real feeds contain items outside this taxonomy.
Per-label F1 (v2) is at or above 0.99 for 16 of 18 labels. The weakest are
distribution_capital_gain (0.90) and redemption (0.92). The residual errors are
"proceeds in excess of cost" read as a redemption, which is a genuinely ambiguous
phrase without the statement's context.
Usage
import skops.io as sio
from huggingface_hub import hf_hub_download
path = hf_hub_download("Torres1980/alts-transaction-classifier", "model.skops")
model = sio.load(path, trusted=sio.get_untrusted_types(file=path)) # review the list first
lines = ["DIST ROC Granite Direct Lending Fund II 125,000.00",
"Monthly deduction - Pinnacle Life VUL Policy #55210"]
for text, p in zip(lines, model.predict_proba(lines)):
label, conf = model.classes_[p.argmax()], p.max()
print(label, round(conf, 3), "auto" if conf >= 0.90 else "review")
Or from the repo: python predict.py "CAP CALL #3 Lakeshore Growth Fund II". It returns
the label, confidence, route, and the next two alternatives for the reviewer.
Model
| Features | Word 1β2-gram TF-IDF plus character 2β5-gram TF-IDF (handles abbreviations like DIST ROC and PREM PMT, and typos) |
| Classifier | Multinomial logistic regression (scikit-learn), C = 8 |
| Size | 6.5 MB, CPU only, thousands of lines per second |
| Format | skops (safe serialization, no pickle) |
| Training | 12,600 synthetic line items plus 180 review-feedback items |
A linear model was chosen on purpose. It trains in seconds, so retraining after each review cycle is cheap. It also runs anywhere, and every prediction can be explained by its top-weighted n-grams, which matters to operations and compliance teams.
Where it fits
Statement / feed line ββΊ classifier ββΊ conf β₯ 0.90 ββΊ book to reporting system
βββΊ conf < 0.90 ββΊ review queue ββΊ label ββΊ next retrain
It pairs with the Alternatives Data Integrity reconciliation engine. The classifier gives every activity line the right type, and the reconciliation matches it against the book of record.
Limitations
- Synthetic data. Training and test data are generated from templates with randomized sponsors, amounts, dates, casing, prefixes, and typos. Real statements are messier: multi-line descriptions, sponsor-specific codes, other languages. Expect lower accuracy on real data until the model is retrained on a firm's own labeled history. The pipeline is built for exactly that.
- Closed taxonomy. Items outside the 18 labels (equalization, custody fees, tax
withholding, transfers in kind) still get one of the 18 labels. Confidence is usually
low enough to route them to review, but a production version should add an explicit
otherclass. - Text only. The model does not use amount sign, account type, or prior activity, all of which would resolve the remaining ambiguous cases.
- Not affiliated with or endorsed by Addepar, iCapital, or any sponsor or carrier. All names are fictional.
Reproduce
pip install scikit-learn skops pandas
python data/generate.py # data/train.csv, test.csv, review_feedback.csv
python train.py # model.skops, metrics.json
Author
Robert Torres Β· 15+ years in wealth management operations and alternatives (E*TRADE, Charles Schwab, Merrill Lynch), including private placements and structured products on Addepar, iCapital, and Orion. LinkedIn Β· GitHub
- Downloads last month
- -
Space using Torres1980/alts-transaction-classifier 1
Evaluation results
- Accuracy (v2, after one review cycle) on Synthetic alternatives & insurance statement activity (held-out entities and phrasings)self-reported0.989
- Macro F1 (v2) on Synthetic alternatives & insurance statement activity (held-out entities and phrasings)self-reported0.989
- Accuracy (v1, training data only) on Synthetic alternatives & insurance statement activity (held-out entities and phrasings)self-reported0.817