ins-pricing 0.5.0__py3-none-any.whl → 0.5.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ins_pricing/cli/BayesOpt_entry.py +15 -5
- ins_pricing/cli/BayesOpt_incremental.py +43 -10
- ins_pricing/cli/Explain_Run.py +16 -5
- ins_pricing/cli/Explain_entry.py +29 -8
- ins_pricing/cli/Pricing_Run.py +16 -5
- ins_pricing/cli/bayesopt_entry_runner.py +45 -12
- ins_pricing/cli/utils/bootstrap.py +23 -0
- ins_pricing/cli/utils/cli_config.py +34 -15
- ins_pricing/cli/utils/import_resolver.py +14 -14
- ins_pricing/cli/utils/notebook_utils.py +120 -106
- ins_pricing/cli/watchdog_run.py +15 -5
- ins_pricing/frontend/app.py +132 -61
- ins_pricing/frontend/config_builder.py +33 -0
- ins_pricing/frontend/example_config.json +11 -0
- ins_pricing/frontend/runner.py +340 -388
- ins_pricing/modelling/README.md +1 -1
- ins_pricing/modelling/__init__.py +10 -10
- ins_pricing/modelling/bayesopt/README.md +29 -11
- ins_pricing/modelling/bayesopt/config_components.py +12 -0
- ins_pricing/modelling/bayesopt/config_preprocess.py +50 -13
- ins_pricing/modelling/bayesopt/core.py +47 -19
- ins_pricing/modelling/bayesopt/model_plotting_mixin.py +20 -14
- ins_pricing/modelling/bayesopt/models/model_ft_components.py +349 -342
- ins_pricing/modelling/bayesopt/models/model_ft_trainer.py +11 -5
- ins_pricing/modelling/bayesopt/models/model_gnn.py +20 -14
- ins_pricing/modelling/bayesopt/models/model_resn.py +9 -3
- ins_pricing/modelling/bayesopt/trainers/trainer_base.py +62 -50
- ins_pricing/modelling/bayesopt/trainers/trainer_ft.py +61 -53
- ins_pricing/modelling/bayesopt/trainers/trainer_glm.py +9 -3
- ins_pricing/modelling/bayesopt/trainers/trainer_gnn.py +40 -32
- ins_pricing/modelling/bayesopt/trainers/trainer_resn.py +36 -24
- ins_pricing/modelling/bayesopt/trainers/trainer_xgb.py +240 -37
- ins_pricing/modelling/bayesopt/utils/distributed_utils.py +193 -186
- ins_pricing/modelling/bayesopt/utils/torch_trainer_mixin.py +23 -10
- ins_pricing/pricing/factors.py +67 -56
- ins_pricing/setup.py +1 -1
- ins_pricing/utils/__init__.py +7 -6
- ins_pricing/utils/device.py +45 -24
- ins_pricing/utils/logging.py +34 -1
- ins_pricing/utils/profiling.py +8 -4
- {ins_pricing-0.5.0.dist-info → ins_pricing-0.5.3.dist-info}/METADATA +182 -182
- {ins_pricing-0.5.0.dist-info → ins_pricing-0.5.3.dist-info}/RECORD +44 -43
- {ins_pricing-0.5.0.dist-info → ins_pricing-0.5.3.dist-info}/WHEEL +0 -0
- {ins_pricing-0.5.0.dist-info → ins_pricing-0.5.3.dist-info}/top_level.txt +0 -0
ins_pricing/utils/__init__.py
CHANGED
|
@@ -17,9 +17,9 @@ Example:
|
|
|
17
17
|
from __future__ import annotations
|
|
18
18
|
|
|
19
19
|
# =============================================================================
|
|
20
|
-
# Logging utilities
|
|
21
|
-
# =============================================================================
|
|
22
|
-
from ins_pricing.utils.logging import get_logger, configure_logging
|
|
20
|
+
# Logging utilities
|
|
21
|
+
# =============================================================================
|
|
22
|
+
from ins_pricing.utils.logging import get_logger, configure_logging, log_print
|
|
23
23
|
|
|
24
24
|
# =============================================================================
|
|
25
25
|
# Metric utilities (PSI, model evaluation)
|
|
@@ -78,9 +78,10 @@ from ins_pricing.utils.device import (
|
|
|
78
78
|
)
|
|
79
79
|
|
|
80
80
|
__all__ = [
|
|
81
|
-
# Logging
|
|
82
|
-
"get_logger",
|
|
83
|
-
"configure_logging",
|
|
81
|
+
# Logging
|
|
82
|
+
"get_logger",
|
|
83
|
+
"configure_logging",
|
|
84
|
+
"log_print",
|
|
84
85
|
# Metrics
|
|
85
86
|
"psi_numeric",
|
|
86
87
|
"psi_categorical",
|
ins_pricing/utils/device.py
CHANGED
|
@@ -58,32 +58,53 @@ class GPUMemoryManager:
|
|
|
58
58
|
_logger = get_logger("ins_pricing.gpu")
|
|
59
59
|
|
|
60
60
|
@classmethod
|
|
61
|
-
def clean(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
61
|
+
def clean(
|
|
62
|
+
cls,
|
|
63
|
+
verbose: bool = False,
|
|
64
|
+
*,
|
|
65
|
+
synchronize: bool = True,
|
|
66
|
+
empty_cache: bool = True,
|
|
67
|
+
) -> None:
|
|
68
|
+
"""Clean up GPU memory.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
verbose: If True, log cleanup details
|
|
72
|
+
synchronize: If True, synchronize CUDA device after cleanup
|
|
73
|
+
empty_cache: If True, clear CUDA cache
|
|
74
|
+
"""
|
|
75
|
+
gc.collect()
|
|
76
|
+
|
|
77
|
+
if TORCH_AVAILABLE and torch.cuda.is_available():
|
|
78
|
+
if empty_cache:
|
|
79
|
+
torch.cuda.empty_cache()
|
|
80
|
+
if synchronize:
|
|
81
|
+
torch.cuda.synchronize()
|
|
82
|
+
if verbose:
|
|
83
|
+
if empty_cache and synchronize:
|
|
84
|
+
cls._logger.debug("CUDA cache cleared and synchronized")
|
|
85
|
+
elif empty_cache:
|
|
86
|
+
cls._logger.debug("CUDA cache cleared")
|
|
87
|
+
elif synchronize:
|
|
88
|
+
cls._logger.debug("CUDA synchronized")
|
|
89
|
+
|
|
90
|
+
# Optional: Force IPC collect for multi-process scenarios
|
|
91
|
+
if os.environ.get("BAYESOPT_CUDA_IPC_COLLECT", "0") == "1":
|
|
92
|
+
try:
|
|
93
|
+
torch.cuda.ipc_collect()
|
|
94
|
+
if verbose:
|
|
95
|
+
cls._logger.debug("CUDA IPC collect performed")
|
|
96
|
+
except Exception:
|
|
97
|
+
pass
|
|
83
98
|
|
|
84
99
|
@classmethod
|
|
85
100
|
@contextmanager
|
|
86
|
-
def cleanup_context(
|
|
101
|
+
def cleanup_context(
|
|
102
|
+
cls,
|
|
103
|
+
verbose: bool = False,
|
|
104
|
+
*,
|
|
105
|
+
synchronize: bool = True,
|
|
106
|
+
empty_cache: bool = True,
|
|
107
|
+
):
|
|
87
108
|
"""Context manager that cleans GPU memory on exit.
|
|
88
109
|
|
|
89
110
|
Args:
|
|
@@ -95,7 +116,7 @@ class GPUMemoryManager:
|
|
|
95
116
|
try:
|
|
96
117
|
yield
|
|
97
118
|
finally:
|
|
98
|
-
cls.clean(verbose=verbose)
|
|
119
|
+
cls.clean(verbose=verbose, synchronize=synchronize, empty_cache=empty_cache)
|
|
99
120
|
|
|
100
121
|
@classmethod
|
|
101
122
|
def move_model_to_cpu(cls, model: Any) -> Any:
|
ins_pricing/utils/logging.py
CHANGED
|
@@ -18,7 +18,7 @@ from __future__ import annotations
|
|
|
18
18
|
import logging
|
|
19
19
|
import os
|
|
20
20
|
from functools import lru_cache
|
|
21
|
-
from typing import Optional
|
|
21
|
+
from typing import Optional, Union
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
@lru_cache(maxsize=1)
|
|
@@ -72,3 +72,36 @@ def configure_logging(
|
|
|
72
72
|
formatter = logging.Formatter(format_string)
|
|
73
73
|
for handler in logger.handlers:
|
|
74
74
|
handler.setFormatter(formatter)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def log_print(
|
|
78
|
+
logger: logging.Logger,
|
|
79
|
+
*args,
|
|
80
|
+
level: Optional[Union[int, str]] = None,
|
|
81
|
+
**kwargs,
|
|
82
|
+
) -> None:
|
|
83
|
+
"""Print-like helper that routes messages to a logger.
|
|
84
|
+
|
|
85
|
+
This preserves basic print semantics (sep/end) while ignoring file/flush,
|
|
86
|
+
and it auto-detects severity when level is not provided.
|
|
87
|
+
"""
|
|
88
|
+
sep = kwargs.get("sep", " ")
|
|
89
|
+
msg = sep.join(str(arg) for arg in args)
|
|
90
|
+
if not msg:
|
|
91
|
+
return
|
|
92
|
+
|
|
93
|
+
if level is None:
|
|
94
|
+
lowered = msg.lstrip().lower()
|
|
95
|
+
if lowered.startswith(("warn", "[warn]", "warning")):
|
|
96
|
+
level_value = logging.WARNING
|
|
97
|
+
elif lowered.startswith(("error", "[error]", "err")):
|
|
98
|
+
level_value = logging.ERROR
|
|
99
|
+
else:
|
|
100
|
+
level_value = logging.INFO
|
|
101
|
+
else:
|
|
102
|
+
if isinstance(level, str):
|
|
103
|
+
level_value = getattr(logging, level.upper(), logging.INFO)
|
|
104
|
+
else:
|
|
105
|
+
level_value = int(level)
|
|
106
|
+
|
|
107
|
+
logger.log(level_value, msg)
|
ins_pricing/utils/profiling.py
CHANGED
|
@@ -18,6 +18,10 @@ import time
|
|
|
18
18
|
from contextlib import contextmanager
|
|
19
19
|
from typing import Optional
|
|
20
20
|
|
|
21
|
+
from ins_pricing.utils import get_logger
|
|
22
|
+
|
|
23
|
+
_logger = get_logger("ins_pricing.utils.profiling")
|
|
24
|
+
|
|
21
25
|
try:
|
|
22
26
|
import psutil
|
|
23
27
|
HAS_PSUTIL = True
|
|
@@ -96,7 +100,7 @@ def profile_section(
|
|
|
96
100
|
if logger:
|
|
97
101
|
logger.log(log_level, msg)
|
|
98
102
|
else:
|
|
99
|
-
|
|
103
|
+
_logger.log(log_level, msg)
|
|
100
104
|
|
|
101
105
|
|
|
102
106
|
def get_memory_info() -> dict:
|
|
@@ -250,7 +254,7 @@ def cleanup_memory(logger: Optional[logging.Logger] = None) -> None:
|
|
|
250
254
|
if logger:
|
|
251
255
|
logger.info(msg)
|
|
252
256
|
else:
|
|
253
|
-
|
|
257
|
+
_logger.info(msg)
|
|
254
258
|
|
|
255
259
|
|
|
256
260
|
class MemoryMonitor:
|
|
@@ -301,7 +305,7 @@ class MemoryMonitor:
|
|
|
301
305
|
if self.logger:
|
|
302
306
|
self.logger.info(msg)
|
|
303
307
|
else:
|
|
304
|
-
|
|
308
|
+
_logger.info(msg)
|
|
305
309
|
|
|
306
310
|
return self
|
|
307
311
|
|
|
@@ -323,7 +327,7 @@ class MemoryMonitor:
|
|
|
323
327
|
if self.logger:
|
|
324
328
|
self.logger.info(msg)
|
|
325
329
|
else:
|
|
326
|
-
|
|
330
|
+
_logger.info(msg)
|
|
327
331
|
|
|
328
332
|
# Check threshold and cleanup if needed
|
|
329
333
|
if self.threshold_gb is not None:
|
|
@@ -1,182 +1,182 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: ins_pricing
|
|
3
|
-
Version: 0.5.
|
|
4
|
-
Summary: Reusable modelling, pricing, governance, and reporting utilities.
|
|
5
|
-
Author: meishi125478
|
|
6
|
-
License: Proprietary
|
|
7
|
-
Keywords: pricing,insurance,bayesopt,ml
|
|
8
|
-
Classifier: Programming Language :: Python :: 3
|
|
9
|
-
Classifier: Programming Language :: Python :: 3 :: Only
|
|
10
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
11
|
-
Classifier: License :: Other/Proprietary License
|
|
12
|
-
Classifier: Operating System :: OS Independent
|
|
13
|
-
Classifier: Intended Audience :: Developers
|
|
14
|
-
Requires-Python: >=3.9
|
|
15
|
-
Description-Content-Type: text/markdown
|
|
16
|
-
Requires-Dist: numpy>=1.20
|
|
17
|
-
Requires-Dist: pandas>=1.4
|
|
18
|
-
Provides-Extra: bayesopt
|
|
19
|
-
Requires-Dist: torch>=1.13; extra == "bayesopt"
|
|
20
|
-
Requires-Dist: optuna>=3.0; extra == "bayesopt"
|
|
21
|
-
Requires-Dist: xgboost>=1.6; extra == "bayesopt"
|
|
22
|
-
Requires-Dist: scikit-learn>=1.1; extra == "bayesopt"
|
|
23
|
-
Requires-Dist: statsmodels>=0.13; extra == "bayesopt"
|
|
24
|
-
Requires-Dist: joblib>=1.2; extra == "bayesopt"
|
|
25
|
-
Requires-Dist: matplotlib>=3.5; extra == "bayesopt"
|
|
26
|
-
Provides-Extra: plotting
|
|
27
|
-
Requires-Dist: matplotlib>=3.5; extra == "plotting"
|
|
28
|
-
Requires-Dist: scikit-learn>=1.1; extra == "plotting"
|
|
29
|
-
Provides-Extra: explain
|
|
30
|
-
Requires-Dist: torch>=1.13; extra == "explain"
|
|
31
|
-
Requires-Dist: shap>=0.41; extra == "explain"
|
|
32
|
-
Requires-Dist: scikit-learn>=1.1; extra == "explain"
|
|
33
|
-
Provides-Extra: geo
|
|
34
|
-
Requires-Dist: contextily>=1.3; extra == "geo"
|
|
35
|
-
Requires-Dist: matplotlib>=3.5; extra == "geo"
|
|
36
|
-
Provides-Extra: gnn
|
|
37
|
-
Requires-Dist: torch>=1.13; extra == "gnn"
|
|
38
|
-
Requires-Dist: pynndescent>=0.5; extra == "gnn"
|
|
39
|
-
Requires-Dist: torch-geometric>=2.3; extra == "gnn"
|
|
40
|
-
Provides-Extra: all
|
|
41
|
-
Requires-Dist: torch>=1.13; extra == "all"
|
|
42
|
-
Requires-Dist: optuna>=3.0; extra == "all"
|
|
43
|
-
Requires-Dist: xgboost>=1.6; extra == "all"
|
|
44
|
-
Requires-Dist: scikit-learn>=1.1; extra == "all"
|
|
45
|
-
Requires-Dist: statsmodels>=0.13; extra == "all"
|
|
46
|
-
Requires-Dist: joblib>=1.2; extra == "all"
|
|
47
|
-
Requires-Dist: matplotlib>=3.5; extra == "all"
|
|
48
|
-
Requires-Dist: shap>=0.41; extra == "all"
|
|
49
|
-
Requires-Dist: contextily>=1.3; extra == "all"
|
|
50
|
-
Requires-Dist: pynndescent>=0.5; extra == "all"
|
|
51
|
-
Requires-Dist: torch-geometric>=2.3; extra == "all"
|
|
52
|
-
|
|
53
|
-
# Insurance-Pricing
|
|
54
|
-
|
|
55
|
-
A reusable toolkit for insurance modeling, pricing, governance, and reporting.
|
|
56
|
-
|
|
57
|
-
## Overview
|
|
58
|
-
|
|
59
|
-
Insurance-Pricing (ins_pricing) is an enterprise-grade Python library designed for machine learning
|
|
60
|
-
model training, pricing calculations, and model governance workflows in the insurance industry.
|
|
61
|
-
|
|
62
|
-
### Core Modules
|
|
63
|
-
|
|
64
|
-
| Module | Description |
|
|
65
|
-
|--------|-------------|
|
|
66
|
-
| modelling | ML model training (GLM, XGBoost, ResNet, FT-Transformer, GNN) and model interpretability |
|
|
67
|
-
| pricing | Factor table construction, numeric binning, premium calibration, exposure calculation, PSI monitoring |
|
|
68
|
-
| production | Model prediction, batch scoring, data drift detection, production metrics monitoring |
|
|
69
|
-
| governance | Model registry, version management, approval workflows, audit logging |
|
|
70
|
-
| reporting | Report generation (Markdown format), report scheduling |
|
|
71
|
-
| utils | Data validation, performance profiling, device management, logging configuration |
|
|
72
|
-
|
|
73
|
-
### Quick Start
|
|
74
|
-
|
|
75
|
-
```python
|
|
76
|
-
# Model training with Bayesian optimization
|
|
77
|
-
from ins_pricing import bayesopt as ropt
|
|
78
|
-
|
|
79
|
-
model = ropt.BayesOptModel(
|
|
80
|
-
train_data, test_data,
|
|
81
|
-
model_name='my_model',
|
|
82
|
-
resp_nme='target',
|
|
83
|
-
weight_nme='weight',
|
|
84
|
-
factor_nmes=feature_list,
|
|
85
|
-
cate_list=categorical_features,
|
|
86
|
-
)
|
|
87
|
-
model.bayesopt_xgb(max_evals=100) # Train XGBoost
|
|
88
|
-
model.bayesopt_resnet(max_evals=50) # Train ResNet
|
|
89
|
-
model.bayesopt_ft(max_evals=50) # Train FT-Transformer
|
|
90
|
-
|
|
91
|
-
# Pricing: build factor table
|
|
92
|
-
from ins_pricing.pricing import build_factor_table
|
|
93
|
-
factors = build_factor_table(
|
|
94
|
-
df,
|
|
95
|
-
factor_col='age_band',
|
|
96
|
-
loss_col='claim_amount',
|
|
97
|
-
exposure_col='exposure',
|
|
98
|
-
)
|
|
99
|
-
|
|
100
|
-
# Production: batch scoring
|
|
101
|
-
from ins_pricing.production import batch_score
|
|
102
|
-
scores = batch_score(model.trainers['xgb'].predict, df)
|
|
103
|
-
|
|
104
|
-
# Model governance
|
|
105
|
-
from ins_pricing.governance import ModelRegistry
|
|
106
|
-
registry = ModelRegistry('models.json')
|
|
107
|
-
registry.register(model_name, version, metrics=metrics)
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
### Project Structure
|
|
111
|
-
|
|
112
|
-
```
|
|
113
|
-
ins_pricing/
|
|
114
|
-
cli/ # Command-line entry points
|
|
115
|
-
modelling/
|
|
116
|
-
core/bayesopt/ # ML model training core
|
|
117
|
-
explain/ # Model interpretability
|
|
118
|
-
plotting/ # Model visualization
|
|
119
|
-
pricing/ # Insurance pricing module
|
|
120
|
-
production/ # Production deployment module
|
|
121
|
-
governance/ # Model governance
|
|
122
|
-
reporting/ # Report generation
|
|
123
|
-
utils/ # Utilities
|
|
124
|
-
tests/ # Test suite
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
### Installation
|
|
128
|
-
|
|
129
|
-
```bash
|
|
130
|
-
# Basic installation
|
|
131
|
-
pip install ins_pricing
|
|
132
|
-
|
|
133
|
-
# Full installation (all optional dependencies)
|
|
134
|
-
pip install ins_pricing[all]
|
|
135
|
-
|
|
136
|
-
# Install specific extras
|
|
137
|
-
pip install ins_pricing[bayesopt] # Model training
|
|
138
|
-
pip install ins_pricing[explain] # Model explanation
|
|
139
|
-
pip install ins_pricing[plotting] # Visualization
|
|
140
|
-
pip install ins_pricing[gnn] # Graph neural networks
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
#### Multi-platform and GPU notes
|
|
144
|
-
|
|
145
|
-
- Install the correct PyTorch build for your platform/GPU before installing extras.
|
|
146
|
-
- Torch Geometric requires platform-specific wheels; follow the official PyG install guide.
|
|
147
|
-
- Multi-GPU uses torch.distributed/DataParallel where supported; Windows disables CUDA DDP.
|
|
148
|
-
|
|
149
|
-
---
|
|
150
|
-
## PyPI Upload (scripts)
|
|
151
|
-
|
|
152
|
-
This repo includes upload scripts for Windows and Linux/macOS.
|
|
153
|
-
|
|
154
|
-
### Windows
|
|
155
|
-
|
|
156
|
-
```cmd
|
|
157
|
-
set TWINE_PASSWORD=your_pypi_token_here
|
|
158
|
-
python -m build
|
|
159
|
-
upload_to_pypi.bat
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
### Linux / macOS
|
|
163
|
-
|
|
164
|
-
```bash
|
|
165
|
-
chmod +x upload_to_pypi.sh
|
|
166
|
-
export TWINE_PASSWORD='your_pypi_token_here'
|
|
167
|
-
python -m build
|
|
168
|
-
./upload_to_pypi.sh
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
### Makefile (if make is available)
|
|
172
|
-
|
|
173
|
-
```bash
|
|
174
|
-
make build
|
|
175
|
-
make upload
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
### Tips
|
|
179
|
-
|
|
180
|
-
- Never commit tokens to version control.
|
|
181
|
-
- Use environment variables or secret managers to store credentials.
|
|
182
|
-
- Test with TestPyPI before publishing when needed.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ins_pricing
|
|
3
|
+
Version: 0.5.3
|
|
4
|
+
Summary: Reusable modelling, pricing, governance, and reporting utilities.
|
|
5
|
+
Author: meishi125478
|
|
6
|
+
License: Proprietary
|
|
7
|
+
Keywords: pricing,insurance,bayesopt,ml
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
11
|
+
Classifier: License :: Other/Proprietary License
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Requires-Python: >=3.9
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
Requires-Dist: numpy>=1.20
|
|
17
|
+
Requires-Dist: pandas>=1.4
|
|
18
|
+
Provides-Extra: bayesopt
|
|
19
|
+
Requires-Dist: torch>=1.13; extra == "bayesopt"
|
|
20
|
+
Requires-Dist: optuna>=3.0; extra == "bayesopt"
|
|
21
|
+
Requires-Dist: xgboost>=1.6; extra == "bayesopt"
|
|
22
|
+
Requires-Dist: scikit-learn>=1.1; extra == "bayesopt"
|
|
23
|
+
Requires-Dist: statsmodels>=0.13; extra == "bayesopt"
|
|
24
|
+
Requires-Dist: joblib>=1.2; extra == "bayesopt"
|
|
25
|
+
Requires-Dist: matplotlib>=3.5; extra == "bayesopt"
|
|
26
|
+
Provides-Extra: plotting
|
|
27
|
+
Requires-Dist: matplotlib>=3.5; extra == "plotting"
|
|
28
|
+
Requires-Dist: scikit-learn>=1.1; extra == "plotting"
|
|
29
|
+
Provides-Extra: explain
|
|
30
|
+
Requires-Dist: torch>=1.13; extra == "explain"
|
|
31
|
+
Requires-Dist: shap>=0.41; extra == "explain"
|
|
32
|
+
Requires-Dist: scikit-learn>=1.1; extra == "explain"
|
|
33
|
+
Provides-Extra: geo
|
|
34
|
+
Requires-Dist: contextily>=1.3; extra == "geo"
|
|
35
|
+
Requires-Dist: matplotlib>=3.5; extra == "geo"
|
|
36
|
+
Provides-Extra: gnn
|
|
37
|
+
Requires-Dist: torch>=1.13; extra == "gnn"
|
|
38
|
+
Requires-Dist: pynndescent>=0.5; extra == "gnn"
|
|
39
|
+
Requires-Dist: torch-geometric>=2.3; extra == "gnn"
|
|
40
|
+
Provides-Extra: all
|
|
41
|
+
Requires-Dist: torch>=1.13; extra == "all"
|
|
42
|
+
Requires-Dist: optuna>=3.0; extra == "all"
|
|
43
|
+
Requires-Dist: xgboost>=1.6; extra == "all"
|
|
44
|
+
Requires-Dist: scikit-learn>=1.1; extra == "all"
|
|
45
|
+
Requires-Dist: statsmodels>=0.13; extra == "all"
|
|
46
|
+
Requires-Dist: joblib>=1.2; extra == "all"
|
|
47
|
+
Requires-Dist: matplotlib>=3.5; extra == "all"
|
|
48
|
+
Requires-Dist: shap>=0.41; extra == "all"
|
|
49
|
+
Requires-Dist: contextily>=1.3; extra == "all"
|
|
50
|
+
Requires-Dist: pynndescent>=0.5; extra == "all"
|
|
51
|
+
Requires-Dist: torch-geometric>=2.3; extra == "all"
|
|
52
|
+
|
|
53
|
+
# Insurance-Pricing
|
|
54
|
+
|
|
55
|
+
A reusable toolkit for insurance modeling, pricing, governance, and reporting.
|
|
56
|
+
|
|
57
|
+
## Overview
|
|
58
|
+
|
|
59
|
+
Insurance-Pricing (ins_pricing) is an enterprise-grade Python library designed for machine learning
|
|
60
|
+
model training, pricing calculations, and model governance workflows in the insurance industry.
|
|
61
|
+
|
|
62
|
+
### Core Modules
|
|
63
|
+
|
|
64
|
+
| Module | Description |
|
|
65
|
+
|--------|-------------|
|
|
66
|
+
| modelling | ML model training (GLM, XGBoost, ResNet, FT-Transformer, GNN) and model interpretability |
|
|
67
|
+
| pricing | Factor table construction, numeric binning, premium calibration, exposure calculation, PSI monitoring |
|
|
68
|
+
| production | Model prediction, batch scoring, data drift detection, production metrics monitoring |
|
|
69
|
+
| governance | Model registry, version management, approval workflows, audit logging |
|
|
70
|
+
| reporting | Report generation (Markdown format), report scheduling |
|
|
71
|
+
| utils | Data validation, performance profiling, device management, logging configuration |
|
|
72
|
+
|
|
73
|
+
### Quick Start
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
# Model training with Bayesian optimization
|
|
77
|
+
from ins_pricing import bayesopt as ropt
|
|
78
|
+
|
|
79
|
+
model = ropt.BayesOptModel(
|
|
80
|
+
train_data, test_data,
|
|
81
|
+
model_name='my_model',
|
|
82
|
+
resp_nme='target',
|
|
83
|
+
weight_nme='weight',
|
|
84
|
+
factor_nmes=feature_list,
|
|
85
|
+
cate_list=categorical_features,
|
|
86
|
+
)
|
|
87
|
+
model.bayesopt_xgb(max_evals=100) # Train XGBoost
|
|
88
|
+
model.bayesopt_resnet(max_evals=50) # Train ResNet
|
|
89
|
+
model.bayesopt_ft(max_evals=50) # Train FT-Transformer
|
|
90
|
+
|
|
91
|
+
# Pricing: build factor table
|
|
92
|
+
from ins_pricing.pricing import build_factor_table
|
|
93
|
+
factors = build_factor_table(
|
|
94
|
+
df,
|
|
95
|
+
factor_col='age_band',
|
|
96
|
+
loss_col='claim_amount',
|
|
97
|
+
exposure_col='exposure',
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
# Production: batch scoring
|
|
101
|
+
from ins_pricing.production import batch_score
|
|
102
|
+
scores = batch_score(model.trainers['xgb'].predict, df)
|
|
103
|
+
|
|
104
|
+
# Model governance
|
|
105
|
+
from ins_pricing.governance import ModelRegistry
|
|
106
|
+
registry = ModelRegistry('models.json')
|
|
107
|
+
registry.register(model_name, version, metrics=metrics)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Project Structure
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
ins_pricing/
|
|
114
|
+
cli/ # Command-line entry points
|
|
115
|
+
modelling/
|
|
116
|
+
core/bayesopt/ # ML model training core
|
|
117
|
+
explain/ # Model interpretability
|
|
118
|
+
plotting/ # Model visualization
|
|
119
|
+
pricing/ # Insurance pricing module
|
|
120
|
+
production/ # Production deployment module
|
|
121
|
+
governance/ # Model governance
|
|
122
|
+
reporting/ # Report generation
|
|
123
|
+
utils/ # Utilities
|
|
124
|
+
tests/ # Test suite
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Installation
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
# Basic installation
|
|
131
|
+
pip install ins_pricing
|
|
132
|
+
|
|
133
|
+
# Full installation (all optional dependencies)
|
|
134
|
+
pip install ins_pricing[all]
|
|
135
|
+
|
|
136
|
+
# Install specific extras
|
|
137
|
+
pip install ins_pricing[bayesopt] # Model training
|
|
138
|
+
pip install ins_pricing[explain] # Model explanation
|
|
139
|
+
pip install ins_pricing[plotting] # Visualization
|
|
140
|
+
pip install ins_pricing[gnn] # Graph neural networks
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
#### Multi-platform and GPU notes
|
|
144
|
+
|
|
145
|
+
- Install the correct PyTorch build for your platform/GPU before installing extras.
|
|
146
|
+
- Torch Geometric requires platform-specific wheels; follow the official PyG install guide.
|
|
147
|
+
- Multi-GPU uses torch.distributed/DataParallel where supported; Windows disables CUDA DDP.
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
## PyPI Upload (scripts)
|
|
151
|
+
|
|
152
|
+
This repo includes upload scripts for Windows and Linux/macOS.
|
|
153
|
+
|
|
154
|
+
### Windows
|
|
155
|
+
|
|
156
|
+
```cmd
|
|
157
|
+
set TWINE_PASSWORD=your_pypi_token_here
|
|
158
|
+
python -m build
|
|
159
|
+
upload_to_pypi.bat
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Linux / macOS
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
chmod +x upload_to_pypi.sh
|
|
166
|
+
export TWINE_PASSWORD='your_pypi_token_here'
|
|
167
|
+
python -m build
|
|
168
|
+
./upload_to_pypi.sh
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Makefile (if make is available)
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
make build
|
|
175
|
+
make upload
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Tips
|
|
179
|
+
|
|
180
|
+
- Never commit tokens to version control.
|
|
181
|
+
- Use environment variables or secret managers to store credentials.
|
|
182
|
+
- Test with TestPyPI before publishing when needed.
|