ins-pricing 0.3.3__tar.gz → 0.3.4__tar.gz

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.
Files changed (133) hide show
  1. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/PKG-INFO +162 -162
  2. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/docs/modelling/BayesOpt_USAGE.md +3 -3
  3. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/bayesopt/config_preprocess.py +12 -0
  4. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/bayesopt/core.py +21 -8
  5. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/bayesopt/models/model_ft_trainer.py +16 -6
  6. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/bayesopt/models/model_gnn.py +16 -6
  7. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/bayesopt/models/model_resn.py +16 -7
  8. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/bayesopt/trainers/trainer_base.py +2 -0
  9. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/bayesopt/trainers/trainer_ft.py +25 -8
  10. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/bayesopt/trainers/trainer_glm.py +14 -11
  11. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/bayesopt/trainers/trainer_gnn.py +29 -10
  12. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/bayesopt/trainers/trainer_resn.py +28 -12
  13. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/bayesopt/trainers/trainer_xgb.py +13 -14
  14. ins_pricing-0.3.4/ins_pricing/modelling/core/bayesopt/utils/losses.py +129 -0
  15. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/bayesopt/utils/metrics_and_devices.py +18 -3
  16. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/bayesopt/utils/torch_trainer_mixin.py +24 -3
  17. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/production/predict.py +38 -9
  18. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/setup.py +1 -1
  19. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/utils/metrics.py +27 -3
  20. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing.egg-info/PKG-INFO +162 -162
  21. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing.egg-info/SOURCES.txt +1 -0
  22. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/pyproject.toml +1 -1
  23. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/setup.cfg +4 -4
  24. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/MANIFEST.in +0 -0
  25. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/README.md +0 -0
  26. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/CHANGELOG.md +0 -0
  27. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/README.md +0 -0
  28. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/RELEASE_NOTES_0.2.8.md +0 -0
  29. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/__init__.py +0 -0
  30. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/cli/BayesOpt_entry.py +0 -0
  31. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/cli/BayesOpt_incremental.py +0 -0
  32. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/cli/Explain_Run.py +0 -0
  33. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/cli/Explain_entry.py +0 -0
  34. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/cli/Pricing_Run.py +0 -0
  35. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/cli/__init__.py +0 -0
  36. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/cli/bayesopt_entry_runner.py +0 -0
  37. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/cli/utils/__init__.py +0 -0
  38. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/cli/utils/cli_common.py +0 -0
  39. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/cli/utils/cli_config.py +0 -0
  40. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/cli/utils/evaluation_context.py +0 -0
  41. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/cli/utils/import_resolver.py +0 -0
  42. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/cli/utils/notebook_utils.py +0 -0
  43. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/cli/utils/run_logging.py +0 -0
  44. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/cli/watchdog_run.py +0 -0
  45. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/docs/modelling/README.md +0 -0
  46. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/exceptions.py +0 -0
  47. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/governance/README.md +0 -0
  48. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/governance/__init__.py +0 -0
  49. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/governance/approval.py +0 -0
  50. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/governance/audit.py +0 -0
  51. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/governance/registry.py +0 -0
  52. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/governance/release.py +0 -0
  53. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/__init__.py +0 -0
  54. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/BayesOpt.py +0 -0
  55. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/__init__.py +0 -0
  56. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/bayesopt/PHASE2_REFACTORING_SUMMARY.md +0 -0
  57. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/bayesopt/PHASE3_REFACTORING_SUMMARY.md +0 -0
  58. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/bayesopt/REFACTORING_SUMMARY.md +0 -0
  59. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/bayesopt/__init__.py +0 -0
  60. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/bayesopt/config_components.py +0 -0
  61. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/bayesopt/model_explain_mixin.py +0 -0
  62. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/bayesopt/model_plotting_mixin.py +0 -0
  63. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/bayesopt/models/__init__.py +0 -0
  64. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/bayesopt/models/model_ft_components.py +0 -0
  65. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/bayesopt/trainers/__init__.py +0 -0
  66. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/bayesopt/utils/__init__.py +0 -0
  67. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/bayesopt/utils/constants.py +0 -0
  68. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/bayesopt/utils/distributed_utils.py +0 -0
  69. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/bayesopt/utils/io_utils.py +0 -0
  70. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/bayesopt/utils.py +0 -0
  71. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/bayesopt/utils_backup.py +0 -0
  72. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/core/evaluation.py +0 -0
  73. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/explain/__init__.py +0 -0
  74. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/explain/gradients.py +0 -0
  75. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/explain/metrics.py +0 -0
  76. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/explain/permutation.py +0 -0
  77. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/explain/shap_utils.py +0 -0
  78. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/plotting/__init__.py +0 -0
  79. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/plotting/common.py +0 -0
  80. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/plotting/curves.py +0 -0
  81. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/plotting/diagnostics.py +0 -0
  82. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/plotting/geo.py +0 -0
  83. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/modelling/plotting/importance.py +0 -0
  84. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/pricing/README.md +0 -0
  85. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/pricing/__init__.py +0 -0
  86. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/pricing/calibration.py +0 -0
  87. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/pricing/data_quality.py +0 -0
  88. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/pricing/exposure.py +0 -0
  89. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/pricing/factors.py +0 -0
  90. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/pricing/monitoring.py +0 -0
  91. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/pricing/rate_table.py +0 -0
  92. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/production/__init__.py +0 -0
  93. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/production/drift.py +0 -0
  94. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/production/monitoring.py +0 -0
  95. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/production/preprocess.py +0 -0
  96. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/production/scoring.py +0 -0
  97. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/reporting/README.md +0 -0
  98. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/reporting/__init__.py +0 -0
  99. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/reporting/report_builder.py +0 -0
  100. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/reporting/scheduler.py +0 -0
  101. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/tests/governance/__init__.py +0 -0
  102. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/tests/governance/test_audit.py +0 -0
  103. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/tests/governance/test_registry.py +0 -0
  104. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/tests/governance/test_release.py +0 -0
  105. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/tests/modelling/conftest.py +0 -0
  106. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/tests/modelling/test_cross_val_generic.py +0 -0
  107. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/tests/modelling/test_distributed_utils.py +0 -0
  108. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/tests/modelling/test_explain.py +0 -0
  109. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/tests/modelling/test_geo_tokens_split.py +0 -0
  110. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/tests/modelling/test_graph_cache.py +0 -0
  111. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/tests/modelling/test_plotting.py +0 -0
  112. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/tests/modelling/test_plotting_library.py +0 -0
  113. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/tests/modelling/test_preprocessor.py +0 -0
  114. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/tests/pricing/__init__.py +0 -0
  115. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/tests/pricing/test_calibration.py +0 -0
  116. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/tests/pricing/test_exposure.py +0 -0
  117. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/tests/pricing/test_factors.py +0 -0
  118. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/tests/pricing/test_rate_table.py +0 -0
  119. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/tests/production/__init__.py +0 -0
  120. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/tests/production/test_monitoring.py +0 -0
  121. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/tests/production/test_predict.py +0 -0
  122. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/tests/production/test_preprocess.py +0 -0
  123. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/tests/production/test_scoring.py +0 -0
  124. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/utils/__init__.py +0 -0
  125. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/utils/device.py +0 -0
  126. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/utils/logging.py +0 -0
  127. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/utils/paths.py +0 -0
  128. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/utils/profiling.py +0 -0
  129. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/utils/torch_compat.py +0 -0
  130. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing/utils/validation.py +0 -0
  131. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing.egg-info/dependency_links.txt +0 -0
  132. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing.egg-info/requires.txt +0 -0
  133. {ins_pricing-0.3.3 → ins_pricing-0.3.4}/ins_pricing.egg-info/top_level.txt +0 -0
@@ -1,162 +1,162 @@
1
- Metadata-Version: 2.4
2
- Name: ins_pricing
3
- Version: 0.3.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 model training, pricing calculations, and model governance workflows in the insurance industry.
60
-
61
- ### Core Modules
62
-
63
- | Module | Description |
64
- |--------|-------------|
65
- | **modelling** | ML model training (GLM, XGBoost, ResNet, FT-Transformer, GNN) and model interpretability (SHAP, permutation importance) |
66
- | **pricing** | Factor table construction, numeric binning, premium calibration, exposure calculation, PSI monitoring |
67
- | **production** | Model prediction, batch scoring, data drift detection, production metrics monitoring |
68
- | **governance** | Model registry, version management, approval workflows, audit logging |
69
- | **reporting** | Report generation (Markdown format), report scheduling |
70
- | **utils** | Data validation, performance profiling, device management, logging configuration |
71
-
72
- ### Quick Start
73
-
74
- ```python
75
- # Model training with Bayesian optimization
76
- from ins_pricing import bayesopt as ropt
77
-
78
- model = ropt.BayesOptModel(
79
- train_data, test_data,
80
- model_name='my_model',
81
- resp_nme='target',
82
- weight_nme='weight',
83
- factor_nmes=feature_list,
84
- cate_list=categorical_features,
85
- )
86
- model.bayesopt_xgb(max_evals=100) # Train XGBoost
87
- model.bayesopt_resnet(max_evals=50) # Train ResNet
88
- model.bayesopt_ft(max_evals=50) # Train FT-Transformer
89
-
90
- # Pricing: build factor table
91
- from ins_pricing.pricing import build_factor_table
92
- factors = build_factor_table(
93
- df,
94
- factor_col='age_band',
95
- loss_col='claim_amount',
96
- exposure_col='exposure',
97
- )
98
-
99
- # Production: batch scoring
100
- from ins_pricing.production import batch_score
101
- scores = batch_score(model.trainers['xgb'].predict, df)
102
-
103
- # Model governance
104
- from ins_pricing.governance import ModelRegistry
105
- registry = ModelRegistry('models.json')
106
- registry.register(model_name, version, metrics=metrics)
107
- ```
108
-
109
- ### Project Structure
110
-
111
- ```
112
- ins_pricing/
113
- ├── cli/ # Command-line entry points
114
- ├── modelling/
115
- │ ├── core/bayesopt/ # ML model training core
116
- │ ├── explain/ # Model interpretability
117
- │ └── plotting/ # Model visualization
118
- ├── pricing/ # Insurance pricing module
119
- ├── production/ # Production deployment module
120
- ├── governance/ # Model governance
121
- ├── reporting/ # Report generation
122
- ├── utils/ # Utilities
123
- └── tests/ # Test suite
124
- ```
125
-
126
- ### Installation
127
-
128
- ```bash
129
- # Basic installation
130
- pip install ins_pricing
131
-
132
- # Full installation (all optional dependencies)
133
- pip install ins_pricing[all]
134
-
135
- # Install specific extras
136
- pip install ins_pricing[bayesopt] # Model training
137
- pip install ins_pricing[explain] # Model explanation
138
- pip install ins_pricing[plotting] # Visualization
139
- pip install ins_pricing[gnn] # Graph neural networks
140
- ```
141
-
142
- #### Multi-platform & GPU installation notes
143
-
144
- - **PyTorch (CPU/GPU/MPS)**: Install the correct PyTorch build for your platform/GPU first (CUDA on
145
- Linux/Windows, ROCm on supported AMD platforms, or MPS on Apple Silicon). Then install the
146
- optional extras you need (e.g., `bayesopt`, `explain`, or `gnn`). This avoids pip pulling a
147
- mismatched wheel.
148
- - **Torch Geometric (GNN)**: `torch-geometric` often requires platform-specific wheels (e.g.,
149
- `torch-scatter`, `torch-sparse`). Follow the official PyG installation instructions for your
150
- CUDA/ROCm/CPU environment, then install `ins_pricing[gnn]`.
151
- - **Multi-GPU**: Training code will use CUDA when available and can enable multi-GPU via
152
- `torch.distributed`/`DataParallel` where supported. On Windows, CUDA DDP is not supported and will
153
- fall back to single-GPU or DataParallel where possible.
154
-
155
- ### Requirements
156
-
157
- - Python >= 3.9
158
- - Core dependencies: numpy >= 1.20, pandas >= 1.4
159
-
160
- ### License
161
-
162
- Proprietary
1
+ Metadata-Version: 2.4
2
+ Name: ins_pricing
3
+ Version: 0.3.4
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 model training, pricing calculations, and model governance workflows in the insurance industry.
60
+
61
+ ### Core Modules
62
+
63
+ | Module | Description |
64
+ |--------|-------------|
65
+ | **modelling** | ML model training (GLM, XGBoost, ResNet, FT-Transformer, GNN) and model interpretability (SHAP, permutation importance) |
66
+ | **pricing** | Factor table construction, numeric binning, premium calibration, exposure calculation, PSI monitoring |
67
+ | **production** | Model prediction, batch scoring, data drift detection, production metrics monitoring |
68
+ | **governance** | Model registry, version management, approval workflows, audit logging |
69
+ | **reporting** | Report generation (Markdown format), report scheduling |
70
+ | **utils** | Data validation, performance profiling, device management, logging configuration |
71
+
72
+ ### Quick Start
73
+
74
+ ```python
75
+ # Model training with Bayesian optimization
76
+ from ins_pricing import bayesopt as ropt
77
+
78
+ model = ropt.BayesOptModel(
79
+ train_data, test_data,
80
+ model_name='my_model',
81
+ resp_nme='target',
82
+ weight_nme='weight',
83
+ factor_nmes=feature_list,
84
+ cate_list=categorical_features,
85
+ )
86
+ model.bayesopt_xgb(max_evals=100) # Train XGBoost
87
+ model.bayesopt_resnet(max_evals=50) # Train ResNet
88
+ model.bayesopt_ft(max_evals=50) # Train FT-Transformer
89
+
90
+ # Pricing: build factor table
91
+ from ins_pricing.pricing import build_factor_table
92
+ factors = build_factor_table(
93
+ df,
94
+ factor_col='age_band',
95
+ loss_col='claim_amount',
96
+ exposure_col='exposure',
97
+ )
98
+
99
+ # Production: batch scoring
100
+ from ins_pricing.production import batch_score
101
+ scores = batch_score(model.trainers['xgb'].predict, df)
102
+
103
+ # Model governance
104
+ from ins_pricing.governance import ModelRegistry
105
+ registry = ModelRegistry('models.json')
106
+ registry.register(model_name, version, metrics=metrics)
107
+ ```
108
+
109
+ ### Project Structure
110
+
111
+ ```
112
+ ins_pricing/
113
+ ├── cli/ # Command-line entry points
114
+ ├── modelling/
115
+ │ ├── core/bayesopt/ # ML model training core
116
+ │ ├── explain/ # Model interpretability
117
+ │ └── plotting/ # Model visualization
118
+ ├── pricing/ # Insurance pricing module
119
+ ├── production/ # Production deployment module
120
+ ├── governance/ # Model governance
121
+ ├── reporting/ # Report generation
122
+ ├── utils/ # Utilities
123
+ └── tests/ # Test suite
124
+ ```
125
+
126
+ ### Installation
127
+
128
+ ```bash
129
+ # Basic installation
130
+ pip install ins_pricing
131
+
132
+ # Full installation (all optional dependencies)
133
+ pip install ins_pricing[all]
134
+
135
+ # Install specific extras
136
+ pip install ins_pricing[bayesopt] # Model training
137
+ pip install ins_pricing[explain] # Model explanation
138
+ pip install ins_pricing[plotting] # Visualization
139
+ pip install ins_pricing[gnn] # Graph neural networks
140
+ ```
141
+
142
+ #### Multi-platform & GPU installation notes
143
+
144
+ - **PyTorch (CPU/GPU/MPS)**: Install the correct PyTorch build for your platform/GPU first (CUDA on
145
+ Linux/Windows, ROCm on supported AMD platforms, or MPS on Apple Silicon). Then install the
146
+ optional extras you need (e.g., `bayesopt`, `explain`, or `gnn`). This avoids pip pulling a
147
+ mismatched wheel.
148
+ - **Torch Geometric (GNN)**: `torch-geometric` often requires platform-specific wheels (e.g.,
149
+ `torch-scatter`, `torch-sparse`). Follow the official PyG installation instructions for your
150
+ CUDA/ROCm/CPU environment, then install `ins_pricing[gnn]`.
151
+ - **Multi-GPU**: Training code will use CUDA when available and can enable multi-GPU via
152
+ `torch.distributed`/`DataParallel` where supported. On Windows, CUDA DDP is not supported and will
153
+ fall back to single-GPU or DataParallel where possible.
154
+
155
+ ### Requirements
156
+
157
+ - Python >= 3.9
158
+ - Core dependencies: numpy >= 1.20, pandas >= 1.4
159
+
160
+ ### License
161
+
162
+ Proprietary
@@ -75,13 +75,13 @@ Under `ins_pricing/modelling/core/bayesopt/`:
75
75
 
76
76
  1) **Tools and utilities**
77
77
 
78
- - `IOUtils / TrainingUtils / PlotUtils`: I/O, training utilities (batch size, tweedie loss, free_cuda), plotting helpers
78
+ - `IOUtils / TrainingUtils / PlotUtils`: I/O, training utilities (batch size, loss functions, free_cuda), plotting helpers
79
79
  - `DistributedUtils`: DDP init, rank/world_size helpers
80
80
 
81
81
  2) **TorchTrainerMixin (common components for torch tabular training)**
82
82
 
83
83
  - DataLoader: `_build_dataloader()` / `_build_val_dataloader()` (prints batch/accum/workers)
84
- - Loss: `_compute_losses()` / `_compute_weighted_loss()` (regression uses tweedie; classification uses BCEWithLogits)
84
+ - Loss: `_compute_losses()` / `_compute_weighted_loss()` (regression supports tweedie/poisson/gamma/mse/mae; classification uses BCEWithLogits)
85
85
  - Early stop: `_early_stop_update()`
86
86
 
87
87
  3) **Sklearn-style model classes (core training objects)**
@@ -292,7 +292,7 @@ FT role is controlled by `ft_role` (from config or CLI `--ft-role`):
292
292
  ### 4.1 Supervised models (GLM/XGB/ResNet/FT-as-model)
