mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-12 13:29:04 +00:00
Remove the superseded role-1 impacts scorer; signals carry the objective currency 🟪
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
e329c50fa3
commit
c70f6730a3
3 changed files with 9 additions and 40 deletions
|
|
@ -33,8 +33,9 @@ from domain.modelling.simulation import EpcSimulation
|
|||
@dataclass(frozen=True)
|
||||
class ScoredOption:
|
||||
"""A candidate Measure Option paired with its role-1 (independent-vs-
|
||||
baseline) SAP gain — the optimiser's input signal. Cost is read from the
|
||||
Option; the gain is supplied by scoring."""
|
||||
baseline) gain in the goal objective's currency — SAP points by default,
|
||||
kg CO2 / £ saved for the goal-aligned Scenarios (ADR-0062). Cost is read
|
||||
from the Option; the gain is supplied by scoring."""
|
||||
|
||||
option: MeasureOption
|
||||
sap_gain: float
|
||||
|
|
|
|||
|
|
@ -83,38 +83,6 @@ def marginal_impacts(
|
|||
return marginals_from_scores(cascade_scores(scorer, baseline, overlays))
|
||||
|
||||
|
||||
def independent_option_impacts(
|
||||
scorer: PackageScorer,
|
||||
baseline: EpcPropertyData,
|
||||
options: Sequence[MeasureOption],
|
||||
) -> list[MeasureImpact]:
|
||||
"""Score each Option's overlay independently against the baseline (role 1 —
|
||||
the optimiser's approximate input signal). Each *distinct* Simulation Overlay
|
||||
is scored once (Options sharing an overlay reuse the result), so the baseline
|
||||
is scored once plus one score per distinct overlay. Results follow the input
|
||||
order. These figures are an approximate signal — never surface them as a
|
||||
measure's true impact."""
|
||||
base: Score = scorer.score(baseline, [])
|
||||
scored: list[tuple[EpcSimulation, MeasureImpact]] = []
|
||||
impacts: list[MeasureImpact] = []
|
||||
for option in options:
|
||||
cached = next(
|
||||
(impact for overlay, impact in scored if overlay == option.overlay), None
|
||||
)
|
||||
if cached is None:
|
||||
current: Score = scorer.score(baseline, [option.overlay])
|
||||
cached = MeasureImpact(
|
||||
sap_points=current.sap_continuous - base.sap_continuous,
|
||||
co2_savings_kg_per_yr=base.co2_kg_per_yr - current.co2_kg_per_yr,
|
||||
energy_savings_kwh_per_yr=(
|
||||
base.primary_energy_kwh_per_yr - current.primary_energy_kwh_per_yr
|
||||
),
|
||||
)
|
||||
scored.append((option.overlay, cached))
|
||||
impacts.append(cached)
|
||||
return impacts
|
||||
|
||||
|
||||
def independent_option_signals(
|
||||
scorer: PackageScorer,
|
||||
baseline: EpcPropertyData,
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ from domain.modelling.recommendation import MeasureOption
|
|||
from domain.modelling.scoring.scoring import (
|
||||
MeasureImpact,
|
||||
cascade_scores,
|
||||
independent_option_impacts,
|
||||
independent_option_signals,
|
||||
marginal_impacts,
|
||||
marginals_from_scores,
|
||||
)
|
||||
|
|
@ -64,7 +64,7 @@ def _option(overlay: EpcSimulation) -> MeasureOption:
|
|||
)
|
||||
|
||||
|
||||
def test_independent_option_impacts_score_each_distinct_overlay_once() -> None:
|
||||
def test_independent_option_signals_score_each_distinct_overlay_once() -> None:
|
||||
# Arrange
|
||||
baseline: EpcPropertyData = build_epc()
|
||||
scorer = _CountingScorer()
|
||||
|
|
@ -86,15 +86,15 @@ def test_independent_option_impacts_score_each_distinct_overlay_once() -> None:
|
|||
options = [_option(overlay_a), _option(overlay_a_dup), _option(overlay_b)]
|
||||
|
||||
# Act
|
||||
impacts: list[MeasureImpact] = independent_option_impacts(
|
||||
scorer, baseline, options
|
||||
signals: list[float] = independent_option_signals(
|
||||
scorer, baseline, options, lambda score: score.sap_continuous
|
||||
)
|
||||
|
||||
# Assert
|
||||
# baseline scored once + one score per DISTINCT overlay (a, b) = 3, not 4
|
||||
assert scorer.calls == 3
|
||||
assert impacts[0].sap_points == impacts[1].sap_points == 2.0
|
||||
assert impacts[2].sap_points == 3.0
|
||||
assert signals[0] == signals[1] == 2.0
|
||||
assert signals[2] == 3.0
|
||||
|
||||
|
||||
def test_single_overlay_marginal_is_its_improvement_over_baseline() -> None:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue