Add a generic named-feature learner for the zone models
Electrical heat, ventilation, wind and inter-zone exchange each need their own coefficient next to the existing loss/heat/bias, and each must stay physically bounded and not claim precision it does not have. learning.py adds FeatureLearner: exponentially weighted RLS over named features with per-feature bounds, priors at 0 for new effects, the same covariance windup bound as the base model, and a linked bound that keeps the directional wind term from cancelling more than the isotropic one. Each prior is sized as "worth N typical samples" (20 for new effects, 200 for zone coupling, which is weakly identifiable). Confidence is the share of a coefficient's information that comes from data; the standard error uses a bias-corrected running noise estimate. Saved models are matched by feature name, so adding a heat source, window or neighbour retrains only that coefficient and keeps the covariance of the rest. The existing 3-parameter learner now uses the same RLS step, covariance bound and positive-definiteness check (behavior unchanged; all existing tests pass). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e59c08f586
commit
220ac570d2
4 files changed
+420
-45
No files matched your search
@@ -1,14 +1,15 @@
|
||||
"""Offline tests: run python -m unittest discover -s tests -v."""
|
||||
import importlib.util
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
path = Path(__file__).resolve().parents[1] / 'custom_components' / 'heating_mpc' / 'physics.py'
|
||||
spec = importlib.util.spec_from_file_location('heating_mpc_physics', path)
|
||||
m = importlib.util.module_from_spec(spec)
|
||||
import sys
|
||||
sys.modules[spec.name] = m
|
||||
spec.loader.exec_module(m)
|
||||
import types
|
||||
|
||||
COMPONENTS = Path(__file__).resolve().parents[1] / 'custom_components' / 'heating_mpc'
|
||||
# Fake only the package container, to avoid importing Home Assistant from __init__.
|
||||
sys.modules.setdefault('heating_mpc', types.ModuleType('heating_mpc'))
|
||||
sys.modules['heating_mpc'].__path__ = [str(COMPONENTS)]
|
||||
from heating_mpc import physics as m # noqa: E402
|
||||
|
||||
|
||||
class ModelTests(unittest.TestCase):
|
||||
|
||||
Reference in new issue
Block a user