293
293
 
294
294
  - `TrainerBase.tune()` calls each trainer's `cross_val()` and minimizes validation metric (default direction `minimize`)
295
- - Regression typically uses Tweedie deviance or related loss; classification uses logloss
295
+ - Regression loss is configurable (tweedie/poisson/gamma/mse/mae); classification uses logloss
296
296
 
297
297
  ### 4.2 FT self-supervised (`unsupervised_embedding`)
298
298
 
@@ -12,6 +12,7 @@ import pandas as pd
12
12
  from sklearn.preprocessing import StandardScaler
13
13
 
14
14
  from .utils import IOUtils
15
+ from .utils.losses import normalize_loss_name
15
16
  from ....exceptions import ConfigurationError, DataValidationError
16
17
 
17
18
  # NOTE: Some CSV exports may contain invisible BOM characters or leading/trailing
@@ -81,6 +82,7 @@ class BayesOptConfig:
81
82
  task_type: Either 'regression' or 'classification'
82
83
  binary_resp_nme: Column name for binary response (optional)
83
84
  cate_list: List of categorical feature column names
85
+ loss_name: Regression loss ('auto', 'tweedie', 'poisson', 'gamma', 'mse', 'mae')
84
86
  prop_test: Proportion of data for validation (0.0-1.0)
