Upload folder using huggingface_hub
Browse files- LEARN.md +813 -0
- README.md +7 -1
- push_to_hf.py +19 -3
- search/README.md +54 -0
LEARN.md
ADDED
|
@@ -0,0 +1,813 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
language:
|
| 3 |
+
- en
|
| 4 |
+
license: apache-2.0
|
| 5 |
+
tags:
|
| 6 |
+
- insurance
|
| 7 |
+
- machine-learning
|
| 8 |
+
- transformers
|
| 9 |
+
- llm
|
| 10 |
+
- qlora
|
| 11 |
+
- ner
|
| 12 |
+
- xgboost
|
| 13 |
+
- glm
|
| 14 |
+
- educational
|
| 15 |
+
- bytical
|
| 16 |
+
---
|
| 17 |
+
|
| 18 |
+
# Learn INSUREOS from Scratch
|
| 19 |
+
|
| 20 |
+
This guide explains the INSUREOS project in plain English for users who are new to machine learning, insurance AI, or both. It is based on the walkthrough and explanations we developed while reviewing the real training code in this repository.
|
| 21 |
+
|
| 22 |
+
## Why this project is split across multiple Hugging Face repos
|
| 23 |
+
|
| 24 |
+
The INSUREOS project is published in separate repos on Hugging Face because each repo serves a different purpose:
|
| 25 |
+
|
| 26 |
+
- **Model repos** contain model weights, tokenizer files, metadata, and a model card.
|
| 27 |
+
- **Dataset repo** contains the generated training datasets.
|
| 28 |
+
- **Code repo** contains the actual training, evaluation, serving, and data-generation code.
|
| 29 |
+
- **Search repo** contains the hybrid search engine files and documentation.
|
| 30 |
+
|
| 31 |
+
This is why a model page may not show Python training scripts directly. The code lives in the shared code repo:
|
| 32 |
+
|
| 33 |
+
- **Code repo:** [piyushptiwari/insureos-models](https://huggingface.co/piyushptiwari/insureos-models)
|
| 34 |
+
- **Dataset repo:** [piyushptiwari/insureos-training-data](https://huggingface.co/datasets/piyushptiwari/insureos-training-data)
|
| 35 |
+
- **Search repo:** [piyushptiwari/insureos-search-engine](https://huggingface.co/piyushptiwari/insureos-search-engine)
|
| 36 |
+
|
| 37 |
+
## The 5 main learning modules
|
| 38 |
+
|
| 39 |
+
We walked through the INSUREOS codebase in the same order someone new to ML would learn it.
|
| 40 |
+
|
| 41 |
+
### M1. Pricing Models: GLM and EBM
|
| 42 |
+
|
| 43 |
+
Code:
|
| 44 |
+
- [training/pricing_glm.py](https://huggingface.co/piyushptiwari/insureos-models/blob/main/training/pricing_glm.py)
|
| 45 |
+
- Data: [claims_motor_25000k.csv](https://huggingface.co/datasets/piyushptiwari/insureos-training-data/blob/main/claims_motor_25000k.csv)
|
| 46 |
+
|
| 47 |
+
What this model does:
|
| 48 |
+
- Predicts insurance premium or claim-related pricing outcomes from tabular policy data.
|
| 49 |
+
|
| 50 |
+
Core concepts:
|
| 51 |
+
- **Tabular ML**: rows and columns like a spreadsheet.
|
| 52 |
+
- **Feature engineering**: create useful derived variables such as vehicle age and no-claims ratios.
|
| 53 |
+
- **GLM**: a generalized linear model, common in insurance pricing.
|
| 54 |
+
- **Tweedie distribution**: useful when targets behave like a mix of frequency and severity.
|
| 55 |
+
- **EBM**: Explainable Boosting Machine, a glass-box model that stays interpretable.
|
| 56 |
+
|
| 57 |
+
Why it matters:
|
| 58 |
+
- This is the most traditional insurance ML workflow in the repo.
|
| 59 |
+
- It shows how actuaries and pricing teams often work with structured data.
|
| 60 |
+
|
| 61 |
+
### M2. Fraud Detection: XGBoost and Isolation Forest
|
| 62 |
+
|
| 63 |
+
Code:
|
| 64 |
+
- [training/fraud_model.py](https://huggingface.co/piyushptiwari/insureos-models/blob/main/training/fraud_model.py)
|
| 65 |
+
- Data: [claims_all_50000.jsonl](https://huggingface.co/datasets/piyushptiwari/insureos-training-data/blob/main/claims_all_50000.jsonl)
|
| 66 |
+
|
| 67 |
+
What this model does:
|
| 68 |
+
- Scores claims for fraud risk across Motor, Property, and Liability.
|
| 69 |
+
|
| 70 |
+
Core concepts:
|
| 71 |
+
- **Decision trees** and **gradient boosting**.
|
| 72 |
+
- **XGBoost** as a strong tabular classifier.
|
| 73 |
+
- **Class imbalance**: fraud is rare, so metrics like accuracy can mislead.
|
| 74 |
+
- **Isolation Forest**: unsupervised anomaly detection for unusual claims.
|
| 75 |
+
- **AUC, precision, recall, F1**: metrics for imbalanced classification.
|
| 76 |
+
|
| 77 |
+
Important teaching note:
|
| 78 |
+
- In this project, many synthetic datasets score almost perfectly. That is a useful warning sign in ML: perfect performance often means the problem is unrealistically easy, synthetic, or has leakage.
|
| 79 |
+
|
| 80 |
+
### M3. Document Classification with ModernBERT
|
| 81 |
+
|
| 82 |
+
Code:
|
| 83 |
+
- [training/doc_classifier.py](https://huggingface.co/piyushptiwari/insureos-models/blob/main/training/doc_classifier.py)
|
| 84 |
+
- Data: [insurance_docs_10k.jsonl](https://huggingface.co/datasets/piyushptiwari/insureos-training-data/blob/main/insurance_docs_10k.jsonl)
|
| 85 |
+
|
| 86 |
+
What this model does:
|
| 87 |
+
- Reads an insurance document and predicts one of 12 classes, such as policy wording, claim form, or renewal notice.
|
| 88 |
+
|
| 89 |
+
Core concepts:
|
| 90 |
+
- **Transformers** and **self-attention**.
|
| 91 |
+
- **Tokenization**: breaking text into model-readable pieces.
|
| 92 |
+
- **Embeddings**: turning tokens into vectors.
|
| 93 |
+
- **Sequence classification**: one label for the whole document.
|
| 94 |
+
- **Fine-tuning** a pretrained language model.
|
| 95 |
+
|
| 96 |
+
Key takeaway:
|
| 97 |
+
- This is the bridge from traditional ML to NLP. The model is no longer using fixed hand-made columns; it learns directly from text.
|
| 98 |
+
|
| 99 |
+
### M4. Named Entity Recognition with ModernBERT
|
| 100 |
+
|
| 101 |
+
Code:
|
| 102 |
+
- [training/ner_model.py](https://huggingface.co/piyushptiwari/insureos-models/blob/main/training/ner_model.py)
|
| 103 |
+
- Data: [insurance_ner_8k.jsonl](https://huggingface.co/datasets/piyushptiwari/insureos-training-data/blob/main/insurance_ner_8k.jsonl)
|
| 104 |
+
|
| 105 |
+
What this model does:
|
| 106 |
+
- Labels each token in insurance text with entity tags such as `PERSON`, `INSURER`, `CLAIM_NUMBER`, or `DATE`.
|
| 107 |
+
|
| 108 |
+
Core concepts:
|
| 109 |
+
- **Token classification** instead of document classification.
|
| 110 |
+
- **BIO tagging**: `B-`, `I-`, and `O` labels.
|
| 111 |
+
- **Subword alignment**: one word can become multiple tokenizer pieces.
|
| 112 |
+
- **`-100` ignore label** for special tokens and ignored positions.
|
| 113 |
+
- **Seqeval metrics**: entity-level precision, recall, and F1.
|
| 114 |
+
|
| 115 |
+
Key takeaway:
|
| 116 |
+
- This is how the project turns messy text into structured data fields.
|
| 117 |
+
|
| 118 |
+
### M5. LLM Fine-Tuning with QLoRA
|
| 119 |
+
|
| 120 |
+
Code:
|
| 121 |
+
- [training/qlora_finetune.py](https://huggingface.co/piyushptiwari/insureos-models/blob/main/training/qlora_finetune.py)
|
| 122 |
+
- [training/dpo_train.py](https://huggingface.co/piyushptiwari/insureos-models/blob/main/training/dpo_train.py)
|
| 123 |
+
- Data: [insurance_sft_10k.jsonl](https://huggingface.co/datasets/piyushptiwari/insureos-training-data/blob/main/insurance_sft_10k.jsonl)
|
| 124 |
+
- Data: [insurance_dpo_5k.jsonl](https://huggingface.co/datasets/piyushptiwari/insureos-training-data/blob/main/insurance_dpo_5k.jsonl)
|
| 125 |
+
|
| 126 |
+
What this model does:
|
| 127 |
+
- Fine-tunes Qwen3-4B to generate insurance-domain answers, claims assessments, and other structured text outputs.
|
| 128 |
+
|
| 129 |
+
Core concepts:
|
| 130 |
+
- **Causal language modeling**: predict the next token.
|
| 131 |
+
- **Autoregressive generation**: write text one token at a time.
|
| 132 |
+
- **Chat templates**: convert system/user/assistant messages into model input.
|
| 133 |
+
- **SFT**: supervised fine-tuning on good examples.
|
| 134 |
+
- **DPO**: preference optimization, teaching the model which answer is better.
|
| 135 |
+
- **QLoRA**: memory-efficient fine-tuning using quantization plus LoRA adapters.
|
| 136 |
+
- **Gradient accumulation** and **gradient checkpointing** to fit large models on smaller GPUs.
|
| 137 |
+
|
| 138 |
+
Key takeaway:
|
| 139 |
+
- This is the stage where the project becomes a real domain-specific assistant instead of a classifier.
|
| 140 |
+
|
| 141 |
+
## The mental model for the whole project
|
| 142 |
+
|
| 143 |
+
Think of INSUREOS as a full insurance AI stack:
|
| 144 |
+
|
| 145 |
+
- **Data generators** create training datasets.
|
| 146 |
+
- **Training scripts** teach different model types.
|
| 147 |
+
- **Evaluation scripts** measure quality.
|
| 148 |
+
- **Serving code** exposes the models by API.
|
| 149 |
+
- **Search engine** gives retrieval and document search.
|
| 150 |
+
|
| 151 |
+
Each model handles a different insurance operations task:
|
| 152 |
+
|
| 153 |
+
- **InsurePricing**: predict price-related outcomes.
|
| 154 |
+
- **InsureFraudNet**: flag suspicious claims.
|
| 155 |
+
- **InsureDocClassifier**: route document types.
|
| 156 |
+
- **InsureNER**: extract structured entities from text.
|
| 157 |
+
- **InsureLLM-4B**: answer and generate insurance-domain text.
|
| 158 |
+
- **InsureSearch**: retrieve the right source material.
|
| 159 |
+
|
| 160 |
+
## If you are new to ML, learn in this order
|
| 161 |
+
|
| 162 |
+
1. Start with tabular models: pricing and fraud.
|
| 163 |
+
2. Move to NLP classifiers: document classification.
|
| 164 |
+
3. Then study token labeling: NER.
|
| 165 |
+
4. Then study generation: LLM fine-tuning with QLoRA and DPO.
|
| 166 |
+
5. Finally connect everything with retrieval, serving, and evaluation.
|
| 167 |
+
|
| 168 |
+
## Where to go next
|
| 169 |
+
|
| 170 |
+
- Start with the code repo overview: [README.md](https://huggingface.co/piyushptiwari/insureos-models/blob/main/README.md)
|
| 171 |
+
- Explore training scripts: [training/](https://huggingface.co/piyushptiwari/insureos-models/tree/main/training)
|
| 172 |
+
- Explore data generators: [data/](https://huggingface.co/piyushptiwari/insureos-models/tree/main/data)
|
| 173 |
+
- Explore retrieval: [search/](https://huggingface.co/piyushptiwari/insureos-models/tree/main/search)
|
| 174 |
+
|
| 175 |
+
## Short answer to the original HF question
|
| 176 |
+
|
| 177 |
+
If you were wondering why model pages did not show all the code and explanations:
|
| 178 |
+
|
| 179 |
+
- The model repos are intentionally weight-focused.
|
| 180 |
+
- The actual Python code lives in the shared code repo.
|
| 181 |
+
- The learning guide you are reading now is meant to make that split understandable for users.
|
| 182 |
+
# INSUREOS Learning Guide
|
| 183 |
+
|
| 184 |
+
This guide is for readers who land on the Hugging Face pages and want to understand:
|
| 185 |
+
|
| 186 |
+
- what each INSUREOS model does
|
| 187 |
+
- which code file trains it
|
| 188 |
+
- what data it uses
|
| 189 |
+
- how the ideas fit together from scratch
|
| 190 |
+
|
| 191 |
+
It is based on a step-by-step teaching walkthrough of this project, rewritten as a clean reader guide rather than a chat transcript.
|
| 192 |
+
|
| 193 |
+
## Start Here: Why HF Has Multiple Repos
|
| 194 |
+
|
| 195 |
+
INSUREOS is intentionally split across separate Hugging Face repos:
|
| 196 |
+
|
| 197 |
+
- `piyushptiwari/InsureLLM-4B`, `InsureDocClassifier`, `InsureNER`, `InsureFraudNet`, `InsurePricing`: model artifacts and model cards
|
| 198 |
+
- `piyushptiwari/insureos-models`: source code for training, evaluation, serving, and search
|
| 199 |
+
- `piyushptiwari/insureos-training-data`: generated datasets used by the models
|
| 200 |
+
|
| 201 |
+
That is why a model page may show weights and a README but no Python training files. The code lives in the shared code repo.
|
| 202 |
+
|
| 203 |
+
## Project Map
|
| 204 |
+
|
| 205 |
+
If you want the shortest path through the codebase, read these directories in order:
|
| 206 |
+
|
| 207 |
+
1. [data/](data) for data generation
|
| 208 |
+
2. [training/](training) for model training
|
| 209 |
+
3. [evaluation/](evaluation) for metrics and reports
|
| 210 |
+
4. [search/](search) for the hybrid retrieval engine
|
| 211 |
+
5. [serve/](serve) for inference APIs
|
| 212 |
+
|
| 213 |
+
## M0. Machine Learning Basics
|
| 214 |
+
|
| 215 |
+
Before the individual models, here is the minimum mental model:
|
| 216 |
+
|
| 217 |
+
- A model learns a mapping from inputs to outputs.
|
| 218 |
+
- Training means adjusting parameters to reduce a loss.
|
| 219 |
+
- Evaluation means checking generalization on held-out data.
|
| 220 |
+
- Different tasks need different model families:
|
| 221 |
+
- tabular regression for pricing
|
| 222 |
+
- tabular classification for fraud
|
| 223 |
+
- sequence classification for document type
|
| 224 |
+
- token classification for NER
|
| 225 |
+
- causal language modeling for long-form text generation
|
| 226 |
+
|
| 227 |
+
Three habits matter throughout this repository:
|
| 228 |
+
|
| 229 |
+
1. Always inspect the data shape before trusting metrics.
|
| 230 |
+
2. Perfect scores on synthetic data are a warning sign, not a victory lap.
|
| 231 |
+
3. Start from the problem type, then choose the model family.
|
| 232 |
+
|
| 233 |
+
## M1. Pricing Models: GLM and EBM
|
| 234 |
+
|
| 235 |
+
Training code: [training/pricing_glm.py](training/pricing_glm.py)
|
| 236 |
+
|
| 237 |
+
Data used:
|
| 238 |
+
|
| 239 |
+
- [data/output/claims_motor_25000k.csv](data/output/claims_motor_25000k.csv)
|
| 240 |
+
|
| 241 |
+
Main idea:
|
| 242 |
+
|
| 243 |
+
- This is a tabular regression problem: predict premium or claim-related value from structured features.
|
| 244 |
+
- The repository trains two pricing models:
|
| 245 |
+
- Tweedie GLM: the standard actuarial-style linear model for insurance pricing
|
| 246 |
+
- EBM: an interpretable boosting model with learned shape functions
|
| 247 |
+
|
| 248 |
+
Core concepts:
|
| 249 |
+
|
| 250 |
+
- A GLM extends linear regression to non-Gaussian targets.
|
| 251 |
+
- Tweedie is useful in insurance because it can model frequency and severity behavior.
|
| 252 |
+
- A log link means the model predicts on a transformed scale and then maps back.
|
| 253 |
+
- EBM keeps strong performance while staying inspectable.
|
| 254 |
+
|
| 255 |
+
Features include driver age, years driving, vehicle value, mileage, excesses, claims history, and engineered variables such as:
|
| 256 |
+
|
| 257 |
+
- `vehicle_age`
|
| 258 |
+
- `driver_experience_ratio`
|
| 259 |
+
- `ncd_ratio`
|
| 260 |
+
|
| 261 |
+
Why it matters:
|
| 262 |
+
|
| 263 |
+
- This is the most classical ML in the repo.
|
| 264 |
+
- It teaches feature engineering, target distributions, interpretability, and regression metrics.
|
| 265 |
+
|
| 266 |
+
## M2. Fraud Detection: XGBoost and Isolation Forest
|
| 267 |
+
|
| 268 |
+
Training code: [training/fraud_model.py](training/fraud_model.py)
|
| 269 |
+
|
| 270 |
+
Data used:
|
| 271 |
+
|
| 272 |
+
- [data/output/claims_all_50000.jsonl](data/output/claims_all_50000.jsonl)
|
| 273 |
+
- [data/output/claims_motor_25000k.csv](data/output/claims_motor_25000k.csv)
|
| 274 |
+
- [data/output/claims_property_15000k.csv](data/output/claims_property_15000k.csv)
|
| 275 |
+
- [data/output/claims_liability_10000k.csv](data/output/claims_liability_10000k.csv)
|
| 276 |
+
|
| 277 |
+
Main idea:
|
| 278 |
+
|
| 279 |
+
- This is a tabular classification problem: predict whether a claim is fraudulent.
|
| 280 |
+
- The repository combines two approaches:
|
| 281 |
+
- XGBoost for supervised fraud probability
|
| 282 |
+
- Isolation Forest for unsupervised anomaly detection
|
| 283 |
+
|
| 284 |
+
Core concepts:
|
| 285 |
+
|
| 286 |
+
- Decision trees split on features to separate normal and suspicious claims.
|
| 287 |
+
- Gradient boosting builds many trees that correct earlier mistakes.
|
| 288 |
+
- Class imbalance matters because fraud is rare.
|
| 289 |
+
- `scale_pos_weight` helps the model take the minority class seriously.
|
| 290 |
+
|
| 291 |
+
Important practical lesson:
|
| 292 |
+
|
| 293 |
+
- The saved scores are extremely high on this synthetic data.
|
| 294 |
+
- In real ML work, suspiciously perfect AUC or F1 often means the task is too easy, features leak the answer, or the synthetic data is cleaner than production reality.
|
| 295 |
+
|
| 296 |
+
Why it matters:
|
| 297 |
+
|
| 298 |
+
- This module teaches tree-based ML, feature importance, anomaly detection, and rare-event evaluation.
|
| 299 |
+
|
| 300 |
+
## M3. Document Classification: ModernBERT
|
| 301 |
+
|
| 302 |
+
Training code: [training/doc_classifier.py](training/doc_classifier.py)
|
| 303 |
+
|
| 304 |
+
Data used:
|
| 305 |
+
|
| 306 |
+
- [data/output/insurance_docs_10k.jsonl](data/output/insurance_docs_10k.jsonl)
|
| 307 |
+
|
| 308 |
+
Main idea:
|
| 309 |
+
|
| 310 |
+
- This is sequence classification: read a whole document and output one label.
|
| 311 |
+
- The model predicts one of 12 document types such as claim form, policy wording, bordereaux, renewal notice, and FNOL report.
|
| 312 |
+
|
| 313 |
+
Core concepts:
|
| 314 |
+
|
| 315 |
+
- A tokenizer converts text into token ids.
|
| 316 |
+
- A transformer encoder produces contextual representations.
|
| 317 |
+
- A classification head maps the final representation to one class.
|
| 318 |
+
- Fine-tuning means starting from a pretrained language model and adapting it to a narrower task.
|
| 319 |
+
|
| 320 |
+
Why it matters:
|
| 321 |
+
|
| 322 |
+
- This is the simplest transformer task in the project.
|
| 323 |
+
- It is the bridge from classical ML to deep NLP.
|
| 324 |
+
|
| 325 |
+
## M4. NER: Label Every Word
|
| 326 |
+
|
| 327 |
+
Training code: [training/ner_model.py](training/ner_model.py)
|
| 328 |
+
|
| 329 |
+
Data used:
|
| 330 |
+
|
| 331 |
+
- [data/output/insurance_ner_8k.jsonl](data/output/insurance_ner_8k.jsonl)
|
| 332 |
+
- [data/constants.py](data/constants.py)
|
| 333 |
+
|
| 334 |
+
Main idea:
|
| 335 |
+
|
| 336 |
+
- NER is token classification: instead of assigning one label to the whole text, the model assigns a label to each word or subword.
|
| 337 |
+
- Example entity types include insurer, person, policy number, claim number, regulation, money, date, postcode, and peril.
|
| 338 |
+
|
| 339 |
+
Core concepts:
|
| 340 |
+
|
| 341 |
+
- BIO tagging:
|
| 342 |
+
- `B-XXX` means the beginning of an entity
|
| 343 |
+
- `I-XXX` means continuation of that entity
|
| 344 |
+
- `O` means outside any entity
|
| 345 |
+
- Tokenizers split words into subwords, so labels must be aligned carefully.
|
| 346 |
+
- The training code uses `word_ids()` and `-100` to ignore special tokens during loss computation.
|
| 347 |
+
- Entity-level metrics matter more than raw token accuracy.
|
| 348 |
+
|
| 349 |
+
Why it matters:
|
| 350 |
+
|
| 351 |
+
- This is how free text becomes structured insurance data.
|
| 352 |
+
- It is a common building block for claims automation and information extraction.
|
| 353 |
+
|
| 354 |
+
## M5. LLM Fine-Tuning: QLoRA and DPO
|
| 355 |
+
|
| 356 |
+
Training code:
|
| 357 |
+
|
| 358 |
+
- [training/qlora_finetune.py](training/qlora_finetune.py)
|
| 359 |
+
- [training/dpo_train.py](training/dpo_train.py)
|
| 360 |
+
- [training/retrain_realworld.py](training/retrain_realworld.py)
|
| 361 |
+
|
| 362 |
+
Data used:
|
| 363 |
+
|
| 364 |
+
- [data/output/insurance_sft_10k.jsonl](data/output/insurance_sft_10k.jsonl)
|
| 365 |
+
- [data/output/insurance_dpo_5k.jsonl](data/output/insurance_dpo_5k.jsonl)
|
| 366 |
+
|
| 367 |
+
Main idea:
|
| 368 |
+
|
| 369 |
+
- This is causal language modeling: the model writes text one token at a time.
|
| 370 |
+
- Instead of predicting one label, it generates full answers, assessments, and explanations.
|
| 371 |
+
|
| 372 |
+
The training pipeline has three stages:
|
| 373 |
+
|
| 374 |
+
1. Supervised fine-tuning (SFT) on insurance conversations
|
| 375 |
+
2. DPO alignment on chosen vs rejected answers
|
| 376 |
+
3. Additional retraining on real-world insurance text converted into instruction data
|
| 377 |
+
|
| 378 |
+
Core concepts:
|
| 379 |
+
|
| 380 |
+
- Decoder-only transformers generate the next token autoregressively.
|
| 381 |
+
- QLoRA makes large-model tuning practical on smaller GPUs:
|
| 382 |
+
- quantize the base model to 4-bit
|
| 383 |
+
- freeze the base weights
|
| 384 |
+
- train small LoRA adapters
|
| 385 |
+
- Gradient accumulation simulates a larger batch.
|
| 386 |
+
- Gradient checkpointing reduces memory use.
|
| 387 |
+
- DPO teaches preferences between two answers without a full RLHF pipeline.
|
| 388 |
+
|
| 389 |
+
Why it matters:
|
| 390 |
+
|
| 391 |
+
- This is the model family behind long-form assistants.
|
| 392 |
+
- It shows how domain adaptation works when you want the system to speak insurance rather than just classify it.
|
| 393 |
+
|
| 394 |
+
## Search and Retrieval: InsureSearch
|
| 395 |
+
|
| 396 |
+
Code:
|
| 397 |
+
|
| 398 |
+
- [search/api.py](search/api.py)
|
| 399 |
+
- [search/hybrid_engine.py](search/hybrid_engine.py)
|
| 400 |
+
- [search/indexer.py](search/indexer.py)
|
| 401 |
+
- [search/bm25.py](search/bm25.py)
|
| 402 |
+
|
| 403 |
+
Main idea:
|
| 404 |
+
|
| 405 |
+
- The LLM should not answer everything from memory.
|
| 406 |
+
- Search retrieves relevant source material first, then the model can answer with better grounding.
|
| 407 |
+
|
| 408 |
+
INSUREOS search combines:
|
| 409 |
+
|
| 410 |
+
- dense vector retrieval
|
| 411 |
+
- BM25 keyword retrieval
|
| 412 |
+
- reranking
|
| 413 |
+
- reciprocal rank fusion
|
| 414 |
+
|
| 415 |
+
Why it matters:
|
| 416 |
+
|
| 417 |
+
- In production, strong retrieval often matters more than a slightly bigger model.
|
| 418 |
+
|
| 419 |
+
## How to Read the Repo as a Beginner
|
| 420 |
+
|
| 421 |
+
If you are new to ML, read in this order:
|
| 422 |
+
|
| 423 |
+
1. [training/pricing_glm.py](training/pricing_glm.py)
|
| 424 |
+
2. [training/fraud_model.py](training/fraud_model.py)
|
| 425 |
+
3. [training/doc_classifier.py](training/doc_classifier.py)
|
| 426 |
+
4. [training/ner_model.py](training/ner_model.py)
|
| 427 |
+
5. [training/qlora_finetune.py](training/qlora_finetune.py)
|
| 428 |
+
6. [training/dpo_train.py](training/dpo_train.py)
|
| 429 |
+
7. [search/hybrid_engine.py](search/hybrid_engine.py)
|
| 430 |
+
|
| 431 |
+
That order moves from easier classical ML toward transformer systems and then into retrieval.
|
| 432 |
+
|
| 433 |
+
## Common Questions
|
| 434 |
+
|
| 435 |
+
### Why do some metrics look unrealistically perfect?
|
| 436 |
+
|
| 437 |
+
Because much of the data is synthetic. Synthetic datasets are useful for scaffolding and prototyping, but they are often cleaner and easier than production data.
|
| 438 |
+
|
| 439 |
+
### Why are there separate model repos and one shared code repo?
|
| 440 |
+
|
| 441 |
+
Because Hugging Face model pages are best for weights, cards, and usage snippets. A shared code repo avoids duplicating every training script into every model repo.
|
| 442 |
+
|
| 443 |
+
### Where should I start if I want to run something quickly?
|
| 444 |
+
|
| 445 |
+
Start with one of these:
|
| 446 |
+
|
| 447 |
+
- [training/doc_classifier.py](training/doc_classifier.py)
|
| 448 |
+
- [training/ner_model.py](training/ner_model.py)
|
| 449 |
+
- [training/fraud_model.py](training/fraud_model.py)
|
| 450 |
+
|
| 451 |
+
The LLM path requires more GPU memory and more dependencies.
|
| 452 |
+
|
| 453 |
+
## Related Repos on Hugging Face
|
| 454 |
+
|
| 455 |
+
- [InsureLLM-4B](https://huggingface.co/piyushptiwari/InsureLLM-4B)
|
| 456 |
+
- [InsureDocClassifier](https://huggingface.co/piyushptiwari/InsureDocClassifier)
|
| 457 |
+
- [InsureNER](https://huggingface.co/piyushptiwari/InsureNER)
|
| 458 |
+
- [InsureFraudNet](https://huggingface.co/piyushptiwari/InsureFraudNet)
|
| 459 |
+
- [InsurePricing](https://huggingface.co/piyushptiwari/InsurePricing)
|
| 460 |
+
- [insureos-models](https://huggingface.co/piyushptiwari/insureos-models)
|
| 461 |
+
- [insureos-training-data](https://huggingface.co/datasets/piyushptiwari/insureos-training-data)
|
| 462 |
+
|
| 463 |
+
## Summary
|
| 464 |
+
|
| 465 |
+
INSUREOS is not one model. It is a compact insurance AI stack:
|
| 466 |
+
|
| 467 |
+
- tabular ML for pricing and fraud
|
| 468 |
+
- transformer encoders for classification and extraction
|
| 469 |
+
- an LLM for long-form generation
|
| 470 |
+
- a search system for retrieval and grounding
|
| 471 |
+
|
| 472 |
+
If you are reading this from Hugging Face, the shortest answer is:
|
| 473 |
+
|
| 474 |
+
- model repos show the artifacts
|
| 475 |
+
- the code repo shows how they were built
|
| 476 |
+
- the dataset repo shows what they were trained on# INSUREOS β Learn How These Models Work
|
| 477 |
+
|
| 478 |
+
**A plain-English guide to the machine learning behind the INSUREOS model suite.**
|
| 479 |
+
Created by [Bytical AI](https://bytical.ai).
|
| 480 |
+
|
| 481 |
+
This document is for anyone β engineers, actuaries, claims handlers, students β who
|
| 482 |
+
wants to understand *how* each INSUREOS model actually works, what data trained it,
|
| 483 |
+
and where to find the exact code. No prior ML background assumed: we start from the
|
| 484 |
+
basics and build up.
|
| 485 |
+
|
| 486 |
+
Every section links to the real training script in this repository so you can read
|
| 487 |
+
the code alongside the explanation.
|
| 488 |
+
|
| 489 |
+
---
|
| 490 |
+
|
| 491 |
+
## The big picture: five ML paradigms in one suite
|
| 492 |
+
|
| 493 |
+
INSUREOS is deliberately built across the whole spectrum of modern ML. Each model is
|
| 494 |
+
a different *family* of algorithm, chosen because it fits the problem:
|
| 495 |
+
|
| 496 |
+
| # | Model | Problem | ML paradigm | Code | Published model |
|
| 497 |
+
|---|-------|---------|-------------|------|-----------------|
|
| 498 |
+
| 1 | **InsurePricing** | Predict a premium (a number) | Tabular regression (GLM + EBM) | [`training/pricing_glm.py`](training/pricing_glm.py) | [InsurePricing](https://huggingface.co/piyushptiwari/InsurePricing) |
|
| 499 |
+
| 2 | **InsureFraudNet** | Is this claim fraud? (yes/no) | Tabular classification (gradient boosting + anomaly detection) | [`training/fraud_model.py`](training/fraud_model.py) | [InsureFraudNet](https://huggingface.co/piyushptiwari/InsureFraudNet) |
|
| 500 |
+
| 3 | **InsureDocClassifier** | What type of document is this? | Transformer text classification | [`training/doc_classifier.py`](training/doc_classifier.py) | [InsureDocClassifier](https://huggingface.co/piyushptiwari/InsureDocClassifier) |
|
| 501 |
+
| 4 | **InsureNER** | Pull entities out of text | Transformer token classification | [`training/ner_model.py`](training/ner_model.py) | [InsureNER](https://huggingface.co/piyushptiwari/InsureNER) |
|
| 502 |
+
| 5 | **InsureLLM-4B** | Write insurance answers | Large Language Model (QLoRA + DPO) | [`training/qlora_finetune.py`](training/qlora_finetune.py) | [InsureLLM-4B](https://huggingface.co/piyushptiwari/InsureLLM-4B) |
|
| 503 |
+
|
| 504 |
+
All of them were trained on the open
|
| 505 |
+
[INSUREOS Training Data](https://huggingface.co/datasets/piyushptiwari/insureos-training-data) dataset.
|
| 506 |
+
|
| 507 |
+
A useful mental model β the difference between the two big groups:
|
| 508 |
+
|
| 509 |
+
```
|
| 510 |
+
Tabular models (1, 2) Language models (3, 4, 5)
|
| 511 |
+
----------------------- -------------------------
|
| 512 |
+
input = rows of numbers input = text
|
| 513 |
+
(age, value, ...) ("Aviva policy POL-123 ...")
|
| 514 |
+
engine = decision trees / engine = transformer (attention)
|
| 515 |
+
linear equations
|
| 516 |
+
output = a number or a output = a label, entities,
|
| 517 |
+
yes/no or generated text
|
| 518 |
+
```
|
| 519 |
+
|
| 520 |
+
---
|
| 521 |
+
|
| 522 |
+
## Module 1 β InsurePricing: predicting a premium
|
| 523 |
+
|
| 524 |
+
**The problem.** Given a driver and a vehicle, predict the right premium (a Β£ amount).
|
| 525 |
+
Predicting a continuous number is called **regression**.
|
| 526 |
+
|
| 527 |
+
**Concept 1 β Linear regression.** The simplest regression draws a straight line:
|
| 528 |
+
`premium = w1Β·age + w2Β·vehicle_value + ... + b`. The model *learns* the weights `w`
|
| 529 |
+
that make the line fit the data best. Easy to interpret, but real insurance costs are
|
| 530 |
+
not a straight line.
|
| 531 |
+
|
| 532 |
+
**Concept 2 β Generalized Linear Models (GLM).** Insurance has used GLMs for decades
|
| 533 |
+
because they fix two problems with plain linear regression:
|
| 534 |
+
|
| 535 |
+
- A **link function** lets the relationship curve. We use a **log link**, so the model
|
| 536 |
+
predicts `log(premium)` and effects become *multiplicative* β "a sports car multiplies
|
| 537 |
+
the price by 1.4" rather than "adds Β£400". That matches how risk actually behaves.
|
| 538 |
+
- A **distribution** describes the shape of the target. Claims cost is a spike at Β£0
|
| 539 |
+
(most policies never claim) plus a long right tail (a few huge claims). The
|
| 540 |
+
**Tweedie distribution** models exactly this. We use **power = 1.5**, which sits
|
| 541 |
+
between Poisson (counting *how often* you claim) and Gamma (*how big* each claim is),
|
| 542 |
+
so a single model captures *frequency Γ severity*.
|
| 543 |
+
|
| 544 |
+
**Concept 3 β Regularization.** The `alpha` parameter discourages the model from
|
| 545 |
+
relying too heavily on any one feature, which prevents **overfitting** (memorising the
|
| 546 |
+
training data instead of learning the pattern).
|
| 547 |
+
|
| 548 |
+
**Concept 4 β The glass-box second model (EBM).** Alongside the GLM we train an
|
| 549 |
+
**Explainable Boosting Machine** (from Microsoft Research's InterpretML). It is more
|
| 550 |
+
accurate (lower error) yet still fully interpretable: it can show you the exact shape
|
| 551 |
+
of "premium vs driver age". In regulated insurance, being able to *explain* a price is
|
| 552 |
+
as important as the price itself.
|
| 553 |
+
|
| 554 |
+
**In the code** ([`training/pricing_glm.py`](training/pricing_glm.py)): look for the
|
| 555 |
+
`TweedieRegressor(power=1.5, link='log', alpha=...)` and the `ExplainableBoostingRegressor`.
|
| 556 |
+
Note the engineered features `vehicle_age`, `driver_experience_ratio`, `ncd_ratio` β
|
| 557 |
+
hand-built ratios that give the model more signal than the raw columns alone.
|
| 558 |
+
|
| 559 |
+
---
|
| 560 |
+
|
| 561 |
+
## Module 2 β InsureFraudNet: catching fraudulent claims
|
| 562 |
+
|
| 563 |
+
**The problem.** Given a claim, output a fraud probability. Predicting a yes/no (or a
|
| 564 |
+
probability) is **classification**.
|
| 565 |
+
|
| 566 |
+
**Concept 1 β Decision trees.** A tree asks a chain of yes/no questions
|
| 567 |
+
("reserve/premium ratio > 5? reported more than 30 days late?") and lands on a verdict.
|
| 568 |
+
Intuitive, but one tree is a weak predictor.
|
| 569 |
+
|
| 570 |
+
**Concept 2 β Gradient boosting (XGBoost).** Instead of one tree, build *hundreds* of
|
| 571 |
+
small trees **in sequence**, where each new tree focuses on the mistakes the previous
|
| 572 |
+
ones made. The errors get "boosted" away. **XGBoost** is the industry-standard
|
| 573 |
+
implementation and dominates tabular ML competitions. Key settings in our code:
|
| 574 |
+
`max_depth=6`, `learning_rate=0.05`, `n_estimators=500`, `early_stopping=30`
|
| 575 |
+
(stop adding trees once the validation score stops improving).
|
| 576 |
+
|
| 577 |
+
**Concept 3 β Class imbalance.** Only ~8% of claims are fraud. A lazy model could
|
| 578 |
+
predict "never fraud" and be 92% accurate β and useless. We fix this with
|
| 579 |
+
**`scale_pos_weight β 11.5`** (= number of legit Γ· number of fraud), which tells
|
| 580 |
+
XGBoost to treat each rare fraud case as ~11Γ more important.
|
| 581 |
+
|
| 582 |
+
**Concept 4 β Unsupervised anomaly detection (Isolation Forest).** Supervised models
|
| 583 |
+
only catch fraud patterns they have *seen labelled*. An **Isolation Forest** needs no
|
| 584 |
+
labels β it isolates claims that simply *look weird* compared to everything else
|
| 585 |
+
(`contamination=0.08`). This is our safety net for *novel* fraud the labels never
|
| 586 |
+
captured. We train one XGBoost + one Isolation Forest per line of business
|
| 587 |
+
(Motor / Property / Liability).
|
| 588 |
+
|
| 589 |
+
**Concept 5 β The right metrics.** For rare events, plain accuracy lies. We use:
|
| 590 |
+
|
| 591 |
+
- **Precision** = of the claims we flagged, how many were really fraud?
|
| 592 |
+
- **Recall** = of the real fraud, how much did we catch?
|
| 593 |
+
- **F1** = the balance of the two.
|
| 594 |
+
- **AUC-PR** (precision-recall area) β far more honest than AUC-ROC when positives are rare.
|
| 595 |
+
|
| 596 |
+
**In the code** ([`training/fraud_model.py`](training/fraud_model.py)): see
|
| 597 |
+
`XGBClassifier(objective='binary:logistic', eval_metric='aucpr', scale_pos_weight=...)`
|
| 598 |
+
and `IsolationForest(contamination=0.08)`. Engineered features like
|
| 599 |
+
`claim_reserve_ratio`, `claim_premium_ratio`, `new_policy`, `late_report` carry most
|
| 600 |
+
of the predictive power.
|
| 601 |
+
|
| 602 |
+
---
|
| 603 |
+
|
| 604 |
+
## Module 3 β InsureDocClassifier: reading whole documents
|
| 605 |
+
|
| 606 |
+
This is where we leave numbers behind and start working with **text**, using
|
| 607 |
+
**transformers** β the architecture behind all modern language AI.
|
| 608 |
+
|
| 609 |
+
**Concept 1 β Tokenization.** Computers can't read words, only numbers. A **tokenizer**
|
| 610 |
+
chops text into pieces (tokens β roughly sub-words) and maps each to an integer ID.
|
| 611 |
+
`"Subrogation"` might become `["Sub", "rog", "ation"]` β `[1234, 567, 89]`.
|
| 612 |
+
|
| 613 |
+
**Concept 2 β Embeddings.** Each token ID becomes a **vector** (a list of numbers) that
|
| 614 |
+
captures meaning. Words used in similar contexts get similar vectors β so the model
|
| 615 |
+
learns that "flood" and "storm" are related.
|
| 616 |
+
|
| 617 |
+
**Concept 3 β The transformer & self-attention.** The breakthrough idea is
|
| 618 |
+
**self-attention**: when processing a word, the model *looks at every other word in the
|
| 619 |
+
sentence* and decides which ones matter. In "the policy *excludes* flood", attention
|
| 620 |
+
links "excludes" to "flood" so the meaning flips. Stacking many attention layers gives a
|
| 621 |
+
rich, context-aware understanding of the text.
|
| 622 |
+
|
| 623 |
+
**Concept 4 β The [CLS] token.** A special `[CLS]` token sits at the front of every
|
| 624 |
+
input. After all the attention layers, its vector becomes a **summary of the whole
|
| 625 |
+
document**. We attach a small **classification head** (one linear layer) on top of that
|
| 626 |
+
summary to predict the document type β one of **12 classes** (Policy Schedule, Claim
|
| 627 |
+
Form, FNOL Report, β¦).
|
| 628 |
+
|
| 629 |
+
**Concept 5 β Pre-training vs fine-tuning (transfer learning).** We don't train a
|
| 630 |
+
language model from scratch β that costs millions. We start from **ModernBERT**, which
|
| 631 |
+
was already **pre-trained** on huge amounts of text (so it already "knows English"), and
|
| 632 |
+
**fine-tune** it on our 10,000 insurance documents. This **transfer learning** is why a
|
| 633 |
+
specialist model can be built quickly and cheaply.
|
| 634 |
+
|
| 635 |
+
Key training settings: `MAX_LEN=512`, `EPOCHS=5`, `BATCH=16`, `LR=2e-5`, a cosine
|
| 636 |
+
learning-rate schedule with `warmup_ratio=0.1`, and `weight_decay=0.01`.
|
| 637 |
+
|
| 638 |
+
- **Epoch** = one full pass over the data. **Batch** = how many examples per step.
|
| 639 |
+
- **Learning rate (LR)** = step size for each update β too big overshoots, too small
|
| 640 |
+
crawls. **Warmup** ramps the LR up gently at the start. **Weight decay** is
|
| 641 |
+
regularization that keeps weights small.
|
| 642 |
+
|
| 643 |
+
**In the code** ([`training/doc_classifier.py`](training/doc_classifier.py)):
|
| 644 |
+
`AutoModelForSequenceClassification.from_pretrained("answerdotai/ModernBERT-base", num_labels=12)`.
|
| 645 |
+
|
| 646 |
+
---
|
| 647 |
+
|
| 648 |
+
## Module 4 β InsureNER: pulling facts out of text
|
| 649 |
+
|
| 650 |
+
**The shift from Module 3.** Document classification gives **one label for the whole
|
| 651 |
+
text**. NER (Named Entity Recognition) gives **a label for every single word** β this is
|
| 652 |
+
**token classification**.
|
| 653 |
+
|
| 654 |
+
From a sentence, NER extracts a structured row:
|
| 655 |
+
|
| 656 |
+
```
|
| 657 |
+
"Brit Insurance must pay Amelia Jones for the vandalism claim (CLM-864344) by 2023-05-25."
|
| 658 |
+
|
| 659 |
+
INSURER = Brit Insurance PERSON = Amelia Jones PERIL = vandalism
|
| 660 |
+
CLAIM_NUMBER = CLM-864344 DATE = 2023-05-25
|
| 661 |
+
```
|
| 662 |
+
|
| 663 |
+
**Concept 1 β BIO / IOB2 tagging.** Every word gets one of three kinds of tag:
|
| 664 |
+
|
| 665 |
+
- `O` β **O**utside any entity (a boring word).
|
| 666 |
+
- `B-XXX` β **B**eginning of an entity of type XXX.
|
| 667 |
+
- `I-XXX` β **I**nside (continuation) of that entity.
|
| 668 |
+
|
| 669 |
+
Example: `Amelia/B-PERSON Jones/I-PERSON`. The `B-`/`I-` split is what lets the model
|
| 670 |
+
tell *two adjacent people* apart from *one two-word person*. Our 13 entity types become
|
| 671 |
+
**27 labels** (`O` + a `B-`/`I-` pair per type).
|
| 672 |
+
|
| 673 |
+
**Concept 2 β Subword alignment (the tricky part).** The tokenizer may split one word
|
| 674 |
+
into several sub-words (`CLM-864344` β `CL ##M - 864 ##344`), but we only have **one**
|
| 675 |
+
label for the whole word. The function `tokenize_and_align` handles this with three
|
| 676 |
+
rules:
|
| 677 |
+
|
| 678 |
+
1. Special tokens (`[CLS]`, `[SEP]`, padding) get label **`-100`**, a magic value that
|
| 679 |
+
tells the loss function "ignore me".
|
| 680 |
+
2. The **first** sub-word of a word gets the real label.
|
| 681 |
+
3. Continuation sub-words convert `B-` β `I-` (the entity is still going).
|
| 682 |
+
|
| 683 |
+
**Concept 3 β Entity-level metrics (seqeval).** We don't score per token (predicting
|
| 684 |
+
`O` everywhere would score ~85% and be useless). The **seqeval** library scores per
|
| 685 |
+
**entity span** β a prediction only counts if the *whole* entity (type, start, and end)
|
| 686 |
+
is correct. That gives honest precision / recall / F1.
|
| 687 |
+
|
| 688 |
+
The architecture is the same ModernBERT as Module 3, but the head predicts a label for
|
| 689 |
+
**every** token instead of just the `[CLS]` summary.
|
| 690 |
+
|
| 691 |
+
**In the code** ([`training/ner_model.py`](training/ner_model.py)):
|
| 692 |
+
`AutoModelForTokenClassification`, the `tokenize_and_align` function, and the
|
| 693 |
+
`seqeval`-based `compute_metrics`. Settings: `MAX_LEN=256`, `EPOCHS=8`, `LR=3e-5`.
|
| 694 |
+
|
| 695 |
+
---
|
| 696 |
+
|
| 697 |
+
## Module 5 β InsureLLM-4B: a model that *writes*
|
| 698 |
+
|
| 699 |
+
The biggest leap. Modules 3β4 **classify** (pick a label). InsureLLM **generates** β
|
| 700 |
+
it writes a full, structured claims assessment paragraph by paragraph.
|
| 701 |
+
|
| 702 |
+
**Concept 1 β Causal language modelling.** A "causal" LM does one thing: **predict the
|
| 703 |
+
next token** given everything before it. To generate text it predicts a token, appends
|
| 704 |
+
it, feeds the whole thing back, and predicts again β **autoregressive** generation,
|
| 705 |
+
looping hundreds of times. Every ChatGPT-style answer is this loop.
|
| 706 |
+
|
| 707 |
+
- Modules 3β4 used an **encoder** (BERT) that reads the whole sentence at once.
|
| 708 |
+
- Module 5 uses a **decoder** (Qwen3) that only sees the words to its left.
|
| 709 |
+
|
| 710 |
+
**Concept 2 β Instruction tuning (SFT).** We show the model thousands of
|
| 711 |
+
`system β user β assistant` chat conversations and train it to produce the *assistant's*
|
| 712 |
+
reply. This is **Supervised Fine-Tuning**. Roles are flattened into one string by the
|
| 713 |
+
tokenizer's **chat template** (`<|im_start|>system β¦ <|im_end|>`), so the model learns
|
| 714 |
+
whose turn it is and when to stop.
|
| 715 |
+
|
| 716 |
+
**Concept 3 β The size problem.** Qwen3-4B has 4 **billion** parameters. Full
|
| 717 |
+
fine-tuning would need 40+ GB of GPU memory. Two tricks shrink that to fit a single
|
| 718 |
+
16 GB GPU β together they are called **QLoRA**:
|
| 719 |
+
|
| 720 |
+
- **Quantization (the "Q").** Store each weight in **4 bits** instead of 16
|
| 721 |
+
(`nf4` format). That is ~4Γ smaller, so the model fits in ~4β5 GB. The weights are
|
| 722 |
+
de-quantized to 16-bit only for the actual maths, so accuracy barely drops.
|
| 723 |
+
- **LoRA β Low-Rank Adaptation.** **Freeze all 4 billion original weights** and never
|
| 724 |
+
touch them. Next to each big matrix, inject two *tiny* trainable matrices `A` and `B`.
|
| 725 |
+
Instead of learning a giant update, learn the small product `BΒ·A`:
|
| 726 |
+
|
| 727 |
+
$$h = Wx + \frac{\alpha}{r}\,(BA)\,x$$
|
| 728 |
+
|
| 729 |
+
With `r=64` (the **rank**) and `alpha=128` (a **scaling** factor), only **~1β2% of the
|
| 730 |
+
parameters are trained**. The huge model keeps all its knowledge (frozen); we just
|
| 731 |
+
learn a small "insurance accent" on top.
|
| 732 |
+
|
| 733 |
+
**Concept 4 β Two more memory tricks.**
|
| 734 |
+
- **Gradient accumulation** (`batch=2`, `grad_accum=8` β effective batch 16): add up the
|
| 735 |
+
gradients from 8 small batches before taking one step, simulating a big batch cheaply.
|
| 736 |
+
- **Gradient checkpointing**: don't store every intermediate value during the forward
|
| 737 |
+
pass β recompute them during back-prop. Trades compute for memory.
|
| 738 |
+
|
| 739 |
+
Note `LR=2e-4` here is ~10Γ higher than the BERT modules: the LoRA adapters start from
|
| 740 |
+
zero and are tiny, so they need a more aggressive learning rate.
|
| 741 |
+
|
| 742 |
+
**The full InsureLLM pipeline is three stages:** QLoRA SFT β **DPO** alignment
|
| 743 |
+
(teaching the model to prefer the better of two answers β see
|
| 744 |
+
[`training/dpo_train.py`](training/dpo_train.py)) β a final real-world fine-tune.
|
| 745 |
+
|
| 746 |
+
**In the code** ([`training/qlora_finetune.py`](training/qlora_finetune.py)):
|
| 747 |
+
`BitsAndBytesConfig(load_in_4bit=True, bnb_4bit_quant_type="nf4", ...)`,
|
| 748 |
+
`LoraConfig(r=64, lora_alpha=128, target_modules="all-linear", task_type=CAUSAL_LM)`,
|
| 749 |
+
and the `trl` `SFTTrainer`. At the end, `merge_and_unload()` folds the adapters back
|
| 750 |
+
into the base to produce a single standalone model.
|
| 751 |
+
|
| 752 |
+
---
|
| 753 |
+
|
| 754 |
+
## A critical ML lesson: when "perfect" is a red flag
|
| 755 |
+
|
| 756 |
+
You will notice that several INSUREOS models report **perfect scores** β fraud
|
| 757 |
+
AUC = 1.0, document accuracy = 1.0, NER F1 = 1.0. **In real machine learning, this is a
|
| 758 |
+
warning sign, not a trophy.**
|
| 759 |
+
|
| 760 |
+
These models are trained on **synthetic** data, where the patterns are cleaner and
|
| 761 |
+
easier than messy reality. A perfect score usually means one of:
|
| 762 |
+
|
| 763 |
+
- **The task is too easy / the synthetic data is too regular.**
|
| 764 |
+
- **Data leakage** β a feature accidentally gives away the answer.
|
| 765 |
+
|
| 766 |
+
The instinct to build: **be suspicious of results that look too good.** On real,
|
| 767 |
+
noisy production data, expect roughly **0.80β0.97**, never a flat 1.0. The value of
|
| 768 |
+
this suite is in the *methods and code*, which transfer directly to real data β not in
|
| 769 |
+
the headline 1.0 numbers.
|
| 770 |
+
|
| 771 |
+
---
|
| 772 |
+
|
| 773 |
+
## Where to go next
|
| 774 |
+
|
| 775 |
+
The INSUREOS repository goes beyond these five models:
|
| 776 |
+
|
| 777 |
+
- **DPO alignment** β [`training/dpo_train.py`](training/dpo_train.py): after SFT teaches
|
| 778 |
+
the model *what* to say, DPO teaches it *preferences* (choose the better of two answers).
|
| 779 |
+
- **Search / RAG** β the [`search/`](search) directory: a hybrid Vector + BM25 engine
|
| 780 |
+
that retrieves real documents to ground the LLM's answers (Retrieval-Augmented
|
| 781 |
+
Generation), reducing hallucination.
|
| 782 |
+
- **Serving & evaluation** β [`serve/api.py`](serve/api.py) and
|
| 783 |
+
[`evaluation/run_eval.py`](evaluation/run_eval.py): how the models are exposed as an
|
| 784 |
+
API and measured.
|
| 785 |
+
|
| 786 |
+
---
|
| 787 |
+
|
| 788 |
+
## Mini-glossary
|
| 789 |
+
|
| 790 |
+
| Term | Plain meaning |
|
| 791 |
+
|------|---------------|
|
| 792 |
+
| **Regression** | Predicting a number (e.g. a premium). |
|
| 793 |
+
| **Classification** | Predicting a category (e.g. fraud / not fraud). |
|
| 794 |
+
| **GLM** | Linear model with a link function + a distribution; the actuarial standard. |
|
| 795 |
+
| **Tweedie** | A distribution that models "mostly zero, occasionally huge" β perfect for claims. |
|
| 796 |
+
| **Gradient boosting** | Hundreds of small trees, each fixing the last one's mistakes (XGBoost). |
|
| 797 |
+
| **Class imbalance** | When one outcome (fraud) is rare; needs special handling. |
|
| 798 |
+
| **Tokenization** | Splitting text into integer tokens a model can read. |
|
| 799 |
+
| **Embedding** | A vector of numbers representing a token's meaning. |
|
| 800 |
+
| **Transformer / attention** | Architecture that weighs every word against every other word. |
|
| 801 |
+
| **Fine-tuning** | Adapting a pre-trained model to your specific task. |
|
| 802 |
+
| **Token classification (NER)** | Labelling every word, not the whole text. |
|
| 803 |
+
| **BIO tagging** | `B-`/`I-`/`O` scheme that marks where entities start, continue, and end. |
|
| 804 |
+
| **Causal LM** | A model that generates text by predicting the next token. |
|
| 805 |
+
| **SFT** | Supervised Fine-Tuning on instruction β answer pairs. |
|
| 806 |
+
| **Quantization** | Storing weights in fewer bits to save memory. |
|
| 807 |
+
| **LoRA / QLoRA** | Training tiny adapters on a frozen (quantized) model β cheap fine-tuning. |
|
| 808 |
+
| **Epoch / Batch / LR** | One data pass / examples per step / update step size. |
|
| 809 |
+
|
| 810 |
+
---
|
| 811 |
+
|
| 812 |
+
*This guide accompanies the [INSUREOS model suite](https://huggingface.co/piyushptiwari).
|
| 813 |
+
Built by [Bytical AI](https://bytical.ai) β AI agents that run insurance operations.*
|
README.md
CHANGED
|
@@ -14,6 +14,12 @@ tags:
|
|
| 14 |
|
| 15 |
**Created by [Bytical AI](https://bytical.ai)** β AI agents that run insurance operations.
|
| 16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
## Overview
|
| 18 |
|
| 19 |
INSUREOS is a complete AI/ML training and inference pipeline for UK insurance operations. This repository contains all source code for data generation, model training, evaluation, data collection, and a hybrid search engine.
|
|
@@ -27,7 +33,7 @@ INSUREOS is a complete AI/ML training and inference pipeline for UK insurance op
|
|
| 27 |
| InsureNER | [piyushptiwari/InsureNER](https://huggingface.co/piyushptiwari/InsureNER) | 13-entity NER | F1: 1.0 |
|
| 28 |
| InsureFraudNet | [piyushptiwari/InsureFraudNet](https://huggingface.co/piyushptiwari/InsureFraudNet) | Fraud detection (3 LoB) | AUC-ROC: 1.0 |
|
| 29 |
| InsurePricing | [piyushptiwari/InsurePricing](https://huggingface.co/piyushptiwari/InsurePricing) | Premium pricing (GLM + EBM) | MAE: Β£11,132 |
|
| 30 |
-
| InsureSearch | (
|
| 31 |
|
| 32 |
### Training Dataset
|
| 33 |
|
|
|
|
| 14 |
|
| 15 |
**Created by [Bytical AI](https://bytical.ai)** β AI agents that run insurance operations.
|
| 16 |
|
| 17 |
+
## Start Here
|
| 18 |
+
|
| 19 |
+
If you are trying to understand the Hugging Face repos, start with [LEARN.md](LEARN.md).
|
| 20 |
+
|
| 21 |
+
That guide explains, in plain English, why the project is split across model, dataset, code, and search repos, and it walks through the concepts, data, and training code behind each model in this repository.
|
| 22 |
+
|
| 23 |
## Overview
|
| 24 |
|
| 25 |
INSUREOS is a complete AI/ML training and inference pipeline for UK insurance operations. This repository contains all source code for data generation, model training, evaluation, data collection, and a hybrid search engine.
|
|
|
|
| 33 |
| InsureNER | [piyushptiwari/InsureNER](https://huggingface.co/piyushptiwari/InsureNER) | 13-entity NER | F1: 1.0 |
|
| 34 |
| InsureFraudNet | [piyushptiwari/InsureFraudNet](https://huggingface.co/piyushptiwari/InsureFraudNet) | Fraud detection (3 LoB) | AUC-ROC: 1.0 |
|
| 35 |
| InsurePricing | [piyushptiwari/InsurePricing](https://huggingface.co/piyushptiwari/InsurePricing) | Premium pricing (GLM + EBM) | MAE: Β£11,132 |
|
| 36 |
+
| InsureSearch | [piyushptiwari/insureos-search-engine](https://huggingface.co/piyushptiwari/insureos-search-engine) | Hybrid search engine | 33K docs indexed |
|
| 37 |
|
| 38 |
### Training Dataset
|
| 39 |
|
push_to_hf.py
CHANGED
|
@@ -108,7 +108,7 @@ if __name__ == "__main__":
|
|
| 108 |
# =========================================================
|
| 109 |
# 6. Training Code + Search Engine (as a regular repo)
|
| 110 |
# =========================================================
|
| 111 |
-
print("\n[6/
|
| 112 |
repo = f"{ORG}/insureos-models"
|
| 113 |
ensure_repo(repo, repo_type="model")
|
| 114 |
# We upload code only β no model weights, no raw data, no personal files
|
|
@@ -128,9 +128,23 @@ if __name__ == "__main__":
|
|
| 128 |
)
|
| 129 |
|
| 130 |
# =========================================================
|
| 131 |
-
# 7.
|
| 132 |
# =========================================================
|
| 133 |
-
print("\n[7/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 134 |
repo = f"{ORG}/insureos-training-data"
|
| 135 |
ensure_repo(repo, repo_type="dataset")
|
| 136 |
upload_folder(
|
|
@@ -149,5 +163,7 @@ if __name__ == "__main__":
|
|
| 149 |
print(f" https://huggingface.co/{ORG}/InsurePricing")
|
| 150 |
print(f"\nCode:")
|
| 151 |
print(f" https://huggingface.co/{ORG}/insureos-models")
|
|
|
|
|
|
|
| 152 |
print(f"\nDataset:")
|
| 153 |
print(f" https://huggingface.co/datasets/{ORG}/insureos-training-data")
|
|
|
|
| 108 |
# =========================================================
|
| 109 |
# 6. Training Code + Search Engine (as a regular repo)
|
| 110 |
# =========================================================
|
| 111 |
+
print("\n[6/8] insureos-models (code repo)")
|
| 112 |
repo = f"{ORG}/insureos-models"
|
| 113 |
ensure_repo(repo, repo_type="model")
|
| 114 |
# We upload code only β no model weights, no raw data, no personal files
|
|
|
|
| 128 |
)
|
| 129 |
|
| 130 |
# =========================================================
|
| 131 |
+
# 7. Search Engine (as a regular repo)
|
| 132 |
# =========================================================
|
| 133 |
+
print("\n[7/8] insureos-search-engine")
|
| 134 |
+
repo = f"{ORG}/insureos-search-engine"
|
| 135 |
+
ensure_repo(repo, repo_type="model")
|
| 136 |
+
upload_folder(
|
| 137 |
+
repo, f"{BASE}/search", repo_type="model",
|
| 138 |
+
ignore_patterns=[
|
| 139 |
+
"__pycache__", "*.pyc", ".DS_Store",
|
| 140 |
+
"index_data/*",
|
| 141 |
+
]
|
| 142 |
+
)
|
| 143 |
+
|
| 144 |
+
# =========================================================
|
| 145 |
+
# 8. Training Data (as a dataset)
|
| 146 |
+
# =========================================================
|
| 147 |
+
print("\n[8/8] insureos-training-data (dataset)")
|
| 148 |
repo = f"{ORG}/insureos-training-data"
|
| 149 |
ensure_repo(repo, repo_type="dataset")
|
| 150 |
upload_folder(
|
|
|
|
| 163 |
print(f" https://huggingface.co/{ORG}/InsurePricing")
|
| 164 |
print(f"\nCode:")
|
| 165 |
print(f" https://huggingface.co/{ORG}/insureos-models")
|
| 166 |
+
print(f"\nSearch:")
|
| 167 |
+
print(f" https://huggingface.co/{ORG}/insureos-search-engine")
|
| 168 |
print(f"\nDataset:")
|
| 169 |
print(f" https://huggingface.co/datasets/{ORG}/insureos-training-data")
|
search/README.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
language:
|
| 3 |
+
- en
|
| 4 |
+
license: apache-2.0
|
| 5 |
+
tags:
|
| 6 |
+
- insurance
|
| 7 |
+
- search
|
| 8 |
+
- rag
|
| 9 |
+
- bm25
|
| 10 |
+
- qdrant
|
| 11 |
+
- fastapi
|
| 12 |
+
- retrieval
|
| 13 |
+
- bytical
|
| 14 |
+
pipeline_tag: sentence-similarity
|
| 15 |
+
---
|
| 16 |
+
|
| 17 |
+
# InsureSearch β Hybrid Insurance Search Engine
|
| 18 |
+
|
| 19 |
+
InsureSearch is the retrieval layer of INSUREOS. It combines vector search, BM25 keyword search, reranking, and FastAPI serving for insurance knowledge retrieval and RAG pipelines.
|
| 20 |
+
|
| 21 |
+
## What it does
|
| 22 |
+
|
| 23 |
+
- Indexes insurance documents and chunks.
|
| 24 |
+
- Supports semantic, keyword, and hybrid retrieval.
|
| 25 |
+
- Reranks results for better relevance.
|
| 26 |
+
- Powers retrieval for insurance assistants and internal search workflows.
|
| 27 |
+
|
| 28 |
+
## Main Components
|
| 29 |
+
|
| 30 |
+
- `embedder.py` β embeddings for semantic search.
|
| 31 |
+
- `bm25.py` β keyword retrieval.
|
| 32 |
+
- `vector_store.py` β vector storage and retrieval.
|
| 33 |
+
- `reranker.py` β reranking stage.
|
| 34 |
+
- `hybrid_engine.py` β fuses vector and keyword results.
|
| 35 |
+
- `indexer.py` β builds the search index.
|
| 36 |
+
- `api.py` β FastAPI endpoints.
|
| 37 |
+
|
| 38 |
+
## Code and Learning Guide
|
| 39 |
+
|
| 40 |
+
- **Search code:** [piyushptiwari/insureos-models/tree/main/search](https://huggingface.co/piyushptiwari/insureos-models/tree/main/search)
|
| 41 |
+
- **Full code repo:** [piyushptiwari/insureos-models](https://huggingface.co/piyushptiwari/insureos-models)
|
| 42 |
+
- **Learning guide:** [LEARN.md](https://huggingface.co/piyushptiwari/insureos-models/blob/main/LEARN.md)
|
| 43 |
+
|
| 44 |
+
## Relationship to the models
|
| 45 |
+
|
| 46 |
+
InsureSearch is typically used together with:
|
| 47 |
+
|
| 48 |
+
- [InsureLLM-4B](https://huggingface.co/piyushptiwari/InsureLLM-4B) for retrieval-augmented generation.
|
| 49 |
+
- [InsureDocClassifier](https://huggingface.co/piyushptiwari/InsureDocClassifier) for document routing.
|
| 50 |
+
- [InsureNER](https://huggingface.co/piyushptiwari/InsureNER) for structured extraction before indexing.
|
| 51 |
+
|
| 52 |
+
## Why this repo exists separately on Hugging Face
|
| 53 |
+
|
| 54 |
+
Users often expect a model card link when a model mentions a companion search engine. Publishing this folder as its own HF repo makes that link explicit and avoids broken references.
|