docs(mera/estimate): пометить сегментные множители как откалиброванные на артефакте
All checks were successful
CI Trade-In / changes (pull_request) Successful in 9s
CI / changes (pull_request) Successful in 10s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 4m56s

Комментарий к estimate_segment_multipliers утверждал, что движок систематически
занижает верхние сегменты (бизнес -16.3%, элит -25.7%), и множители 1.08/1.06
это чинят. Посылка неверна: _segment_metrics в бэктесте группирует ошибки по
SOLD руб/м2 — по той самой величине, которую движок предсказывает. Группировка
по исходу даёт регрессию к среднему, и монотонный спуск «чем дороже сегмент,
тем сильнее занижаем» появляется у любого предиктора.

Контрольный опыт на 13074 сделках ЕКБ: предиктор без сегментного перекоса по
построению даёт в тех же корзинах бизнес -17.04%, элит -30.06% — больше, чем
наблюдавшийся перекос движка (-9.74% и -18.45% на n=1191). Перекрёстная
проверка с бэндом по независимому прокси (цена собственного дома) градиента не
показывает вовсе.

Флаг выключен, поведение не меняется — правка только текстовая. Смысл: не дать
включить множители по прежнему обоснованию, подняв бизнес и элит на 6-8% без
причины. Историческая посылка сохранена, но помечена как ненадёжная.
This commit is contained in:
bot-backend 2026-08-29 22:49:46 +03:00
parent 5e9619d662
commit d5201c37f6

View file

@ -718,6 +718,32 @@ class Settings(BaseSettings):
estimate_quarter_from_coords_enabled: bool = False
# ── Сегментная поправка эстиматора по ценовому бэнду (#2255) ──────────────
#
# ⚠ НЕ ВКЛЮЧАТЬ БЕЗ ПЕРЕЗАМЕРА. Посылка, на которой откалиброваны множители
# ниже («движок занижает верхние сегменты»), 2026-08-29 признана АРТЕФАКТОМ
# измерения, а не свойством движка.
#
# Причина: `scripts/backtest_estimator.py::_segment_metrics` группирует ошибки
# ПО SOLD ₽/м² — по той самой величине, которую движок предсказывает. Группировка
# по исходу даёт регрессию к среднему: в дешёвых корзинах любой предиктор выглядит
# завышающим, в дорогих — занижающим, даже при нулевом перекосе.
#
# Контрольный опыт (13 074 сделки ЕКБ с 2025-06): предиктор БЕЗ сегментного
# перекоса по построению — медиана окружения 1 км ÷ общий уровень — даёт в тех же
# корзинах эконом +22.28%, бизнес 17.04%, элит 30.06%. Это БОЛЬШЕ наблюдавшегося
# перекоса движка (бизнес 9.74%, элит 18.45% на n=1191), т.е. движок «занижает»
# ровно настолько, насколько этого требует способ замера, и даже меньше.
#
# Перекрёстная проверка: те же сделки, но бэнд задан НЕЗАВИСИМЫМ прокси (медиана
# активных объявлений собственного дома, own_n>=3) — градиент исчезает, остаётся
# ровный уровень +20…+27% (это разрыв asking↔sold, его чинит asking_to_sold_ratio).
#
# Следствие: включение флага подняло бы бизнес/элит на 6-8% БЕЗ ОСНОВАНИЯ.
# Прежде чем трогать — перевести `_segment_metrics` на независимый бэнд и
# перемерить. Абзац «band-mismatch» ниже описывает симптом того же артефакта.
# Разбор: vault `segment-bias-is-regression-to-the-mean-artifact`.
#
# ИСТОРИЧЕСКАЯ ПОСЫЛКА (сохранена как есть, НЕ опирайся на неё):
# Эстиматор систематически занижает верхние сегменты (live-бэктест n=561,
# 2026-07-03): эконом +3.2%, комфорт 4.5%, бизнес 16.3% (n=76),
# элит 25.7% (n=16). Множитель применяется к median_price/median_ppm2 и
@ -740,6 +766,9 @@ class Settings(BaseSettings):
# бизнес bias 10.4→3.2, элит 30→24.6, эконом почти intact (MAPE 18.0).
# Дальнейшее сжатие bias без роста MAPE — только с confidence-гейтом
# (не применять множитель на low-confidence предсказаниях) → follow-up issue.
# NB (2026-08-29): «bias 10.4→3.2» выше меряет схлопывание АРТЕФАКТА, а не
# исправление ошибки — см. предупреждение в начале блока. Рост общего MAPE
# +1.87pp при этом настоящий: множитель двигает реальные цены.
# Пересчёт биасов — см. scripts/backtest_estimator.py --calibrate-segments.
estimate_segment_multipliers: dict[str, float] = {
"эконом": 1.00,