85
87
  rand_seed: Random seed for reproducibility
86
88
  epochs: Number of training epochs
@@ -117,6 +119,7 @@ class BayesOptConfig:
117
119
  task_type: str = 'regression'
118
120
  binary_resp_nme: Optional[str] = None
119
121
  cate_list: Optional[List[str]] = None
122
+ loss_name: str = "auto"
120
123
 
121
124
  # Training configuration
122
125
  prop_test: float = 0.25
@@ -207,6 +210,15 @@ class BayesOptConfig:
207
210
  errors.append(
208
211
  f"task_type must be one of {valid_task_types}, got '{self.task_type}'"
209
212
  )
213
+ # Validate loss_name
214
+ try:
215
+ normalized_loss = normalize_loss_name(self.loss_name, self.task_type)
216
+ if self.task_type == "classification" and normalized_loss not in {"auto", "logloss", "bce"}:
217
+ errors.append(
218
+ "loss_name must be 'auto', 'logloss', or 'bce' for classification tasks."
219
+ )
220
+ except ValueError as exc:
221
+ errors.append(str(exc))
210
222
 
211
223
  # Validate prop_test
212
224
  if not 0.0 < self.prop_test < 1.0:
@@ -17,6 +17,12 @@ from .model_plotting_mixin import BayesOptPlottingMixin
17
17
  from .models import GraphNeuralNetSklearn
