Text Classification
Transformers
Safetensors
English
roberta
industries
data-licensing
company-data
ai-training-data
text-embeddings-inference
Instructions to use aitrainingdatabroker/industry-page-classifier with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use aitrainingdatabroker/industry-page-classifier with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-classification", model="aitrainingdatabroker/industry-page-classifier")# pip install -U transformers accelerate # Load model directly from transformers import AutoTokenizer, AutoModelForSequenceClassification tokenizer = AutoTokenizer.from_pretrained("aitrainingdatabroker/industry-page-classifier") model = AutoModelForSequenceClassification.from_pretrained("aitrainingdatabroker/industry-page-classifier", device_map="auto") - Notebooks
- Google Colab
- Kaggle
Download source/gen_synth.py from aitrainingdatabroker/industry-page-classifier: direct link, hf CLI and curl.
- Browser
- Download file 32.4 kB
-
https://huggingface.co/aitrainingdatabroker/industry-page-classifier/resolve/main/source/gen_synth.py
- Command line
-
hf download hf://aitrainingdatabroker/industry-page-classifier/source/gen_synth.py
-
curl -L -o gen_synth.py https://huggingface.co/aitrainingdatabroker/industry-page-classifier/resolve/main/source/gen_synth.py
32.4 kB
| """Datasets 5 to 10 and the training files of models 4 to 10: invented text, no real person, company or secret (2026-10-30). | |
| python hf-work/gen_synth.py | |
| Each dataset is filled from templates. The TEST templates are never used for training, so a score measures new sentence | |
| shapes and not only new names. Names, companies and numbers are invented; phone numbers use the fictional 555-01xx range, | |
| emails use example domains, and keys carry a "demo" prefix. | |
| """ | |
| import json | |
| import random | |
| import string | |
| from pathlib import Path | |
| ROOT = Path(__file__).resolve().parent.parent | |
| rng = random.Random(20261030) | |
| FIRST = ["Marisol", "Dennick", "Aurelio", "Tamsin", "Liesel", "Bram", "Yusra", "Corwin", "Ilse", "Nadim", "Petra", "Ravindra", | |
| "Sunniva", "Teodor", "Wren", "Zaida", "Hollis", "Imogen", "Kasimir", "Delphine", "Ezio", "Odalys", "Fenwick", "Galen"] | |
| LAST = ["Quarrington", "Abernethy", "Okafor", "Lindqvist", "Marchetti", "Pemberton", "Szabo", "Thistlewood", "Hakimi", | |
| "Brannigan", "Castellanos", "Duchesne", "Fairweather", "Gruber", "Ishikawa", "Valdespino", "Nwosu", "Ostrander"] | |
| ORGS = ["Larkspur Logistics", "Copperfield Supply", "Harborview Dental", "Northgate Analytics", "Juniper Freight", "Ridgeway Builders", | |
| "Millbrook Software", "Ashford Insurance Group", "Kingsport Marine", "Willow Creek Foods", "Eastlake Clinics", | |
| "Brightwater Staffing", "Granite Peak Capital", "Fernhill Media", "Stonebridge Legal", "Tidewater Robotics"] | |
| STREETS = ["Larkspur Lane", "Copperfield Road", "Harbor View Drive", "Old Mill Court", "Juniper Street", "Ridgeway Avenue", | |
| "Elmhurst Boulevard", "Quarry Road", "Saltmarsh Way", "Pine Terrace"] | |
| CITIES = ["Brookhaven", "Millbrook", "Fairhaven", "Ashford", "Kingsport", "Willow Creek", "Eastlake", "Stonebridge", "Tidewater"] | |
| MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] | |
| DOMAINS = ["example.com", "example.org", "mail.example", "corp.example", "sample.test"] | |
| def person(): | |
| return f"{rng.choice(FIRST)} {rng.choice(LAST)}" | |
| def org(): | |
| return rng.choice(ORGS) | |
| def email(name=None): | |
| n = (name or person()).lower().replace(" ", ".") | |
| return f"{n}@{rng.choice(DOMAINS)}" | |
| def phone(): | |
| return f"(555) 01{rng.randint(0, 9)}-{rng.randint(1000, 9999)}" | |
| def address(): | |
| return f"{rng.randint(12, 980)} {rng.choice(STREETS)}, {rng.choice(CITIES)}" | |
| def date(): | |
| return f"{rng.choice(MONTHS)} {rng.randint(1, 28)}, {rng.randint(2024, 2026)}" | |
| def money(): | |
| return f"${rng.randint(120, 48000):,}.{rng.randint(0, 99):02d}" | |
| def code(prefix, n=6): | |
| return prefix + "".join(rng.choice(string.digits) for _ in range(n)) | |
| def key(): | |
| return "demo_key_" + "".join(rng.choice(string.ascii_lowercase + string.digits) for _ in range(20)) | |
| def ip(): | |
| return f"10.{rng.randint(0, 250)}.{rng.randint(0, 250)}.{rng.randint(2, 250)}" | |
| def write(kind, name, split, rows): | |
| out = ROOT / kind / name / "data" | |
| out.mkdir(parents=True, exist_ok=True) | |
| with open(out / f"{split}.jsonl", "w", encoding="utf-8", newline="\n") as f: | |
| for r in rows: | |
| f.write(json.dumps(r, ensure_ascii=False) + "\n") | |
| print(f"{kind}/{name}/{split}: {len(rows)} rows") | |
| PRE = ["", "", "Note: ", "FYI, ", "Quick one: ", "Following up. ", "Per our earlier message, ", "Hello. ", "To whom it may concern: ", "Sorry for the delay. "] | |
| SUF = ["", "", " Thanks.", " Please advise.", " Let me know.", " More detail on request.", " Regards.", " Appreciated."] | |
| def classification(name, label_field, train_t, test_t, fill, per_template, extra=None): | |
| """train_t / test_t: {label: [template, ...]}. Returns (train_rows, test_rows) and writes the dataset.""" | |
| out = {} | |
| for split, templates in (("train", train_t), ("test", test_t)): | |
| rows, seen = [], set() | |
| for label, tpls in templates.items(): | |
| for t in tpls: | |
| for _ in range(per_template): | |
| text = rng.choice(PRE) + t.format(**fill()) + rng.choice(SUF) | |
| if text in seen: | |
| continue | |
| seen.add(text) | |
| rows.append({"text": text, label_field: label, **({k: v(label) for k, v in extra.items()} if extra else {})}) | |
| rng.shuffle(rows) | |
| out[split] = rows | |
| return out | |
| def with_ids(prefix, rows): | |
| return [{"id": f"{prefix}-{i:04d}", **r} for i, r in enumerate(rows, 1)] | |
| def spans_from(segments): | |
| text, ents = "", [] | |
| for seg, lab in segments: | |
| if lab: | |
| ents.append({"label": lab, "start": len(text), "end": len(text) + len(seg)}) | |
| text += seg | |
| return {"text": text, "entities": ents} | |
| # ======================= dataset 5 and model 9: document sensitivity tier ======================= | |
| THING = ["the Q3 roadmap", "the onboarding guide", "the vendor list", "the pricing sheet", "the incident review", "the hiring plan", | |
| "the support playbook", "the launch plan", "the audit notes", "the budget draft", "the partner terms", "the training deck"] | |
| TEAM = ["support", "finance", "engineering", "sales", "operations", "legal", "people team", "marketing"] | |
| TIER_FILL = lambda: {"thing": rng.choice(THING), "team": rng.choice(TEAM), "org": org(), "n": rng.randint(3, 40), "month": rng.choice(MONTHS)} | |
| TIER_TRAIN = { | |
| "public": ["{org} announces {thing} in a press release for all media.", "Blog post for our website readers: how {team} works with customers.", | |
| "Published job listing for a {team} role, visible on our careers page.", "Public FAQ answer about opening hours and how to contact {team}.", | |
| "Product brochure PDF for download, approved by marketing for anyone.", "Social media post celebrating {n} years in business.", | |
| "Open-source release notes for version {n}, posted on our public repository.", "Conference talk slides cleared for the public audience."], | |
| "internal": ["Team update from {team}: {thing} moves to next sprint, share inside the company only.", "All-hands notes from {month}, for employees, not for customers.", | |
| "Internal wiki page on how {team} files expense reports.", "Slack thread where {team} compares tools; staff only.", | |
| "Meeting agenda for the weekly {team} sync and action items.", "Draft of {thing} circulating among managers for comment.", | |
| "Staff newsletter with office closures and training dates.", "Org chart and desk map for employees."], | |
| "confidential": ["Customer contract with {org} that names pricing, renewal terms and discounts.", "Revenue forecast for the board, not for release outside leadership.", | |
| "Unreleased {thing}, under embargo until the announcement.", "Supplier agreement with negotiated rates for {team}.", | |
| "Investor update with cash position and runway for {n} months.", "Source code of the billing service, access limited to engineers.", | |
| "Acquisition discussion notes with {org}, known to a handful of executives.", "Salary bands and bonus plan for {team}, shared with HR only."], | |
| "restricted": ["Patient records with names, diagnoses and insurance numbers, covered by health privacy law.", "Export of customer payment card numbers and billing addresses.", | |
| "Employee Social Security numbers and bank details held by payroll.", "Production database credentials and private signing keys for {thing}.", | |
| "Legal hold material under attorney-client privilege for a pending case.", "Unredacted identity documents scanned for {n} customers.", | |
| "Full customer database with emails, phone numbers and home addresses, un-de-identified.", "Security incident forensics naming affected accounts and exploited weaknesses."], | |
| } | |
| TIER_TEST = { | |
| "public": ["Newsletter issue for subscribers about {thing}, published openly.", "Open house invitation from {org}, posted for the neighbourhood."], | |
| "internal": ["Reminder to {team} staff about the holiday schedule and who covers the desk.", "Notes from {team}'s retrospective on {thing}, inside the company."], | |
| "confidential": ["Term sheet from {org}, only for the deal team.", "Customer churn analysis with account names and contract values."], | |
| "restricted": ["Spreadsheet of staff medical leave reasons and doctors' notes.", "Raw customer list with government ID numbers attached to {n} rows."], | |
| } | |
| r = classification("document-sensitivity-tiers", "label", TIER_TRAIN, TIER_TEST, TIER_FILL, 10) | |
| write("datasets", "synthetic-document-sensitivity-tiers", "train", with_ids("tier", [{"text": x["text"], "tier": x["label"]} for x in r["train"]])) | |
| write("datasets", "synthetic-document-sensitivity-tiers", "test", with_ids("tier-t", [{"text": x["text"], "tier": x["label"]} for x in r["test"]])) | |
| write("models", "document-sensitivity-tier-classifier", "train", r["train"]) | |
| write("models", "document-sensitivity-tier-classifier", "test", r["test"]) | |
| # ======================= dataset 6, models 4 and 10: contract clauses (type and risk) ======================= | |
| CL_FILL = lambda: {"a": rng.choice(["the Seller", "the Company", "Licensor"]), "b": rng.choice(["the Buyer", "the Lab", "Licensee"]), | |
| "n": rng.choice([30, 45, 60, 90, 180]), "y": rng.choice([1, 2, 3, 5]), "p": rng.choice(["thirty", "forty-five", "sixty", "ninety"])} | |
| CLAUSES = { # type -> (standard train, watch train, standard test, watch test) | |
| "exclusivity": (["{b} receives exclusive rights to the Dataset for {n} days, after which {a} may license it to others.", | |
| "During the exclusivity period of {n} days, {a} will not license the Dataset to any other party; the period ends on a fixed date."], | |
| ["{b} receives exclusive rights to the Dataset for all purposes, with no end date.", | |
| "{a} may never license the Dataset or anything derived from it to any other party, in any field."], | |
| ["Exclusivity applies for {y} year(s) and only to the named use, and {a} keeps all other rights."], | |
| ["The exclusive grant covers every future version of the Dataset and renews automatically without notice."]), | |
| "term_and_renewal": (["This Agreement lasts {y} year(s) and renews only if both parties agree in writing.", | |
| "The term is {y} year(s) from the effective date, and either party may decline renewal with {n} days' notice."], | |
| ["This Agreement renews automatically for successive {y}-year terms and {a} cannot end it.", | |
| "The term continues until {b} decides to stop, at its sole discretion."], | |
| ["The initial term is {y} year(s); renewal needs a signed amendment."], | |
| ["The license is perpetual and irrevocable and survives any breach by {b}."]), | |
| "payment": (["{b} pays the fee within {n} days of an invoice, by bank transfer, and late amounts accrue modest interest.", | |
| "The fee is due in stages: a deposit on signing and the balance on acceptance of the delivered data."], | |
| ["{b} may withhold payment for any reason until it is fully satisfied, with no deadline.", | |
| "Payment is due only after {b} has earned revenue from a model trained on the Dataset, and {a} cannot see those figures."], | |
| ["Invoices are payable within {n} days and disputes must be raised in writing within ten days."], | |
| ["Fees may be reduced by {b} at any time by notice, and refunds are due on request after delivery."]), | |
| "confidentiality": (["Each party keeps the other's confidential information private for {y} year(s) after the Agreement ends, with the usual exceptions.", | |
| "{b} will protect the Dataset with the care it gives its own secrets and limit access to those who need it."], | |
| ["{a} must keep every detail of this Agreement secret forever, even from its own advisers and auditors.", | |
| "{b} may disclose the Dataset to any third party without telling {a}."], | |
| ["Confidential information excludes what is public, already known or independently developed."], | |
| ["Confidentiality binds {a} only; {b} owes no duty of secrecy about anything it learns."]), | |
| "ip_and_ownership": (["{a} keeps ownership of the Dataset and grants {b} a limited license for the stated purpose.", | |
| "Models {b} trains remain {b}'s, and {a} keeps its rights in the source records."], | |
| ["Ownership of the Dataset passes to {b} on delivery, including all future records {a} creates.", | |
| "{b} owns everything {a} produces during the term, whether or not it relates to the Dataset."], | |
| ["The license is non-transferable and covers only the field of use set out in the schedule."], | |
| ["{a} assigns all present and future rights in its systems and records to {b} for no extra fee."]), | |
| "indemnity": (["Each party defends the other against claims caused by its own breach, up to a stated cap.", | |
| "{a} stands behind its statement that it has the right to license the Dataset, with liability capped at the fees paid."], | |
| ["{a} indemnifies {b} without any cap for every claim of any kind, including claims {b} causes.", | |
| "{a} pays {b}'s legal costs on any dispute, even where {a} wins."], | |
| ["Liability under this clause is limited to the fees paid in the {n} days before the claim."], | |
| ["{a} bears all liability for how {b} uses the Dataset after delivery, with no limit."]), | |
| "audit_and_deletion": (["{a} may ask once a year for a written confirmation of how the Dataset is used, and {b} deletes it at the end of the term.", | |
| "On request {b} confirms in writing that copies were deleted within {n} days."], | |
| ["{b} may keep the Dataset forever and {a} has no way to check how it is used.", | |
| "{b} may share the Dataset with its affiliates and partners and need not delete it."], | |
| ["At the end of the term {b} deletes the Dataset and certifies it, and {a} may audit once with notice."], | |
| ["There is no audit right and no duty to delete, even if {a} ends the Agreement for breach."]), | |
| "termination": (["Either party may end the Agreement for uncured breach after {n} days' written notice.", | |
| "{a} may end the Agreement if {b} misses a payment and does not fix it within {n} days."], | |
| ["Only {b} may end the Agreement, at any time, and keeps everything delivered.", | |
| "{a} cannot end the Agreement for any reason, including non-payment."], | |
| ["Termination for convenience needs {n} days' notice, and fees already earned stay payable."], | |
| ["On termination by {b}, all data already delivered stays with {b} and no fees are refunded or owed."]), | |
| } | |
| tr_t_type, te_t_type, tr_t_risk, te_t_risk = {}, {}, {"standard": [], "watch": []}, {"standard": [], "watch": []} | |
| rows_train, rows_test = [], [] | |
| for ctype, (s_tr, w_tr, s_te, w_te) in CLAUSES.items(): | |
| for tpls, risk, rows in ((s_tr, "standard", rows_train), (w_tr, "watch", rows_train), (s_te, "standard", rows_test), (w_te, "watch", rows_test)): | |
| seen = set() | |
| for t in tpls: | |
| for _ in range(12): | |
| text = rng.choice(PRE) + t.format(**CL_FILL()) + rng.choice(SUF) | |
| if text not in seen: | |
| seen.add(text) | |
| rows.append({"text": text, "clause_type": ctype, "risk": risk}) | |
| rng.shuffle(rows_train) | |
| rng.shuffle(rows_test) | |
| write("datasets", "synthetic-contract-clauses-by-type-and-risk", "train", with_ids("cl", rows_train)) | |
| write("datasets", "synthetic-contract-clauses-by-type-and-risk", "test", with_ids("cl-t", rows_test)) | |
| write("models", "contract-clause-type-classifier", "train", [{"text": x["text"], "label": x["clause_type"]} for x in rows_train]) | |
| write("models", "contract-clause-type-classifier", "test", [{"text": x["text"], "label": x["clause_type"]} for x in rows_test]) | |
| write("models", "contract-clause-risk-classifier", "train", [{"text": x["text"], "label": x["risk"]} for x in rows_train]) | |
| write("models", "contract-clause-risk-classifier", "test", [{"text": x["text"], "label": x["risk"]} for x in rows_test]) | |
| # ======================= dataset 7 and model 5: inbound inquiries by intent ======================= | |
| IQ_FILL = lambda: {"name": person(), "org": org(), "n": rng.choice([30, 45, 60, 120, 400]), "thing": rng.choice( | |
| ["support tickets", "CRM history", "design files", "call recordings", "team chat", "project records", "code reviews", "invoices"])} | |
| INTENT_TRAIN = { | |
| "seller_interest": ["Hi, I run {org} with about {n} staff. We have years of {thing}. Could we sell or license it to an AI lab?", | |
| "My company has a lot of {thing} sitting unused. How does licensing it work and what would you need from us?", | |
| "We are closing down {org} and want to know whether our {thing} has any value to AI companies.", | |
| "I saw your video. Does a firm of {n} people qualify, and who pays your fee?", | |
| "Our owners are open to licensing {thing}. What is the first step?", "Interested in learning how to monetise our archive of {thing}. Please call me."], | |
| "buyer_request": ["We are an AI lab looking for licensed {thing} from operating companies. Can you share what you have?", | |
| "Our model team needs a dataset of {thing}, de-identified, with clear rights. Do you source this?", | |
| "Looking to buy business records for training an agent. Which industries can you cover?", | |
| "As a buyer we want sample data before committing. How do you handle diligence?", | |
| "Please send what you can offer in {thing}; we have a budget this quarter.", "Our research group wants to license real-world {thing} and needs the rights confirmed."], | |
| "referral_offer": ["I know several owners with {thing}. How does your referral arrangement work?", | |
| "As a consultant I can introduce companies of {n} people. What do referrers receive?", | |
| "My accounting clients keep asking about selling their data. Can we partner on introductions?", | |
| "I run an M&A advisory and can bring wind-down companies. Do you work with referral partners?", | |
| "Happy to introduce owners if the terms are fair. Please send your partner details.", "We have a list of companies that may want to license {thing}; can we share it with you?"], | |
| "press_media": ["I am a reporter writing about AI training data. Could you give a comment on how licensing works?", | |
| "Our podcast would like to interview you about selling company data to AI labs.", | |
| "Writing a feature on data brokers for our newsletter; can we schedule a short call?", | |
| "Journalist here. Do you have figures on how many companies license their data?", | |
| "We would like to quote you in an article about {thing} and AI.", "An editor asked me to request an interview about your work."], | |
| "vendor_pitch": ["We offer lead generation and can fill your calendar with {n} meetings a month.", "Our agency does SEO and link building for sites like yours. Want a free audit?", | |
| "I can build you a website redesign at a discount this week.", "Our software helps companies like {org} automate outreach. Book a demo?", | |
| "We sell guest posts on high authority blogs; interested?", "Special offer on email lists for your campaigns, limited time."], | |
| "support_question": ["I filled in your form but did not get a reply. Can you check on it?", "How do I update the details I sent you last week?", | |
| "I cannot open the calculator result page. Could you help?", "Where do I find the checklist you mentioned in the video?", | |
| "I made an account, but I forgot which email I used. Can you help me sign in?", "The page says error when I submit my company information."], | |
| "opt_out": ["Please remove me from your list.", "Stop emailing me. I am not interested.", "Unsubscribe me and do not contact this address again.", | |
| "I did not ask for these messages. Take me off your list.", "Not interested, please delete my details.", "Remove {org} from your mailing list."], | |
| "spam": ["Congratulations, you have won a prize, click here to claim.", "Buy cheap watches and pills now, best prices guaranteed.", | |
| "Earn money fast from home, no skills needed, send your bank login.", "Your account is suspended, verify your password at the link.", | |
| "Hot singles near you want to meet tonight.", "Crypto giveaway, send one coin and get ten back."], | |
| } | |
| INTENT_TEST = { | |
| "seller_interest": ["We own a small agency, {n} employees, with {thing} going back years. Is there a market for this?", "Can {org} get paid for its {thing}? We would like an honest answer."], | |
| "buyer_request": ["Procurement at our lab is exploring licensed {thing}; what is your sourcing process?", "We are building an evaluation set and need real {thing} with permission."], | |
| "referral_offer": ["Do you pay a finder's fee if I connect you with a company of {n} staff?", "I advise owners on exits and would like to discuss working together on introductions."], | |
| "press_media": ["I cover AI for a trade magazine and need an expert on data licensing for a quote.", "Would you join our webinar to explain how companies sell {thing} to AI labs?"], | |
| "vendor_pitch": ["We help companies like {org} get more traffic with our paid promotion package.", "Our team can create videos for your channel at a fraction of the usual cost."], | |
| "support_question": ["The link in your email does not work for me. Can you resend it?", "I need to correct a number I entered on the form. How do I do that?"], | |
| "opt_out": ["Kindly take {org} off all further messages.", "I would like no further contact. Please confirm you removed me."], | |
| "spam": ["Winner! Claim your free gift card by entering your card details here.", "Invest now and double your money in a week, guaranteed returns."], | |
| } | |
| r = classification("inquiries", "label", INTENT_TRAIN, INTENT_TEST, IQ_FILL, 10) | |
| write("datasets", "synthetic-inbound-inquiries-by-intent", "train", with_ids("inq", [{"text": x["text"], "intent": x["label"]} for x in r["train"]])) | |
| write("datasets", "synthetic-inbound-inquiries-by-intent", "test", with_ids("inq-t", [{"text": x["text"], "intent": x["label"]} for x in r["test"]])) | |
| write("models", "inbound-inquiry-intent-classifier", "train", r["train"]) | |
| write("models", "inbound-inquiry-intent-classifier", "test", r["test"]) | |
| # ======================= dataset 8 and model 6: invoice and purchase order text with personal and account details ======================= | |
| def inv_fill(): | |
| return {"p": person(), "o": org(), "e": email(), "ph": phone(), "ad": address(), "d": date(), "m": money(), "i": code("INV-"), "ac": code("", 10), "t": code("", 9)} | |
| def spans_template(parts): | |
| """parts: list of (text-or-slot, label). Slot names in braces fill from `fill`.""" | |
| return parts | |
| INV_TRAIN = [ | |
| [("Invoice ", None), ("{i}", "INVOICE_ID"), (" issued ", None), ("{d}", "DATE"), (" to ", None), ("{o}", "ORG"), (", attn ", None), ("{p}", "PERSON"), (". Amount due ", None), ("{m}", "MONEY"), (".", None)], | |
| [("Bill to: ", None), ("{p}", "PERSON"), (", ", None), ("{ad}", "ADDRESS"), (". Contact ", None), ("{e}", "EMAIL"), (" or ", None), ("{ph}", "PHONE"), (". Total ", None), ("{m}", "MONEY"), (".", None)], | |
| [("Please remit ", None), ("{m}", "MONEY"), (" to account ", None), ("{ac}", "BANK_ACCOUNT"), (" by ", None), ("{d}", "DATE"), (" quoting ", None), ("{i}", "INVOICE_ID"), (".", None)], | |
| [("Vendor: ", None), ("{o}", "ORG"), (" (tax ID ", None), ("{t}", "TAX_ID"), ("). Remit to ", None), ("{ad}", "ADDRESS"), (".", None)], | |
| [("Purchase order ", None), ("{i}", "INVOICE_ID"), (" approved by ", None), ("{p}", "PERSON"), (" on ", None), ("{d}", "DATE"), (" for ", None), ("{m}", "MONEY"), (".", None)], | |
| [("Questions about this invoice? Email ", None), ("{e}", "EMAIL"), (" or call ", None), ("{ph}", "PHONE"), (". Ref ", None), ("{i}", "INVOICE_ID"), (".", None)], | |
| [("Payment received from ", None), ("{o}", "ORG"), (" on ", None), ("{d}", "DATE"), (", ", None), ("{m}", "MONEY"), (", from account ending ", None), ("{ac}", "BANK_ACCOUNT"), (".", None)], | |
| ] | |
| INV_TEST = [ | |
| [("Statement for ", None), ("{p}", "PERSON"), (" at ", None), ("{o}", "ORG"), (": balance ", None), ("{m}", "MONEY"), (", due ", None), ("{d}", "DATE"), (".", None)], | |
| [("Wire details: account ", None), ("{ac}", "BANK_ACCOUNT"), (", beneficiary ", None), ("{o}", "ORG"), (", tax number ", None), ("{t}", "TAX_ID"), (".", None)], | |
| [("Ship to ", None), ("{ad}", "ADDRESS"), (" for ", None), ("{p}", "PERSON"), (", phone ", None), ("{ph}", "PHONE"), (", order ", None), ("{i}", "INVOICE_ID"), (".", None)], | |
| [("Credit note ", None), ("{i}", "INVOICE_ID"), (" of ", None), ("{m}", "MONEY"), (" sent to ", None), ("{e}", "EMAIL"), (" on ", None), ("{d}", "DATE"), (".", None)], | |
| ] | |
| def render_spans(templates, per, fill): | |
| rows, seen = [], set() | |
| for tpl in templates: | |
| for _ in range(per): | |
| f = fill() | |
| seg = [] | |
| for text, lab in tpl: | |
| seg.append((text.format(**f) if "{" in text else text, lab)) | |
| row = spans_from(seg) | |
| if row["text"] not in seen: | |
| seen.add(row["text"]) | |
| rows.append(row) | |
| rng.shuffle(rows) | |
| return rows | |
| tr, te = render_spans(INV_TRAIN, 40, inv_fill), render_spans(INV_TEST, 30, inv_fill) | |
| write("datasets", "synthetic-invoice-pii-spans", "train", with_ids("inv", tr)) | |
| write("datasets", "synthetic-invoice-pii-spans", "test", with_ids("inv-t", te)) | |
| write("models", "invoice-pii-detector", "train", tr) | |
| write("models", "invoice-pii-detector", "test", te) | |
| # ======================= dataset 9 and model 7: chat logs with personal and technical identifiers ======================= | |
| def chat_fill(): | |
| return {"p": person(), "p2": person(), "e": email(), "ph": phone(), "k": key(), "ip": ip(), "t": code("TCK-", 5)} | |
| CHAT_TRAIN = [ | |
| [("[10:42] ", None), ("{p}", "PERSON"), (": can you email the file to ", None), ("{e}", "EMAIL"), (" before lunch?", None)], | |
| [("[14:03] ", None), ("{p}", "PERSON"), (": customer rang from ", None), ("{ph}", "PHONE"), (", ticket is ", None), ("{t}", "ID_NUMBER"), (".", None)], | |
| [("oops I pasted the key in here: ", None), ("{k}", "API_KEY"), (" please rotate it", None)], | |
| [("{p}", "PERSON"), (" > the server at ", None), ("{ip}", "IP_ADDRESS"), (" keeps timing out again", None)], | |
| [("@", None), ("{p2}", "PERSON"), (" can you take ", None), ("{t}", "ID_NUMBER"), ("? ", None), ("{p}", "PERSON"), (" is out today", None)], | |
| [("Reach me on ", None), ("{ph}", "PHONE"), (" if the deploy fails, or ", None), ("{e}", "EMAIL"), (".", None)], | |
| [("config line: token=", None), ("{k}", "API_KEY"), (" host=", None), ("{ip}", "IP_ADDRESS")], | |
| [("thanks ", None), ("{p2}", "PERSON"), (", closing ", None), ("{t}", "ID_NUMBER"), (" now", None)], | |
| ] | |
| CHAT_TEST = [ | |
| [("DM from ", None), ("{p}", "PERSON"), (": my login is ", None), ("{e}", "EMAIL"), (", the old box is ", None), ("{ip}", "IP_ADDRESS")], | |
| [("Heads up ", None), ("{p2}", "PERSON"), (": api secret ", None), ("{k}", "API_KEY"), (" is in the wiki page, remove it", None)], | |
| [("call ", None), ("{p}", "PERSON"), (" on ", None), ("{ph}", "PHONE"), (" about ", None), ("{t}", "ID_NUMBER")], | |
| [("{p}", "PERSON"), (" and ", None), ("{p2}", "PERSON"), (" are both cc'd at ", None), ("{e}", "EMAIL")], | |
| ] | |
| tr, te = render_spans(CHAT_TRAIN, 45, chat_fill), render_spans(CHAT_TEST, 35, chat_fill) | |
| write("datasets", "synthetic-chat-logs-pii-spans", "train", with_ids("chat", tr)) | |
| write("datasets", "synthetic-chat-logs-pii-spans", "test", with_ids("chat-t", te)) | |
| write("models", "chat-log-pii-detector", "train", tr) | |
| write("models", "chat-log-pii-detector", "test", te) | |
| # ======================= dataset 10 and model 8: sales call notes by outcome ======================= | |
| CALL_FILL = lambda: {"name": person(), "org": org(), "n": rng.choice([2, 3, 4, 6]), "w": rng.choice(["Friday", "next Tuesday", "the 14th", "end of month"]), | |
| "thing": rng.choice(["the pilot", "the proposal", "the quote", "the demo", "the sample"])} | |
| OUT_TRAIN = { | |
| "advanced": ["Spoke with {name} at {org}. Liked {thing}, wants a second call with the team on {w}.", "{name} asked for a written proposal and named two colleagues to join the next meeting.", | |
| "Good fit confirmed. {org} will send access for {thing} and we booked a review on {w}.", "Budget approved in principle by {name}; next step is the security questionnaire.", | |
| "{name} introduced us to legal at {org}. Drafting terms this week.", "Strong interest. They want {thing} reworked for their data and will reply by {w}."], | |
| "stalled": ["{name} said the team is busy and to check back after {w}. No date set.", "Waiting on {org} to reply to the last {n} emails. Nothing since the call.", | |
| "{name} likes it but needs sign-off from a person they cannot name yet.", "Pushed back to next quarter by {org}; no owner for {thing}.", | |
| "Left a voicemail twice for {name}. Still no answer on {thing}.", "Interest is real but their priorities changed and the project is on hold."], | |
| "lost": ["{name} told us {org} chose another provider and will not continue.", "Price was too high for {org}; {name} closed the file.", | |
| "{org} decided to build it in house, so no further calls are needed.", "{name} said it is not a fit for their size and asked us to stop following up.", | |
| "Legal at {org} refused the data terms and the deal ended.", "{name} replied that they have no interest in {thing} and no budget now or later."], | |
| "won": ["{name} signed the agreement for {org} and we start on {w}.", "Contract returned countersigned by {org}; invoice sent for {thing}.", | |
| "{org} confirmed the order after {thing} and payment is scheduled for {w}.", "{name} approved the final terms; kickoff booked with {n} people from their side.", | |
| "Deal closed. {org} signed, and first delivery is planned for {w}.", "Signed today. {name} thanked the team and asked for the onboarding pack."], | |
| } | |
| OUT_TEST = { | |
| "advanced": ["{name} wants {thing} sent to their technical lead before the next call with {org}.", "They asked for references and set a follow-up for {w}."], | |
| "stalled": ["No response from {org} after the proposal; last contact was {n} weeks ago.", "{name} is travelling and said to try again later without giving a date."], | |
| "lost": ["{org} went with a cheaper alternative, according to {name}.", "{name} said the project was cancelled and {org} no longer needs this."], | |
| "won": ["{org} has accepted the quote and {name} sent the purchase order.", "We got the yes from {name}; paperwork is complete."], | |
| } | |
| r = classification("calls", "label", OUT_TRAIN, OUT_TEST, CALL_FILL, 10) | |
| write("datasets", "synthetic-sales-call-notes-by-outcome", "train", with_ids("call", [{"text": x["text"], "outcome": x["label"]} for x in r["train"]])) | |
| write("datasets", "synthetic-sales-call-notes-by-outcome", "test", with_ids("call-t", [{"text": x["text"], "outcome": x["label"]} for x in r["test"]])) | |
| write("models", "sales-call-outcome-classifier", "train", r["train"]) | |
| write("models", "sales-call-outcome-classifier", "test", r["test"]) | |