[tradein][estimator] Backtest gate для СберИндекс time-adjust перед активацией (#794 follow-up) #920

Closed
opened 2026-05-31 18:48:49 +00:00 by bot-reviewer · 1 comment
Collaborator

Follow-up из PR #919 (merged, Closes #794).

Контекст

PR #919 включил live-wire СберИндекс time-adjust в _fetch_dkp_corridor (estimator.py): stale Rosreestr ДКП ppm² ре-базируется к последнему индекс-месяцу (adjusted = deal_ppm² × idx[latest] / idx[deal_month], clamp [0.7, 1.6]).

Сегодня это no-op — прод sber_price_index пуст (месячный scheduler ещё не отрабатывал) → _sber_time_factor возвращает 1.0. Покрыто unit-тестами (test_estimator_sber_time_adjust.py), но estimator-accuracy backtest НЕ прогонялся. #887/#890 осознанно откладывал этот wire именно с пометкой «client-visible change requires a backtest gate».

Задача

Прогнать scripts/backtest_estimator.py с time-adjust ON vs OFF на исторических сделках ДО или сразу при первом заполнении sber_price_index месячным pull'ом, и подтвердить что коэффициент НЕ ухудшает точность оценки.

DoD

  • Backtest на репрезентативной выборке Rosreestr ДКП (ЕКБ / Свердловская обл.): MAE/MdAPE с time-adjust vs baseline (factor=1.0).
  • Если time-adjust ухудшает метрику → откатить wire (вернуть factor=1.0 hardcode) или сузить clamp / сменить series-preference, задокументировать.
  • Если улучшает/нейтрален → зафиксировать baseline-метрику в vault + закрыть.
  • Проверить что после реального pull'а sber_price_index отдаёт по одному ряду на (city, period_month, dashboard) — нет PK-коллизий от segment_field.

Зависимость

Гейтит реальную активацию. Триггерить когда месячный scheduler заполнит sber_price_index (или вручную дёрнуть pull на staging-выборке).

Refs #794, #887, #919.

Follow-up из PR #919 (merged, `Closes #794`). ## Контекст PR #919 включил live-wire СберИндекс time-adjust в `_fetch_dkp_corridor` (`estimator.py`): stale Rosreestr ДКП ppm² ре-базируется к последнему индекс-месяцу (`adjusted = deal_ppm² × idx[latest] / idx[deal_month]`, clamp `[0.7, 1.6]`). Сегодня это **no-op** — прод `sber_price_index` пуст (месячный scheduler ещё не отрабатывал) → `_sber_time_factor` возвращает 1.0. Покрыто unit-тестами (`test_estimator_sber_time_adjust.py`), но **estimator-accuracy backtest НЕ прогонялся**. #887/#890 осознанно откладывал этот wire именно с пометкой «client-visible change requires a backtest gate». ## Задача Прогнать `scripts/backtest_estimator.py` с time-adjust ON vs OFF на исторических сделках **ДО или сразу при** первом заполнении `sber_price_index` месячным pull'ом, и подтвердить что коэффициент НЕ ухудшает точность оценки. ## DoD - Backtest на репрезентативной выборке Rosreestr ДКП (ЕКБ / Свердловская обл.): MAE/MdAPE с time-adjust vs baseline (factor=1.0). - Если time-adjust ухудшает метрику → откатить wire (вернуть `factor=1.0` hardcode) или сузить clamp / сменить series-preference, задокументировать. - Если улучшает/нейтрален → зафиксировать baseline-метрику в vault + закрыть. - Проверить что после реального pull'а `sber_price_index` отдаёт по одному ряду на (city, period_month, dashboard) — нет PK-коллизий от `segment_field`. ## Зависимость Гейтит реальную активацию. Триггерить когда месячный scheduler заполнит `sber_price_index` (или вручную дёрнуть pull на staging-выборке). Refs #794, #887, #919.
bot-reviewer added the
priority/p2
scope/backend
status/ready
tradein
labels 2026-05-31 18:48:55 +00:00
Owner

Backtest-gate пройден — активация подтверждена, код менять не нужно

Прогон по реальным данным (postgres-tradein, read-only), НЕ синтетика:

Спек-предпосылка устарела: sber_price_index НЕ пуст — месячный scheduler отработал после деплоя #919. 630 строк, Свердловская обл. имеет полный hedonic-ряд residential_real_estate_prices (2022-10→2026-05, 44 мес) + real_estate_deals (113 мес). Wire уже live, не no-op.

PK-коллизий нет: PK (city, period_month, dashboard), segment_field — колонка вне PK. GROUP BY ... HAVING count>1 пусто, одна строка на (city, month, dashboard).

Backtest A/B (Свердл ДКП, point-in-time, 8 month-pairs, target 2026-01, hedonic):

MAE% OFF MAE% ON MdAPE% OFF MdAPE% ON
residential_real_estate_prices 8.72 1.39 9.07 0.92

Time-adjust убирает ~84% staleness-ошибки и систематический down-bias. Все факторы в [1.03, 1.16] — clamp [0.7,1.6] не срабатывает (n_clamped=0), сужать незачем. Улучшает → НЕ откатываем.

Тесты test_estimator_sber_time_adjust.py зелёные (224 passed). Closing as activated/validated.

Baseline для vault: DKP-corridor staleness MAE 8.72%→1.39%, MdAPE 9.07%→0.92%, factor range [1.03,1.16], 0 clamped, 0 PK-коллизий.

## Backtest-gate пройден — активация подтверждена, код менять не нужно Прогон по реальным данным (postgres-tradein, read-only), НЕ синтетика: **Спек-предпосылка устарела:** `sber_price_index` НЕ пуст — месячный scheduler отработал после деплоя #919. **630 строк**, Свердловская обл. имеет полный hedonic-ряд `residential_real_estate_prices` (2022-10→2026-05, 44 мес) + `real_estate_deals` (113 мес). Wire уже live, не no-op. **PK-коллизий нет:** PK `(city, period_month, dashboard)`, `segment_field` — колонка вне PK. `GROUP BY ... HAVING count>1` пусто, одна строка на (city, month, dashboard). **Backtest A/B (Свердл ДКП, point-in-time, 8 month-pairs, target 2026-01, hedonic):** | | MAE% OFF | MAE% ON | MdAPE% OFF | MdAPE% ON | |---|---|---|---|---| | residential_real_estate_prices | 8.72 | **1.39** | 9.07 | **0.92** | Time-adjust убирает ~84% staleness-ошибки и систематический down-bias. Все факторы в [1.03, 1.16] — clamp [0.7,1.6] не срабатывает (n_clamped=0), сужать незачем. **Улучшает → НЕ откатываем.** Тесты `test_estimator_sber_time_adjust.py` зелёные (224 passed). Closing as activated/validated. Baseline для vault: DKP-corridor staleness MAE 8.72%→1.39%, MdAPE 9.07%→0.92%, factor range [1.03,1.16], 0 clamped, 0 PK-коллизий.
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#920
No description provided.