18
18
  from .trainers import FTTrainer, GLMTrainer, GNNTrainer, ResNetTrainer, XGBTrainer
19
19
  from .utils import EPS, infer_factor_and_cate_list, set_global_seed
20
+ from .utils.losses import (
21
+ infer_loss_name_from_model_name,
22
+ normalize_loss_name,
23
+ resolve_tweedie_power,
24
+ resolve_xgb_objective,
25
+ )
20
26
 
21
27
 
22
28
  class _CVSplitter:
@@ -293,6 +299,14 @@ class BayesOptModel(BayesOptPlottingMixin, BayesOptExplainMixin):
293
299
  self.config = cfg
294
300
  self.model_nme = cfg.model_nme
295
301
  self.task_type = cfg.task_type
302
+ normalized_loss = normalize_loss_name(getattr(cfg, "loss_name", None), self.task_type)
303
+ if self.task_type == "classification":
304
+ self.loss_name = "logloss" if normalized_loss == "auto" else normalized_loss
305
+ else:
306
+ if normalized_loss == "auto":
307
+ self.loss_name = infer_loss_name_from_model_name(self.model_nme)
308
+ else:
309
+ self.loss_name = normalized_loss
296
310
  self.resp_nme = cfg.resp_nme
297
311
  self.weight_nme = cfg.weight_nme
298
312
  self.factor_nmes = cfg.factor_nmes
@@ -339,14 +353,7 @@ class BayesOptModel(BayesOptPlottingMixin, BayesOptExplainMixin):
339
353
  if self.task_type == 'classification':
340
354
  self.obj = 'binary:logistic'
341
355
  else: # regression task
342
- if 'f' in self.model_nme:
343
- self.obj = 'count:poisson'
344
- elif 's' in self.model_nme:
345
- self.obj = 'reg:gamma'
346
- elif 'bc' in self.model_nme:
347
- self.obj = 'reg:tweedie'
348
- else:
349
- self.obj = 'reg:tweedie'
356
+ self.obj = resolve_xgb_objective(self.loss_name)
350
357
  self.fit_params = {
351
358
  'sample_weight': self.train_data[self.weight_nme].values
352
359
  }
@@ -426,6 +433,11 @@ class BayesOptModel(BayesOptPlottingMixin, BayesOptExplainMixin):
426
433
  def default_tweedie_power(self, obj: Optional[str] = None) -> Optional[float]:
427
434
  if self.task_type == 'classification':
428
435
  return None
436
+ loss_name = getattr(self, "loss_name", None)
437
+ if loss_name:
438
+ resolved = resolve_tweedie_power(str(loss_name), default=1.5)
439
+ if resolved is not None:
440
+ return resolved
429
441
  objective = obj or getattr(self, "obj", None)
430
442
  if objective == 'count:poisson':
431
443
  return 1.0
@@ -503,6 +515,7 @@ class BayesOptModel(BayesOptPlottingMixin, BayesOptExplainMixin):
503
515
  patience=5,
504
516
  task_type=self.task_type,
505
517
  tweedie_power=tw_power,
518
+ loss_name=self.loss_name,
506
519
  use_data_parallel=False,
507
520
  use_ddp=False,
