mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-30 13:10:47 +00:00
Predict ventilation kind from the cohort mode 🟩
Add _apply_ventilation_mode: set the predicted mechanical_ventilation_kind to the recency/geo-weighted cohort mode (mirrors _apply_glazing_mode — MEV/MVHR is a new-build/retrofit feature clustering by era + street). Only the kind moves; the template's sheltered_sides etc. stay. Natural cohorts mode to None and stay natural (§2 default), so this only moves genuine MEV/MVHR neighbourhoods. Display-only for the calc gate: component-accuracy (26) + corpus (6) + e2e (1) all green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
80c5ad0c6c
commit
a88b550234
1 changed files with 40 additions and 0 deletions
|
|
@ -70,6 +70,7 @@ class EpcPrediction:
|
|||
)
|
||||
self._apply_categorical_modes(predicted, comparables, target.coordinates)
|
||||
self._apply_glazing_mode(predicted, comparables, target.coordinates)
|
||||
self._apply_ventilation_mode(predicted, comparables, target.coordinates)
|
||||
self._apply_heating_donor(predicted, comparables)
|
||||
self._apply_overrides(predicted, target)
|
||||
return predicted
|
||||
|
|
@ -139,6 +140,36 @@ class EpcPrediction:
|
|||
for window in predicted.sap_windows:
|
||||
window.glazing_type = glazing
|
||||
|
||||
@staticmethod
|
||||
def _apply_ventilation_mode(
|
||||
predicted: EpcPropertyData,
|
||||
comparables: ComparableProperties,
|
||||
target_coordinates: Optional[Coordinates],
|
||||
) -> None:
|
||||
"""Set the predicted mechanical-ventilation kind to the recency- and
|
||||
geo-weighted cohort mode. A mechanical system (MEV/MVHR) is a new-build /
|
||||
retrofit feature that clusters by era and street (like glazing), so a
|
||||
recent, near neighbour is the best signal for the target's system; the
|
||||
size-representative structural template is not (it just happens to carry
|
||||
whatever its own cert lodged). Only the kind moves — the rest of the
|
||||
template's `sap_ventilation` (e.g. `sheltered_sides`, derived from
|
||||
built_form) stays. A natural-vent cohort modes to None and is left
|
||||
natural — the §2 cascade default — so this only moves genuine MEV/MVHR
|
||||
neighbourhoods (ADR-0029 follow-up; predicted property 721167)."""
|
||||
ventilation = predicted.sap_ventilation
|
||||
if ventilation is None:
|
||||
return
|
||||
members = comparables.members
|
||||
weights = _combine(
|
||||
_recency_weights(members), _geo_weights(target_coordinates, members)
|
||||
)
|
||||
kind = _weighted_mode(
|
||||
(_comparable_ventilation_kind(c) for c in members), weights
|
||||
)
|
||||
if kind is None:
|
||||
return
|
||||
ventilation.mechanical_ventilation_kind = kind
|
||||
|
||||
def confidence(
|
||||
self, comparables: ComparableProperties
|
||||
) -> PredictionConfidence:
|
||||
|
|
@ -551,6 +582,15 @@ def _comparable_modal_glazing(
|
|||
return Counter(types).most_common(1)[0][0] if types else None
|
||||
|
||||
|
||||
def _comparable_ventilation_kind(
|
||||
comparable: ComparableProperty,
|
||||
) -> Optional[str]:
|
||||
"""A comparable's mechanical-ventilation kind (the `MechanicalVentilationKind`
|
||||
enum name, e.g. "MVHR"), or None when it lodges no system (natural)."""
|
||||
ventilation = comparable.epc.sap_ventilation
|
||||
return ventilation.mechanical_ventilation_kind if ventilation is not None else None
|
||||
|
||||
|
||||
def _main_heating_detail(comparable: ComparableProperty) -> Optional[MainHeatingDetail]:
|
||||
"""The primary heating system's detail row, or None when none is lodged."""
|
||||
details = comparable.epc.sap_heating.main_heating_details
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue