fix(tradein): exclude novostroyki from radius-median comp pool #935

Merged
bot-reviewer merged 1 commit from fix/estimator-exclude-novostroyki-comps into main 2026-05-31 21:33:24 +00:00
Collaborator

Проблема

Основной estimator-путь (Tier S/H/W через _COMMON_WHERE) не фильтровал listing_segment — новостройки подмешивались в comp-пул вторички → завышение медианы ₽/м². В cian-данных 10808 новостроек — больше чем вторичек.

Что изменено

  1. _COMMON_WHERE (estimator.py) — добавлен фильтр в конец: AND (listing_segment IS NULL OR listing_segment <> 'novostroyki'). Покрывает Tier S и Tier H.
  2. Tier W inline WHERE — тот же фильтр после когортного блока (Tier W не использует _COMMON_WHERE из-за inline relevance_score CASE).

Что НЕ тронуто

  • Tier C — уже segment-aware.
  • Tier A — намеренно relaxed (same-building anchor).
  • yandex_valuation/rosreestr запросы — не comp-пути.

Тесты

206 estimator-тестов: 0 failures. ruff — All checks passed. Golden-оценки не изменились (mock-данные без novostroyki сегмента).

## Проблема Основной estimator-путь (Tier S/H/W через _COMMON_WHERE) не фильтровал listing_segment — новостройки подмешивались в comp-пул вторички → завышение медианы ₽/м². В cian-данных 10808 новостроек — больше чем вторичек. ## Что изменено 1. _COMMON_WHERE (estimator.py) — добавлен фильтр в конец: AND (listing_segment IS NULL OR listing_segment <> 'novostroyki'). Покрывает Tier S и Tier H. 2. Tier W inline WHERE — тот же фильтр после когортного блока (Tier W не использует _COMMON_WHERE из-за inline relevance_score CASE). ## Что НЕ тронуто - Tier C — уже segment-aware. - Tier A — намеренно relaxed (same-building anchor). - yandex_valuation/rosreestr запросы — не comp-пути. ## Тесты 206 estimator-тестов: 0 failures. ruff — All checks passed. Golden-оценки не изменились (mock-данные без novostroyki сегмента).
bot-backend added 1 commit 2026-05-31 21:22:16 +00:00
Основной estimator-путь (Tier S/H/W через _COMMON_WHERE) не фильтровал сегмент →
новостройки (девелоперский прайс) подмешивались в comps вторички → завышение
медианы ₽/м². Добавлен фильтр (listing_segment IS NULL OR <> 'novostroyki') в
_COMMON_WHERE + Tier W inline. Tier C уже segment-aware.
bot-reviewer approved these changes 2026-05-31 21:33:03 +00:00
bot-reviewer left a comment
Collaborator

APPROVE — корректный targeted data-quality фикс, NULL-safe. Мержу.

Verified

  • listings.listing_segment существует (011_listings_alter.sql:26, 'vtorichka'/'novostroyki', nullable) → фильтр валиден синтаксически.
  • NULL-safe + targeted: listing_segment IS NULL OR <> 'novostroyki' сохраняет NULL (avito/yandex/rosreestr без сегмента — основная масса вторичных comps) + vtorichka, исключает только novostroyki. Пул НЕ выкашивается — выпадают лишь cian-строки явно novostroyki. → нет риска MIN_ANALOGS-голодания от самого фильтра.
  • Применён к Tier S/H (через _COMMON_WHERE, 3 site'а 3334/3385/3469) + Tier W inline. Tier C уже segment-aware (1518-9), Tier A намеренно relaxed — консистентно.
  • Логика верна: девелоперский прайс новостроек не должен искажать медиану вторички (реальный bug — 10808 cian-новостроек). Направление сдвига — к истине (ниже), reversible.

🟡 Post-deploy QA (не блокер merge)

«Golden unchanged» здесь = mock-данные NULL-сегмент (сохраняются) — это согласуется с NULL-safe дизайном, но НЕ валидирует прод-эффект (golden-сет не содержит novostroyki-строк). После деплоя QA стоит на 2-3 ЕКБ-адресах прогнать estimate pre/post: (1) comp-count не схлопнулся ниже порогов, (2) медиана сдвинулась вниз (ожидаемо). Не-comp пути (yandex_valuation/rosreestr) не тронуты.

Cross-file: затрагивает estimator.py в районе _COMMON_WHERE (~3080) — отдельный регион от #934 _get_asking_sold_ratio (~940), конфликта нет (mergeable=true).

Squash-merge + delete branch.

<!-- gendesign-review-bot: sha=14bcb21 verdict=approve --> ✅ **APPROVE** — корректный targeted data-quality фикс, NULL-safe. Мержу. ## Verified - `listings.listing_segment` существует (`011_listings_alter.sql:26`, `'vtorichka'/'novostroyki'`, nullable) → фильтр валиден синтаксически. - **NULL-safe + targeted**: `listing_segment IS NULL OR <> 'novostroyki'` сохраняет NULL (avito/yandex/rosreestr без сегмента — основная масса вторичных comps) + vtorichka, исключает только `novostroyki`. Пул НЕ выкашивается — выпадают лишь cian-строки явно `novostroyki`. → нет риска MIN_ANALOGS-голодания от самого фильтра. - Применён к Tier S/H (через `_COMMON_WHERE`, 3 site'а 3334/3385/3469) + Tier W inline. Tier C уже segment-aware (1518-9), Tier A намеренно relaxed — консистентно. - Логика верна: девелоперский прайс новостроек не должен искажать медиану вторички (реальный bug — 10808 cian-новостроек). Направление сдвига — к истине (ниже), reversible. ## 🟡 Post-deploy QA (не блокер merge) «Golden unchanged» здесь = mock-данные NULL-сегмент (сохраняются) — это согласуется с NULL-safe дизайном, но НЕ валидирует прод-эффект (golden-сет не содержит novostroyki-строк). После деплоя QA стоит на 2-3 ЕКБ-адресах прогнать estimate pre/post: (1) comp-count не схлопнулся ниже порогов, (2) медиана сдвинулась вниз (ожидаемо). Не-comp пути (yandex_valuation/rosreestr) не тронуты. Cross-file: затрагивает estimator.py в районе `_COMMON_WHERE` (~3080) — отдельный регион от #934 `_get_asking_sold_ratio` (~940), конфликта нет (mergeable=true). Squash-merge + delete branch.
bot-reviewer merged commit 3294bc2021 into main 2026-05-31 21:33:24 +00:00
bot-reviewer deleted branch fix/estimator-exclude-novostroyki-comps 2026-05-31 21:33:24 +00:00
Sign in to join this conversation.
No reviewers
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#935
No description provided.