508
521
  use_approx_knn=self.config.gnn_use_approx_knn,
@@ -16,6 +16,11 @@ from torch.nn.parallel import DistributedDataParallel as DDP
16
16
  from torch.nn.utils import clip_grad_norm_
17
17
 
18
18
  from ..utils import DistributedUtils, EPS, TorchTrainerMixin
19
+ from ..utils.losses import (
20
+ infer_loss_name_from_model_name,
21
+ normalize_loss_name,
22
+ resolve_tweedie_power,
23
+ )
19
24
  from .model_ft_components import FTTransformerCore, MaskedTabularDataset, TabularDataset
20
25
 
21
26
 
@@ -159,7 +164,8 @@ class FTTransformerSklearn(TorchTrainerMixin, nn.Module):
159
164
  weight_decay: float = 0.0,
160
165
  use_data_parallel: bool = True,
161
166
  use_ddp: bool = False,
162
- num_numeric_tokens: Optional[int] = None
167
+ num_numeric_tokens: Optional[int] = None,
168
+ loss_name: Optional[str] = None
163
169
  ):
164
170
  super().__init__()
165
171
 
@@ -187,14 +193,18 @@ class FTTransformerSklearn(TorchTrainerMixin, nn.Module):
187
193
  self.weight_decay = weight_decay
188
194
  self.task_type = task_type
189
195
  self.patience = patience
196
+ resolved_loss = normalize_loss_name(loss_name, self.task_type)
190
197
  if self.task_type == 'classification':
198
+ self.loss_name = "logloss"
191
199
  self.tw_power = None # No Tweedie power for classification.
192
- elif 'f' in self.model_nme:
193
- self.tw_power = 1.0
194
- elif 's' in self.model_nme:
195
- self.tw_power = 2.0
196
200
  else:
197
- self.tw_power = tweedie_power
201
+ if resolved_loss == "auto":
202
+ resolved_loss = infer_loss_name_from_model_name(self.model_nme)
203
+ self.loss_name = resolved_loss
204
+ if self.loss_name == "tweedie":
205
+ self.tw_power = float(tweedie_power) if tweedie_power is not None else 1.5
206
+ else:
207
+ self.tw_power = resolve_tweedie_power(self.loss_name, default=1.5)
198
208
 
199
209
  if self.is_ddp_enabled:
200
210
  self.device = torch.device(f"cuda:{self.local_rank}")
@@ -17,6 +17,11 @@ from torch.nn.parallel import DistributedDataParallel as DDP
17
17
  from torch.nn.utils import clip_grad_norm_
18
18
 
19
19
  from ..utils import DistributedUtils, EPS, IOUtils, TorchTrainerMixin
20
+ from ..utils.losses import (
21
+ infer_loss_name_from_model_name,
22
+ normalize_loss_name,
23
+ resolve_tweedie_power,
24
+ )
20
25
 
21
26
  try:
22
27
  from torch_geometric.nn import knn_graph
@@ -109,7 +114,8 @@ class GraphNeuralNetSklearn(TorchTrainerMixin, nn.Module):
109
114
  max_gpu_knn_nodes: Optional[int] = None,
110
115
  knn_gpu_mem_ratio: float = 0.9,
111
116
  knn_gpu_mem_overhead: float = 2.0,
112
- knn_cpu_jobs: Optional[int] = -1) -> None:
117
+ knn_cpu_jobs: Optional[int] = -1,
118
+ loss_name: Optional[str] = None) -> None:
113
119
  super().__init__()
114
120
  self.model_nme = model_nme
115
121
  self.input_dim = input_dim
@@ -139,14 +145,18 @@ class GraphNeuralNetSklearn(TorchTrainerMixin, nn.Module):
139
145
  self._adj_cache_key: Optional[Tuple[Any, ...]] = None
140
146
  self._adj_cache_tensor: Optional[torch.Tensor] = None
141
147
 
148
+ resolved_loss = normalize_loss_name(loss_name, self.task_type)
142
149
  if self.task_type == 'classification':
150
+ self.loss_name = "logloss"
143
151
  self.tw_power = None
