ins-pricing 0.4.4__py3-none-any.whl → 0.5.0__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/README.md +74 -56
- ins_pricing/__init__.py +142 -90
- ins_pricing/cli/BayesOpt_entry.py +52 -50
- ins_pricing/cli/BayesOpt_incremental.py +832 -898
- ins_pricing/cli/Explain_Run.py +31 -23
- ins_pricing/cli/Explain_entry.py +532 -579
- ins_pricing/cli/Pricing_Run.py +31 -23
- ins_pricing/cli/bayesopt_entry_runner.py +1440 -1438
- ins_pricing/cli/utils/cli_common.py +256 -256
- ins_pricing/cli/utils/cli_config.py +375 -375
- ins_pricing/cli/utils/import_resolver.py +382 -365
- ins_pricing/cli/utils/notebook_utils.py +340 -340
- ins_pricing/cli/watchdog_run.py +209 -201
- ins_pricing/frontend/README.md +573 -419
- ins_pricing/frontend/__init__.py +10 -10
- ins_pricing/frontend/config_builder.py +1 -0
- ins_pricing/frontend/example_workflows.py +1 -1
- ins_pricing/governance/__init__.py +20 -20
- ins_pricing/governance/release.py +159 -159
- ins_pricing/modelling/README.md +67 -0
- ins_pricing/modelling/__init__.py +147 -92
- ins_pricing/modelling/bayesopt/README.md +59 -0
- ins_pricing/modelling/{core/bayesopt → bayesopt}/__init__.py +64 -102
- ins_pricing/modelling/{core/bayesopt → bayesopt}/config_preprocess.py +562 -550
- ins_pricing/modelling/{core/bayesopt → bayesopt}/core.py +965 -962
- ins_pricing/modelling/{core/bayesopt → bayesopt}/model_explain_mixin.py +296 -296
- ins_pricing/modelling/{core/bayesopt → bayesopt}/model_plotting_mixin.py +482 -548
- ins_pricing/modelling/{core/bayesopt → bayesopt}/models/__init__.py +27 -27
- ins_pricing/modelling/{core/bayesopt → bayesopt}/models/model_ft_trainer.py +915 -913
- ins_pricing/modelling/{core/bayesopt → bayesopt}/models/model_gnn.py +788 -785
- ins_pricing/modelling/{core/bayesopt → bayesopt}/models/model_resn.py +448 -446
- ins_pricing/modelling/bayesopt/trainers/__init__.py +19 -0
- ins_pricing/modelling/{core/bayesopt → bayesopt}/trainers/trainer_base.py +1308 -1308
- ins_pricing/modelling/{core/bayesopt → bayesopt}/trainers/trainer_ft.py +3 -3
- ins_pricing/modelling/{core/bayesopt → bayesopt}/trainers/trainer_glm.py +197 -198
- ins_pricing/modelling/{core/bayesopt → bayesopt}/trainers/trainer_gnn.py +344 -344
- ins_pricing/modelling/{core/bayesopt → bayesopt}/trainers/trainer_resn.py +283 -283
- ins_pricing/modelling/{core/bayesopt → bayesopt}/trainers/trainer_xgb.py +346 -347
- ins_pricing/modelling/bayesopt/utils/__init__.py +67 -0
- ins_pricing/modelling/bayesopt/utils/constants.py +21 -0
- ins_pricing/modelling/bayesopt/utils/io_utils.py +7 -0
- ins_pricing/modelling/bayesopt/utils/losses.py +27 -0
- ins_pricing/modelling/bayesopt/utils/metrics_and_devices.py +17 -0
- ins_pricing/modelling/{core/bayesopt → bayesopt}/utils/torch_trainer_mixin.py +623 -623
- ins_pricing/modelling/{core/evaluation.py → evaluation.py} +113 -104
- ins_pricing/modelling/explain/__init__.py +55 -55
- ins_pricing/modelling/explain/metrics.py +27 -174
- ins_pricing/modelling/explain/permutation.py +237 -237
- ins_pricing/modelling/plotting/__init__.py +40 -36
- ins_pricing/modelling/plotting/compat.py +228 -0
- ins_pricing/modelling/plotting/curves.py +572 -572
- ins_pricing/modelling/plotting/diagnostics.py +163 -163
- ins_pricing/modelling/plotting/geo.py +362 -362
- ins_pricing/modelling/plotting/importance.py +121 -121
- ins_pricing/pricing/__init__.py +27 -27
- ins_pricing/production/__init__.py +35 -25
- ins_pricing/production/{predict.py → inference.py} +140 -57
- ins_pricing/production/monitoring.py +8 -21
- ins_pricing/reporting/__init__.py +11 -11
- ins_pricing/setup.py +1 -1
- ins_pricing/tests/production/test_inference.py +90 -0
- ins_pricing/utils/__init__.py +116 -83
- ins_pricing/utils/device.py +255 -255
- ins_pricing/utils/features.py +53 -0
- ins_pricing/utils/io.py +72 -0
- ins_pricing/{modelling/core/bayesopt/utils → utils}/losses.py +125 -129
- ins_pricing/utils/metrics.py +158 -24
- ins_pricing/utils/numerics.py +76 -0
- ins_pricing/utils/paths.py +9 -1
- {ins_pricing-0.4.4.dist-info → ins_pricing-0.5.0.dist-info}/METADATA +55 -35
- ins_pricing-0.5.0.dist-info/RECORD +131 -0
- ins_pricing/CHANGELOG.md +0 -272
- ins_pricing/RELEASE_NOTES_0.2.8.md +0 -344
- ins_pricing/docs/LOSS_FUNCTIONS.md +0 -78
- ins_pricing/docs/modelling/BayesOpt_USAGE.md +0 -945
- ins_pricing/docs/modelling/README.md +0 -34
- ins_pricing/frontend/QUICKSTART.md +0 -152
- ins_pricing/modelling/core/BayesOpt.py +0 -146
- ins_pricing/modelling/core/__init__.py +0 -1
- ins_pricing/modelling/core/bayesopt/PHASE2_REFACTORING_SUMMARY.md +0 -449
- ins_pricing/modelling/core/bayesopt/PHASE3_REFACTORING_SUMMARY.md +0 -406
- ins_pricing/modelling/core/bayesopt/REFACTORING_SUMMARY.md +0 -247
- ins_pricing/modelling/core/bayesopt/trainers/__init__.py +0 -19
- ins_pricing/modelling/core/bayesopt/utils/__init__.py +0 -86
- ins_pricing/modelling/core/bayesopt/utils/constants.py +0 -183
- ins_pricing/modelling/core/bayesopt/utils/io_utils.py +0 -126
- ins_pricing/modelling/core/bayesopt/utils/metrics_and_devices.py +0 -555
- ins_pricing/modelling/core/bayesopt/utils.py +0 -105
- ins_pricing/modelling/core/bayesopt/utils_backup.py +0 -1503
- ins_pricing/tests/production/test_predict.py +0 -233
- ins_pricing-0.4.4.dist-info/RECORD +0 -137
- /ins_pricing/modelling/{core/bayesopt → bayesopt}/config_components.py +0 -0
- /ins_pricing/modelling/{core/bayesopt → bayesopt}/models/model_ft_components.py +0 -0
- /ins_pricing/modelling/{core/bayesopt → bayesopt}/utils/distributed_utils.py +0 -0
- {ins_pricing-0.4.4.dist-info → ins_pricing-0.5.0.dist-info}/WHEEL +0 -0
- {ins_pricing-0.4.4.dist-info → ins_pricing-0.5.0.dist-info}/top_level.txt +0 -0
ins_pricing/frontend/__init__.py
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Insurance Pricing Frontend Package
|
|
3
|
-
Web-based interface for configuring and running insurance pricing model tasks.
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
from .config_builder import ConfigBuilder
|
|
7
|
-
from .runner import TaskRunner, TrainingRunner
|
|
8
|
-
from .ft_workflow import FTWorkflowHelper
|
|
9
|
-
|
|
10
|
-
__all__ = ['ConfigBuilder', 'TaskRunner', 'TrainingRunner', 'FTWorkflowHelper']
|
|
1
|
+
"""
|
|
2
|
+
Insurance Pricing Frontend Package
|
|
3
|
+
Web-based interface for configuring and running insurance pricing model tasks.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from ins_pricing.frontend.config_builder import ConfigBuilder
|
|
7
|
+
from ins_pricing.frontend.runner import TaskRunner, TrainingRunner
|
|
8
|
+
from ins_pricing.frontend.ft_workflow import FTWorkflowHelper
|
|
9
|
+
|
|
10
|
+
__all__ = ['ConfigBuilder', 'TaskRunner', 'TrainingRunner', 'FTWorkflowHelper']
|
|
@@ -19,7 +19,7 @@ from ins_pricing.modelling.plotting import (
|
|
|
19
19
|
plot_oneway,
|
|
20
20
|
)
|
|
21
21
|
from ins_pricing.modelling.plotting.common import finalize_figure, plt
|
|
22
|
-
from ins_pricing.production.
|
|
22
|
+
from ins_pricing.production.inference import load_predictor_from_config
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
def _parse_csv_list(value: str) -> List[str]:
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from .approval import ApprovalAction, ApprovalRequest, ApprovalStore
|
|
4
|
-
from .audit import AuditEvent, AuditLogger
|
|
5
|
-
from .registry import ModelArtifact, ModelRegistry, ModelVersion
|
|
6
|
-
from .release import DeploymentState, ModelRef, ReleaseManager
|
|
7
|
-
|
|
8
|
-
__all__ = [
|
|
9
|
-
"ApprovalAction",
|
|
10
|
-
"ApprovalRequest",
|
|
11
|
-
"ApprovalStore",
|
|
12
|
-
"AuditEvent",
|
|
13
|
-
"AuditLogger",
|
|
14
|
-
"ModelArtifact",
|
|
15
|
-
"ModelRegistry",
|
|
16
|
-
"ModelVersion",
|
|
17
|
-
"DeploymentState",
|
|
18
|
-
"ModelRef",
|
|
19
|
-
"ReleaseManager",
|
|
20
|
-
]
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from ins_pricing.governance.approval import ApprovalAction, ApprovalRequest, ApprovalStore
|
|
4
|
+
from ins_pricing.governance.audit import AuditEvent, AuditLogger
|
|
5
|
+
from ins_pricing.governance.registry import ModelArtifact, ModelRegistry, ModelVersion
|
|
6
|
+
from ins_pricing.governance.release import DeploymentState, ModelRef, ReleaseManager
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
"ApprovalAction",
|
|
10
|
+
"ApprovalRequest",
|
|
11
|
+
"ApprovalStore",
|
|
12
|
+
"AuditEvent",
|
|
13
|
+
"AuditLogger",
|
|
14
|
+
"ModelArtifact",
|
|
15
|
+
"ModelRegistry",
|
|
16
|
+
"ModelVersion",
|
|
17
|
+
"DeploymentState",
|
|
18
|
+
"ModelRef",
|
|
19
|
+
"ReleaseManager",
|
|
20
|
+
]
|
|
@@ -1,159 +1,159 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import json
|
|
4
|
-
from dataclasses import asdict, dataclass, field
|
|
5
|
-
from datetime import datetime
|
|
6
|
-
from pathlib import Path
|
|
7
|
-
from typing import List, Optional
|
|
8
|
-
|
|
9
|
-
from .audit import AuditLogger
|
|
10
|
-
from .registry import ModelRegistry
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
@dataclass
|
|
14
|
-
class ModelRef:
|
|
15
|
-
name: str
|
|
16
|
-
version: str
|
|
17
|
-
activated_at: str
|
|
18
|
-
actor: Optional[str] = None
|
|
19
|
-
note: Optional[str] = None
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
@dataclass
|
|
23
|
-
class DeploymentState:
|
|
24
|
-
env: str
|
|
25
|
-
active: Optional[ModelRef] = None
|
|
26
|
-
history: List[ModelRef] = field(default_factory=list)
|
|
27
|
-
updated_at: Optional[str] = None
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
class ReleaseManager:
|
|
31
|
-
"""Environment release manager with rollback support."""
|
|
32
|
-
|
|
33
|
-
def __init__(
|
|
34
|
-
self,
|
|
35
|
-
state_dir: str | Path,
|
|
36
|
-
*,
|
|
37
|
-
registry: Optional[ModelRegistry] = None,
|
|
38
|
-
audit_logger: Optional[AuditLogger] = None,
|
|
39
|
-
):
|
|
40
|
-
self.state_dir = Path(state_dir)
|
|
41
|
-
self.state_dir.mkdir(parents=True, exist_ok=True)
|
|
42
|
-
self.registry = registry
|
|
43
|
-
self.audit_logger = audit_logger
|
|
44
|
-
|
|
45
|
-
def _state_path(self, env: str) -> Path:
|
|
46
|
-
return self.state_dir / f"{env}.json"
|
|
47
|
-
|
|
48
|
-
def _load(self, env: str) -> DeploymentState:
|
|
49
|
-
path = self._state_path(env)
|
|
50
|
-
if not path.exists():
|
|
51
|
-
return DeploymentState(env=env)
|
|
52
|
-
with path.open("r", encoding="utf-8") as fh:
|
|
53
|
-
payload = json.load(fh)
|
|
54
|
-
active = payload.get("active")
|
|
55
|
-
history = payload.get("history", [])
|
|
56
|
-
return DeploymentState(
|
|
57
|
-
env=payload.get("env", env),
|
|
58
|
-
active=ModelRef(**active) if active else None,
|
|
59
|
-
history=[ModelRef(**item) for item in history],
|
|
60
|
-
updated_at=payload.get("updated_at"),
|
|
61
|
-
)
|
|
62
|
-
|
|
63
|
-
def _save(self, state: DeploymentState) -> None:
|
|
64
|
-
payload = {
|
|
65
|
-
"env": state.env,
|
|
66
|
-
"active": asdict(state.active) if state.active else None,
|
|
67
|
-
"history": [asdict(item) for item in state.history],
|
|
68
|
-
"updated_at": state.updated_at,
|
|
69
|
-
}
|
|
70
|
-
path = self._state_path(state.env)
|
|
71
|
-
with path.open("w", encoding="utf-8") as fh:
|
|
72
|
-
json.dump(payload, fh, indent=2, ensure_ascii=True)
|
|
73
|
-
|
|
74
|
-
def get_active(self, env: str) -> Optional[ModelRef]:
|
|
75
|
-
state = self._load(env)
|
|
76
|
-
return state.active
|
|
77
|
-
|
|
78
|
-
def list_history(self, env: str) -> List[ModelRef]:
|
|
79
|
-
return self._load(env).history
|
|
80
|
-
|
|
81
|
-
def deploy(
|
|
82
|
-
self,
|
|
83
|
-
env: str,
|
|
84
|
-
name: str,
|
|
85
|
-
version: str,
|
|
86
|
-
*,
|
|
87
|
-
actor: Optional[str] = None,
|
|
88
|
-
note: Optional[str] = None,
|
|
89
|
-
update_registry_status: bool = True,
|
|
90
|
-
registry_status: str = "production",
|
|
91
|
-
) -> DeploymentState:
|
|
92
|
-
state = self._load(env)
|
|
93
|
-
if state.active and state.active.name == name and state.active.version == version:
|
|
94
|
-
return state
|
|
95
|
-
|
|
96
|
-
if state.active is not None:
|
|
97
|
-
state.history.append(state.active)
|
|
98
|
-
|
|
99
|
-
now = datetime.utcnow().isoformat()
|
|
100
|
-
state.active = ModelRef(
|
|
101
|
-
name=name,
|
|
102
|
-
version=version,
|
|
103
|
-
activated_at=now,
|
|
104
|
-
actor=actor,
|
|
105
|
-
note=note,
|
|
106
|
-
)
|
|
107
|
-
state.updated_at = now
|
|
108
|
-
self._save(state)
|
|
109
|
-
|
|
110
|
-
if self.registry and update_registry_status:
|
|
111
|
-
self.registry.promote(name, version, new_status=registry_status)
|
|
112
|
-
|
|
113
|
-
if self.audit_logger:
|
|
114
|
-
self.audit_logger.log(
|
|
115
|
-
"deploy",
|
|
116
|
-
actor or "unknown",
|
|
117
|
-
metadata={"env": env, "name": name, "version": version},
|
|
118
|
-
note=note,
|
|
119
|
-
)
|
|
120
|
-
|
|
121
|
-
return state
|
|
122
|
-
|
|
123
|
-
def rollback(
|
|
124
|
-
self,
|
|
125
|
-
env: str,
|
|
126
|
-
*,
|
|
127
|
-
actor: Optional[str] = None,
|
|
128
|
-
note: Optional[str] = None,
|
|
129
|
-
update_registry_status: bool = False,
|
|
130
|
-
registry_status: str = "production",
|
|
131
|
-
) -> DeploymentState:
|
|
132
|
-
state = self._load(env)
|
|
133
|
-
if not state.history:
|
|
134
|
-
raise ValueError("No history available to rollback.")
|
|
135
|
-
|
|
136
|
-
previous = state.history.pop()
|
|
137
|
-
now = datetime.utcnow().isoformat()
|
|
138
|
-
state.active = ModelRef(
|
|
139
|
-
name=previous.name,
|
|
140
|
-
version=previous.version,
|
|
141
|
-
activated_at=now,
|
|
142
|
-
actor=actor or previous.actor,
|
|
143
|
-
note=note or previous.note,
|
|
144
|
-
)
|
|
145
|
-
state.updated_at = now
|
|
146
|
-
self._save(state)
|
|
147
|
-
|
|
148
|
-
if self.registry and update_registry_status:
|
|
149
|
-
self.registry.promote(previous.name, previous.version, new_status=registry_status)
|
|
150
|
-
|
|
151
|
-
if self.audit_logger:
|
|
152
|
-
self.audit_logger.log(
|
|
153
|
-
"rollback",
|
|
154
|
-
actor or "unknown",
|
|
155
|
-
metadata={"env": env, "name": previous.name, "version": previous.version},
|
|
156
|
-
note=note,
|
|
157
|
-
)
|
|
158
|
-
|
|
159
|
-
return state
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from dataclasses import asdict, dataclass, field
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import List, Optional
|
|
8
|
+
|
|
9
|
+
from ins_pricing.governance.audit import AuditLogger
|
|
10
|
+
from ins_pricing.governance.registry import ModelRegistry
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass
|
|
14
|
+
class ModelRef:
|
|
15
|
+
name: str
|
|
16
|
+
version: str
|
|
17
|
+
activated_at: str
|
|
18
|
+
actor: Optional[str] = None
|
|
19
|
+
note: Optional[str] = None
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass
|
|
23
|
+
class DeploymentState:
|
|
24
|
+
env: str
|
|
25
|
+
active: Optional[ModelRef] = None
|
|
26
|
+
history: List[ModelRef] = field(default_factory=list)
|
|
27
|
+
updated_at: Optional[str] = None
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ReleaseManager:
|
|
31
|
+
"""Environment release manager with rollback support."""
|
|
32
|
+
|
|
33
|
+
def __init__(
|
|
34
|
+
self,
|
|
35
|
+
state_dir: str | Path,
|
|
36
|
+
*,
|
|
37
|
+
registry: Optional[ModelRegistry] = None,
|
|
38
|
+
audit_logger: Optional[AuditLogger] = None,
|
|
39
|
+
):
|
|
40
|
+
self.state_dir = Path(state_dir)
|
|
41
|
+
self.state_dir.mkdir(parents=True, exist_ok=True)
|
|
42
|
+
self.registry = registry
|
|
43
|
+
self.audit_logger = audit_logger
|
|
44
|
+
|
|
45
|
+
def _state_path(self, env: str) -> Path:
|
|
46
|
+
return self.state_dir / f"{env}.json"
|
|
47
|
+
|
|
48
|
+
def _load(self, env: str) -> DeploymentState:
|
|
49
|
+
path = self._state_path(env)
|
|
50
|
+
if not path.exists():
|
|
51
|
+
return DeploymentState(env=env)
|
|
52
|
+
with path.open("r", encoding="utf-8") as fh:
|
|
53
|
+
payload = json.load(fh)
|
|
54
|
+
active = payload.get("active")
|
|
55
|
+
history = payload.get("history", [])
|
|
56
|
+
return DeploymentState(
|
|
57
|
+
env=payload.get("env", env),
|
|
58
|
+
active=ModelRef(**active) if active else None,
|
|
59
|
+
history=[ModelRef(**item) for item in history],
|
|
60
|
+
updated_at=payload.get("updated_at"),
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
def _save(self, state: DeploymentState) -> None:
|
|
64
|
+
payload = {
|
|
65
|
+
"env": state.env,
|
|
66
|
+
"active": asdict(state.active) if state.active else None,
|
|
67
|
+
"history": [asdict(item) for item in state.history],
|
|
68
|
+
"updated_at": state.updated_at,
|
|
69
|
+
}
|
|
70
|
+
path = self._state_path(state.env)
|
|
71
|
+
with path.open("w", encoding="utf-8") as fh:
|
|
72
|
+
json.dump(payload, fh, indent=2, ensure_ascii=True)
|
|
73
|
+
|
|
74
|
+
def get_active(self, env: str) -> Optional[ModelRef]:
|
|
75
|
+
state = self._load(env)
|
|
76
|
+
return state.active
|
|
77
|
+
|
|
78
|
+
def list_history(self, env: str) -> List[ModelRef]:
|
|
79
|
+
return self._load(env).history
|
|
80
|
+
|
|
81
|
+
def deploy(
|
|
82
|
+
self,
|
|
83
|
+
env: str,
|
|
84
|
+
name: str,
|
|
85
|
+
version: str,
|
|
86
|
+
*,
|
|
87
|
+
actor: Optional[str] = None,
|
|
88
|
+
note: Optional[str] = None,
|
|
89
|
+
update_registry_status: bool = True,
|
|
90
|
+
registry_status: str = "production",
|
|
91
|
+
) -> DeploymentState:
|
|
92
|
+
state = self._load(env)
|
|
93
|
+
if state.active and state.active.name == name and state.active.version == version:
|
|
94
|
+
return state
|
|
95
|
+
|
|
96
|
+
if state.active is not None:
|
|
97
|
+
state.history.append(state.active)
|
|
98
|
+
|
|
99
|
+
now = datetime.utcnow().isoformat()
|
|
100
|
+
state.active = ModelRef(
|
|
101
|
+
name=name,
|
|
102
|
+
version=version,
|
|
103
|
+
activated_at=now,
|
|
104
|
+
actor=actor,
|
|
105
|
+
note=note,
|
|
106
|
+
)
|
|
107
|
+
state.updated_at = now
|
|
108
|
+
self._save(state)
|
|
109
|
+
|
|
110
|
+
if self.registry and update_registry_status:
|
|
111
|
+
self.registry.promote(name, version, new_status=registry_status)
|
|
112
|
+
|
|
113
|
+
if self.audit_logger:
|
|
114
|
+
self.audit_logger.log(
|
|
115
|
+
"deploy",
|
|
116
|
+
actor or "unknown",
|
|
117
|
+
metadata={"env": env, "name": name, "version": version},
|
|
118
|
+
note=note,
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
return state
|
|
122
|
+
|
|
123
|
+
def rollback(
|
|
124
|
+
self,
|
|
125
|
+
env: str,
|
|
126
|
+
*,
|
|
127
|
+
actor: Optional[str] = None,
|
|
128
|
+
note: Optional[str] = None,
|
|
129
|
+
update_registry_status: bool = False,
|
|
130
|
+
registry_status: str = "production",
|
|
131
|
+
) -> DeploymentState:
|
|
132
|
+
state = self._load(env)
|
|
133
|
+
if not state.history:
|
|
134
|
+
raise ValueError("No history available to rollback.")
|
|
135
|
+
|
|
136
|
+
previous = state.history.pop()
|
|
137
|
+
now = datetime.utcnow().isoformat()
|
|
138
|
+
state.active = ModelRef(
|
|
139
|
+
name=previous.name,
|
|
140
|
+
version=previous.version,
|
|
141
|
+
activated_at=now,
|
|
142
|
+
actor=actor or previous.actor,
|
|
143
|
+
note=note or previous.note,
|
|
144
|
+
)
|
|
145
|
+
state.updated_at = now
|
|
146
|
+
self._save(state)
|
|
147
|
+
|
|
148
|
+
if self.registry and update_registry_status:
|
|
149
|
+
self.registry.promote(previous.name, previous.version, new_status=registry_status)
|
|
150
|
+
|
|
151
|
+
if self.audit_logger:
|
|
152
|
+
self.audit_logger.log(
|
|
153
|
+
"rollback",
|
|
154
|
+
actor or "unknown",
|
|
155
|
+
metadata={"env": env, "name": previous.name, "version": previous.version},
|
|
156
|
+
note=note,
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
return state
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Modelling
|
|
2
|
+
|
|
3
|
+
This directory contains reusable training tooling and frameworks centered on BayesOpt.
|
|
4
|
+
|
|
5
|
+
## Key locations
|
|
6
|
+
|
|
7
|
+
- `core/bayesopt/` - core training/tuning package
|
|
8
|
+
- `explain/` - explainability helpers
|
|
9
|
+
- `plotting/` - plotting utilities
|
|
10
|
+
- `ins_pricing/cli/` - CLI entry points
|
|
11
|
+
- `examples/` - example configs and notebooks (repo only)
|
|
12
|
+
|
|
13
|
+
## Common usage
|
|
14
|
+
|
|
15
|
+
- CLI training: `python ins_pricing/cli/BayesOpt_entry.py --config-json config_template.json`
|
|
16
|
+
- Notebook API: `from ins_pricing.modelling import BayesOptModel`
|
|
17
|
+
|
|
18
|
+
## Explainability
|
|
19
|
+
|
|
20
|
+
- CLI: `python ins_pricing/cli/Explain_entry.py --config-json config_explain_template.json`
|
|
21
|
+
- Notebook: `examples/04 Explain_Run.ipynb`
|
|
22
|
+
|
|
23
|
+
## Loss functions
|
|
24
|
+
|
|
25
|
+
Configure the regression/classification loss with `loss_name` in the BayesOpt config.
|
|
26
|
+
|
|
27
|
+
Supported `loss_name` values:
|
|
28
|
+
- `auto` (default): legacy behavior based on model name
|
|
29
|
+
- `tweedie`: Tweedie deviance
|
|
30
|
+
- `poisson`: Poisson deviance
|
|
31
|
+
- `gamma`: Gamma deviance
|
|
32
|
+
- `mse`: mean squared error
|
|
33
|
+
- `mae`: mean absolute error
|
|
34
|
+
|
|
35
|
+
Mapping summary:
|
|
36
|
+
- Tweedie deviance -> `tweedie`
|
|
37
|
+
- Poisson deviance -> `poisson`
|
|
38
|
+
- Gamma deviance -> `gamma`
|
|
39
|
+
- Mean squared error -> `mse`
|
|
40
|
+
- Mean absolute error -> `mae`
|
|
41
|
+
- Classification log loss -> `logloss` (classification only)
|
|
42
|
+
- Classification BCE -> `bce` (classification only)
|
|
43
|
+
|
|
44
|
+
Classification tasks:
|
|
45
|
+
- `loss_name` can be `auto`, `logloss`, or `bce`.
|
|
46
|
+
- Training uses `BCEWithLogits` for torch models; evaluation uses log loss.
|
|
47
|
+
|
|
48
|
+
Where to set `loss_name`:
|
|
49
|
+
|
|
50
|
+
```json
|
|
51
|
+
{
|
|
52
|
+
"task_type": "regression",
|
|
53
|
+
"loss_name": "mse"
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Behavior notes:
|
|
58
|
+
- When `loss_name` is `mse` or `mae`, tuning does not sample Tweedie power.
|
|
59
|
+
- When `loss_name` is `poisson` or `gamma`, power is fixed (1.0 / 2.0).
|
|
60
|
+
- When `loss_name` is `tweedie`, power is sampled as usual.
|
|
61
|
+
- XGBoost objective is selected from the loss name.
|
|
62
|
+
|
|
63
|
+
## Notes
|
|
64
|
+
|
|
65
|
+
- Models load from `output_dir/model` by default (override with `explain.model_dir`).
|
|
66
|
+
- Training outputs are written to `plot/`, `Results/`, and `model/` under `output_dir`.
|
|
67
|
+
- Keep large data and secrets outside the repo; use environment variables or `.env` files.
|