Text Classification
Scikit-learn
English
finance
wealth-management
alternative-investments
private-equity
insurance
annuities
structured-products
data-operations
reconciliation
tabular-text
skops
Eval Results (legacy)
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
Download data/generate.py from Torres1980/alts-transaction-classifier: direct link, hf CLI and curl.
- Browser
- Download file 12.6 kB
-
https://huggingface.co/Torres1980/alts-transaction-classifier/resolve/main/data/generate.py
- Command line
-
hf download hf://Torres1980/alts-transaction-classifier/data/generate.py
-
curl -L -o generate.py https://huggingface.co/Torres1980/alts-transaction-classifier/resolve/main/data/generate.py
12.6 kB
| """ | |
| Synthetic statement line items for alternatives, structured notes and insurance. | |
| Each row is the kind of free-text description that arrives from GP capital account | |
| statements, administrator notices, custodian activity files and carrier statements, | |
| labeled with a standardized transaction type. | |
| To measure generalization honestly, the test split uses fund sponsors, fund names | |
| and phrasings that never appear in training. | |
| Run: python data/generate.py | |
| """ | |
| import csv | |
| import random | |
| from pathlib import Path | |
| random.seed(42) | |
| OUT = Path(__file__).parent | |
| LABELS = [ | |
| "capital_call", "distribution_income", "distribution_return_of_capital", | |
| "distribution_capital_gain", "recallable_distribution", "management_fee", | |
| "incentive_fee", "fund_expense", "subscription", "redemption", | |
| "insurance_premium", "policy_charge", "policy_loan", "withdrawal_surrender", | |
| "index_credit", "note_coupon", "note_call_maturity", "valuation_update", | |
| ] | |
| SPONSORS_TRAIN = ["Summit Ridge", "Harborview", "Granite", "Meridian", "Wasatch", "Keystone", "Northbeam", | |
| "Cascade", "Bonneville", "Timberline", "Redwood", "Ironbridge", "Silverlake Trail", | |
| "Oakmont", "Bluewater", "Highline", "Stonegate", "Pinecrest", "Copperleaf", "Westfield"] | |
| SPONSORS_TEST = ["Lakeshore", "Aspen Hollow", "Driftwood", "Kingsley", "Marrow Creek", "Halcyon", "Tidewater"] | |
| STRATS = ["Growth Fund", "Buyout Partners", "Direct Lending Fund", "Senior Credit Fund", "Multifamily Fund", | |
| "Infrastructure Fund", "Opportunity Zone Fund", "Co-Invest", "Secondaries Fund", "Venture Partners", | |
| "Real Estate Income Trust", "Private Credit Interval Fund", "Multi-Strategy Ltd", "Energy Transition Fund"] | |
| ROMAN = ["I", "II", "III", "IV", "V", "VI", "VII", "2019", "2021", "2023"] | |
| SUFFIX = ["", " LP", " L.P.", ", L.P.", " Fund LP", " Feeder LP", " (Offshore) Ltd", " Onshore LP"] | |
| CARRIERS_TRAIN = ["Pinnacle Life", "Evergreen Mutual", "Atlas Annuity", "Sterling Life & Annuity", "Harbor Mutual"] | |
| CARRIERS_TEST = ["Northstar Life", "Crestline Annuity"] | |
| PRODUCTS = ["PPLI Policy", "PPVA Contract", "Fixed Indexed Annuity", "RILA Contract", "VUL Policy"] | |
| ISSUERS_TRAIN = ["Global Bank AG", "Northern Securities", "Atlantic Capital Markets", "Continental Bank"] | |
| ISSUERS_TEST = ["Pacific Rim Finance"] | |
| UNDERLYING = ["S&P 500", "Russell 2000", "Nasdaq-100", "EURO STOXX 50", "SPX/RTY worst-of", "MSCI EAFE"] | |
| MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] | |
| def fund(test): | |
| s = random.choice(SPONSORS_TEST if test else SPONSORS_TRAIN) | |
| name = f"{s} {random.choice(STRATS)} {random.choice(ROMAN)}{random.choice(SUFFIX)}" | |
| return random.choice([name, name.upper(), name.replace("Fund", "Fd").replace("Partners", "Ptnrs")]) | |
| def policy(test): | |
| c = random.choice(CARRIERS_TEST if test else CARRIERS_TRAIN) | |
| return f"{c} {random.choice(PRODUCTS)} #{random.randint(10000, 99999)}" | |
| def note(test): | |
| i = random.choice(ISSUERS_TEST if test else ISSUERS_TRAIN) | |
| kind = random.choice(["Autocallable", "Buffered", "Barrier", "Contingent Income", "Market-Linked CD"]) | |
| return f"{i} {kind} Note on {random.choice(UNDERLYING)} due {random.randint(2026, 2032)} CUSIP {random.randint(10000, 99999)}X{random.randint(10, 99)}" | |
| def amt(): | |
| v = random.choice([random.uniform(500, 9999), random.uniform(10000, 250000), random.uniform(250000, 2500000)]) | |
| return random.choice([f"${v:,.2f}", f"{v:,.2f}", f"USD {v:,.2f}", f"{v:.2f}", ""]) | |
| def dt(): | |
| m, d, y = random.randint(1, 12), random.randint(1, 28), random.choice([2024, 2025, 2026]) | |
| return random.choice([f"{m:02d}/{d:02d}/{y}", f"{y}-{m:02d}-{d:02d}", f"{MONTHS[m-1]} {d}, {y}", f"Q{(m-1)//3+1} {y}", ""]) | |
| def q(): | |
| return random.choice([f"Q{random.randint(1, 4)} {random.choice([2024, 2025, 2026])}", f"{random.choice(MONTHS)} {random.choice([2025, 2026])}", "period end", ""]) | |
| # Templates: (train_phrasings, test_only_phrasings). {f}=fund, {p}=policy, {n}=note, {a}=amount, {d}=date, {q}=period, {k}=call number | |
| T = { | |
| "capital_call": ( | |
| ["Capital Call #{k} - {f} {a}", "CAP CALL {f} DUE {d}", "Contribution - {f} - Call Notice {k}", "{f}: capital contribution {a}", | |
| "Drawdown notice #{k} {f}", "INVESTOR CONTRIBUTION {f} {a}", "Capital call for investments - {f}", "CONTRIB {f} CALL {k}", | |
| "{f} - Call {k} (investments & fees) {a}", "Funding request {f} due {d}"], | |
| ["Draw-down #{k} {f} payable {d}", "Paid-in capital {f} {a}", "Commitment drawn - {f}"]), | |
| "distribution_income": ( | |
| ["Distribution - Income - {f} {a}", "DIST INC {f}", "Income distribution {q} {f}", "{f} interest income distribution {a}", | |
| "Dividend distribution - {f}", "INCOME DISTR {f} {d}", "Net investment income distribution {f}", "{f} - distribution (ordinary income)"], | |
| ["Yield distribution {f} {a}", "Current income paid - {f}", "{f} quarterly income payout"]), | |
| "distribution_return_of_capital": ( | |
| ["Distribution - Return of Capital - {f} {a}", "DIST ROC {f}", "Return of capital {f} {d}", "{f} ROC distribution {a}", | |
| "RETURN OF CAPITAL DISTR {f}", "Capital returned - {f} - realization", "{f} distribution (return of contributed capital)"], | |
| ["Cost basis returned {f} {a}", "Non-taxable return of capital - {f}", "Capital repayment distribution {f}"]), | |
| "distribution_capital_gain": ( | |
| ["Distribution - Realized Gain - {f} {a}", "DIST LTCG {f}", "Capital gain distribution {f} {d}", "{f} gain on sale distribution", | |
| "Realized gain distr - {f} - exit proceeds", "LONG TERM CAP GAIN DIST {f} {a}", "{f} distribution of realized gains"], | |
| ["Exit gain paid {f} {a}", "Profit distribution on realization - {f}", "{f} - proceeds in excess of cost"]), | |
| "recallable_distribution": ( | |
| ["Recallable distribution - {f} {a}", "DIST RECALLABLE {f}", "{f} recallable return of capital {d}", "Temporary distribution (subject to recall) {f}", | |
| "RECALL DIST {f} {a}", "{f} - distribution, recallable per LPA"], | |
| ["Distribution subject to recycling {f}", "Reinvestable distribution {f} {a}"]), | |
| "management_fee": ( | |
| ["Management fee {q} - {f} {a}", "MGMT FEE {f}", "{f} management fee (outside commitment) {a}", "Mgmt fee {q} {f}", | |
| "Advisory fee - {f} - {q}", "MANAGEMENT FEES {f} {d}", "{f} - management fee offset applied"], | |
| ["Quarterly sponsor fee {f} {a}", "Base fee {q} - {f}", "GP fee {f} {q}"]), | |
| "incentive_fee": ( | |
| ["Carried interest - {f} {a}", "INCENTIVE ALLOCATION {f}", "{f} performance fee {q}", "Carry paid to GP - {f}", | |
| "INCENT FEE {f} {a}", "Incentive fee crystallization {f} {d}", "{f} - general partner carried interest"], | |
| ["Promote paid {f} {a}", "Performance allocation to manager - {f}"]), | |
| "fund_expense": ( | |
| ["Fund expenses {q} - {f} {a}", "ORG EXPENSES {f}", "{f} partnership expenses {a}", "Admin & audit expense - {f}", | |
| "Organizational costs {f} {d}", "FUND EXP {f} {q}", "{f} - legal and fund administration expenses"], | |
| ["Operating expense allocation {f} {a}", "Partnership costs - {f} {q}", "Audit/tax prep charge {f}"]), | |
| "subscription": ( | |
| ["Subscription - {f} {a}", "SUB {f} {d}", "Initial subscription {f}", "{f} additional subscription {a}", | |
| "Purchase - {f} - subscription accepted", "SUBSCR {f}", "{f} subscription settled {d}"], | |
| ["Buy-in to {f} {a}", "Shares issued - {f} {d}", "Initial investment {f}"]), | |
| "redemption": ( | |
| ["Redemption - {f} {a}", "REDEMPTION {f} {d}", "{f} partial redemption {a}", "Tender offer proceeds - {f}", | |
| "REDEEM {f} {q}", "{f} full redemption paid", "Repurchase proceeds {f} {a}"], | |
| ["Withdrawal of shares {f} {a}", "Liquidity window payout - {f}", "Share repurchase {f} {q}"]), | |
| "insurance_premium": ( | |
| ["Premium payment - {p} {a}", "PREM PMT {p}", "{p} annual premium {d}", "Planned premium {p} {a}", | |
| "Initial premium - {p}", "PREMIUM {p} {q}", "{p} - additional premium deposit {a}", "Purchase payment {p}"], | |
| ["Contract deposit {p} {a}", "Policy funding payment - {p}", "Single premium paid {p}"]), | |
| "policy_charge": ( | |
| ["Cost of insurance charge - {p} {a}", "COI {p} {q}", "{p} M&E charge {a}", "Policy admin fee {p}", | |
| "MONTHLY DEDUCTION {p}", "{p} - premium load / DAC tax", "Rider charge {p} {a}", "Mortality & expense fee {p} {q}"], | |
| ["Insurance cost deduction {p} {a}", "Contract maintenance fee {p}", "Monthly policy charges - {p}"]), | |
| "policy_loan": ( | |
| ["Policy loan - {p} {a}", "LOAN ADVANCE {p}", "{p} loan disbursement {d}", "Loan repayment - {p} {a}", | |
| "POLICY LOAN INT {p}", "{p} - loan interest charged {q}"], | |
| ["Borrowing against cash value {p} {a}", "Loan proceeds paid {p}"]), | |
| "withdrawal_surrender": ( | |
| ["Partial withdrawal - {p} {a}", "SURRENDER {p}", "{p} full surrender {d}", "Free withdrawal {p} {a}", | |
| "PARTIAL SURR {p}", "{p} - surrender charge applied", "Required minimum distribution - {p} {a}", "Systematic withdrawal {p}"], | |
| ["Cash-out of contract {p} {a}", "Contract termination proceeds {p}", "Annuity payout {p} {q}"]), | |
| "index_credit": ( | |
| ["Index credit - {p} {a}", "INDEX CREDIT {p} {d}", "{p} annual point-to-point credit {a}", "Interest credited - {p}", | |
| "Cap rate credit {p} {q}", "{p} - segment maturity credit", "Buffer segment credit {p} {a}"], | |
| ["Crediting strategy gain {p} {a}", "Indexed interest posted {p}", "Segment term credit {p} {q}"]), | |
| "note_coupon": ( | |
| ["Coupon payment - {n} {a}", "CPN {n}", "Contingent coupon paid {n} {d}", "Interest payment {n}", | |
| "COUPON {n} {a}", "{n} - periodic coupon"], | |
| ["Income observation paid {n} {a}", "Fixed coupon credited {n}"]), | |
| "note_call_maturity": ( | |
| ["Autocall redemption - {n} {a}", "CALLED {n} {d}", "Maturity proceeds - {n}", "{n} called at par plus coupon", | |
| "MATURITY {n} {a}", "Early redemption (autocall) {n}", "Principal repayment at maturity {n}"], | |
| ["Note terminated early {n} {a}", "Final settlement {n} {d}"]), | |
| "valuation_update": ( | |
| ["NAV statement {q} - {f} {a}", "Capital account balance {q} {f}", "{f} quarterly valuation {a}", "Market value update {p} {d}", | |
| "ENDING CAPITAL {f} {q}", "Contract value as of {d} {p}", "{f} - estimated NAV {q}", "Accumulation value {p} {a}"], | |
| ["Partner's capital at {q} - {f}", "Statement value {p} {a}", "Reported fair value {f} {q}"]), | |
| } | |
| def noise(s): | |
| r = random.random() | |
| if r < 0.15: | |
| s = s.upper() | |
| elif r < 0.22: | |
| s = s.lower() | |
| if random.random() < 0.08: # small typo | |
| i = random.randrange(len(s)) | |
| s = s[:i] + s[i + 1:] | |
| if random.random() < 0.15: | |
| s = random.choice(["WIRE IN ", "WIRE OUT ", "ACH ", "JNL ", "ACTIVITY: ", "REF#" + str(random.randint(100000, 999999)) + " "]) + s | |
| return " ".join(s.split()) | |
| def render(tpl, test): | |
| return noise(tpl.format(f=fund(test), p=policy(test), n=note(test), a=amt(), d=dt(), q=q(), k=random.randint(1, 14))) | |
| def build(n_train=700, n_test=150): | |
| train, test = [], [] | |
| for label in LABELS: | |
| tr_t, te_t = T[label] | |
| for _ in range(n_train): | |
| train.append({"text": render(random.choice(tr_t), False), "label": label}) | |
| for _ in range(n_test): | |
| # Test: unseen sponsors/carriers/issuers always; held-out phrasings half the time. | |
| unseen = random.random() < 0.5 | |
| tpl = random.choice(te_t) if unseen else random.choice(tr_t) | |
| test.append({"text": render(tpl, True), "label": label, | |
| "condition": "unseen_phrasing" if unseen else "unseen_entities"}) | |
| # Reviewer feedback: 10 items per label in the phrasings the model has not seen, labeled by | |
| # a person during exception review. Uses training-side entities, so test entities stay unseen. | |
| feedback = [{"text": render(random.choice(T[label][1]), False), "label": label} | |
| for label in LABELS for _ in range(10)] | |
| random.shuffle(train) | |
| random.shuffle(test) | |
| random.shuffle(feedback) | |
| return train, test, feedback | |
| def write(name, rows): | |
| with open(OUT / name, "w", newline="") as f: | |
| w = csv.DictWriter(f, fieldnames=list(rows[0].keys())) | |
| w.writeheader() | |
| w.writerows(rows) | |
| if __name__ == "__main__": | |
| tr, te, fb = build() | |
| write("train.csv", tr) | |
| write("test.csv", te) | |
| write("review_feedback.csv", fb) | |
| print(f"{len(tr)} train, {len(te)} test, {len(fb)} review feedback, {len(LABELS)} labels") | |