144
- elif 'f' in self.model_nme:
145
- self.tw_power = 1.0
146
- elif 's' in self.model_nme:
147
- self.tw_power = 2.0
148
152
  else:
149
- self.tw_power = tweedie_power
153
+ if resolved_loss == "auto":
154
+ resolved_loss = infer_loss_name_from_model_name(self.model_nme)
155
+ self.loss_name = resolved_loss
156
+ if self.loss_name == "tweedie":
157
+ self.tw_power = float(tweedie_power) if tweedie_power is not None else 1.5
158
+ else:
159
+ self.tw_power = resolve_tweedie_power(self.loss_name, default=1.5)
150
160
 
151
161
  self.ddp_enabled = False
152
162
  self.local_rank = int(os.environ.get("LOCAL_RANK", 0))
@@ -12,6 +12,11 @@ from torch.nn.utils import clip_grad_norm_
12
12
  from torch.utils.data import TensorDataset
13
13
 
14
14
  from ..utils import DistributedUtils, EPS, TorchTrainerMixin
15
+ from ..utils.losses import (
16
+ infer_loss_name_from_model_name,
17
+ normalize_loss_name,
18
+ resolve_tweedie_power,
19
+ )
15
20
 
16
21
 
17
22
  # =============================================================================
@@ -140,7 +145,8 @@ class ResNetSklearn(TorchTrainerMixin, nn.Module):
140
145
  stochastic_depth: float = 0.0,
141
146
  weight_decay: float = 1e-4,
142
147
  use_data_parallel: bool = True,
143
- use_ddp: bool = False):
148
+ use_ddp: bool = False,
149
+ loss_name: Optional[str] = None):
144
150
  super(ResNetSklearn, self).__init__()
145
151
 
146
152
  self.use_ddp = use_ddp
@@ -179,15 +185,18 @@ class ResNetSklearn(TorchTrainerMixin, nn.Module):
179
185
  else:
180
186
  self.device = torch.device('cpu')
181
187
 
182
- # Tweedie power (unused for classification)
188
+ resolved_loss = normalize_loss_name(loss_name, self.task_type)
183
189
  if self.task_type == 'classification':
190
+ self.loss_name = "logloss"
184
191
  self.tw_power = None
185
- elif 'f' in self.model_nme:
186
- self.tw_power = 1
187
- elif 's' in self.model_nme:
188
- self.tw_power = 2
189
192
  else:
190
- self.tw_power = tweedie_power
193
+ if resolved_loss == "auto":
194
+ resolved_loss = infer_loss_name_from_model_name(self.model_nme)
195
+ self.loss_name = resolved_loss
196
+ if self.loss_name == "tweedie":
197
+ self.tw_power = float(tweedie_power) if tweedie_power is not None else 1.5
198
+ else:
199
+ self.tw_power = resolve_tweedie_power(self.loss_name, default=1.5)
191
200
 
192
201
  # Build network (construct on CPU first)
193
202
  core = ResNetSequential(
@@ -578,6 +578,7 @@ class TrainerBase:
578
578
  "n_layers": getattr(self.model, "n_layers", 4),
579
579
  "dropout": getattr(self.model, "dropout", 0.1),
580
580
  "task_type": getattr(self.model, "task_type", "regression"),
581
+ "loss_name": getattr(self.model, "loss_name", None),
581
582
  "tw_power": getattr(self.model, "tw_power", 1.5),
582
583
  "num_geo": getattr(self.model, "num_geo", 0),
583
584
  "num_numeric_tokens": getattr(self.model, "num_numeric_tokens", None),
@@ -638,6 +639,7 @@ class TrainerBase:
638
639
  n_layers=model_config.get("n_layers", 4),
639
640
  dropout=model_config.get("dropout", 0.1),
640
641
  task_type=model_config.get("task_type", "regression"),
642
+ loss_name=model_config.get("loss_name", None),
641
643
  tweedie_power=model_config.get("tw_power", 1.5),
642
644
  num_numeric_tokens=model_config.get("num_numeric_tokens"),
643
645
  use_data_parallel=False,