[tradein][analytics] Elite/premium estimate accuracy — data-research findings + roadmap #2002

Open
opened 2026-06-27 15:22:02 +00:00 by lekss361 · 3 comments
Owner

Большой data-research (2026-06-27) по систематической недооценке движком бизнес/элит (−21%/−38%). Шипнуто по ходу: гейт #1997, калиброванный 80% PI #2001.

Измерено (hermetic harness + прод-дамп n=2366, held-out)

  • g(es)-рекалибровка — ТУПИК: УХУДШАЕТ хвосты (элит −26%→−36%) — es сжат (R²=0.16), элит неотделим от комфорта при равном es (unidentifiability). НЕ шипить.
  • Премия дорогих — в analog-headline, не в ratio: пул / микро-компсы / ДКП-история / own-building asking ВСЕ занижают элит (0.79 / 0.71 / 0.59 / 0.765); own_ask/pool=0.92. → премия unit-level.
  • Композит (es + year + dkp_ratio + area): R² 0.12→0.31 (held-out, ×3). Помогает эконом/комфорт/бизнес (−22%→−19%, разворачивает вред g(es)); элит/премиум не двигает. year — звезда (corr 0.378 с остатком: движок недооценивает новостройки). floor есть на сделках → measurable, добавить в композит.

ЕКБ ≥20М₽ vs обычные (идентифицируемость элита)

area 115 vs 55 м² (2×), ppm² 254k vs 74k (3.4×). Описания: класс-слова (элит/премиум/бизнес-класс) 25%, вид/набережная 32%, дизайнер 14%. Концентрация по домам: Гоголя 21 (90 листингов), Жукова 16 (66), Энергостроителей 7 (61), Ельцина 6 (36)... → элит идентифицируем: (1) большая площадь [на сделках], (2) data-derived premium-building список, (3) класс-слова описаний (25%).

Источники класса (БД + код + live-браузер)

  • Avito «Класс жилья» — только новостройки (live-verified: вторичка не даёт; в houses.raw_characteristics, не извлекается; потолок ~620 = 4.5%).
  • Yandex по домам — 7 строк (мизер). Вторичный люкс (99% элита) структурного класса не имеет нигде → только description.

Roadmap (приоритет ROI)

  • Композит-PR (year+floor+area) — measurable, помогает эконом/комфорт/бизнес. Валидация через гейт (year/floor/area есть в фикстуре).
  • Description-mining: parse_house_class+infer_repair_state_from_text существуют, но подключены ТОЛЬКО к yandex-новострою — навесить на avito/yandex description → класс/отделка из текста (вторичный люкс). ~25% элит-описаний несут класс явно.
  • Premium-building список (data-derived из концентрации ≥20М) → premium-флаг + частичный uplift.
  • Manual-review флаг high-value/low-conf → ручная оценка (PR-2).
  • Forward-logging прод-оценок — единственный способ валидировать unit-level (отделка/класс/вид): ДКП их не несут.
  • Поднять avito-detail throughput (anti-bot) → наполняет repair/ceiling/finish.

Catch (хард-ограничение)

Ground-truth ДКП несут только floor/rooms/area/year/price. finish/view/class бэктестом НЕ валидируются → measurable-рычаги = year+floor+area; unit-сигналы только через forward-logging.

Bugs найдены попутно — отдельный issue.

Refs #1966

Большой data-research (2026-06-27) по систематической недооценке движком бизнес/элит (−21%/−38%). Шипнуто по ходу: гейт #1997, калиброванный 80% PI #2001. ## Измерено (hermetic harness + прод-дамп n=2366, held-out) - **g(es)-рекалибровка — ТУПИК**: УХУДШАЕТ хвосты (элит −26%→−36%) — `es` сжат (R²=0.16), элит неотделим от комфорта при равном `es` (unidentifiability). НЕ шипить. - **Премия дорогих — в analog-headline, не в ratio**: пул / микро-компсы / ДКП-история / own-building asking ВСЕ занижают элит (0.79 / 0.71 / 0.59 / 0.765); own_ask/pool=0.92. → премия **unit-level**. - **Композит (es + year + dkp_ratio + area): R² 0.12→0.31 (held-out, ×3)**. Помогает эконом/комфорт/**бизнес** (−22%→−19%, разворачивает вред g(es)); элит/премиум не двигает. `year` — звезда (corr 0.378 с остатком: движок недооценивает новостройки). **`floor` есть на сделках → measurable, добавить в композит.** ## ЕКБ ≥20М₽ vs обычные (идентифицируемость элита) area **115 vs 55 м² (2×)**, ppm² **254k vs 74k (3.4×)**. Описания: класс-слова (элит/премиум/бизнес-класс) **25%**, вид/набережная **32%**, дизайнер 14%. **Концентрация по домам**: Гоголя 21 (90 листингов), Жукова 16 (66), Энергостроителей 7 (61), Ельцина 6 (36)... → элит **идентифицируем**: (1) большая площадь [на сделках], (2) data-derived premium-building список, (3) класс-слова описаний (25%). ## Источники класса (БД + код + live-браузер) - Avito «Класс жилья» — **только новостройки** (live-verified: вторичка не даёт; в `houses.raw_characteristics`, не извлекается; потолок ~620 = 4.5%). - Yandex по домам — 7 строк (мизер). Вторичный люкс (99% элита) структурного класса не имеет нигде → **только `description`**. ## Roadmap (приоритет ROI) - [ ] **Композит-PR** (year+floor+area) — measurable, помогает эконом/комфорт/бизнес. Валидация через гейт (year/floor/area есть в фикстуре). - [ ] **Description-mining**: `parse_house_class`+`infer_repair_state_from_text` существуют, но подключены ТОЛЬКО к yandex-новострою — навесить на avito/yandex `description` → класс/отделка из текста (вторичный люкс). ~25% элит-описаний несут класс явно. - [ ] **Premium-building список** (data-derived из концентрации ≥20М) → premium-флаг + частичный uplift. - [ ] **Manual-review флаг** high-value/low-conf → ручная оценка (PR-2). - [ ] **Forward-logging прод-оценок** — единственный способ валидировать unit-level (отделка/класс/вид): ДКП их не несут. - [ ] Поднять avito-detail throughput (anti-bot) → наполняет repair/ceiling/finish. ## Catch (хард-ограничение) Ground-truth ДКП несут только floor/rooms/area/year/price. finish/view/class **бэктестом НЕ валидируются** → measurable-рычаги = year+floor+area; unit-сигналы только через forward-logging. Bugs найдены попутно — отдельный issue. Refs #1966
lekss361 added the
analytics
priority/p2
scope/backend
tradein
labels 2026-06-27 15:22:34 +00:00
Author
Owner

Tier-aware ratio (#928) — measured + diagnosed dead-end (removed)

Ran the live full-spine harness (700 prod deals) with tier_aware_ratio_enabled OFF vs ON:

  • бизнес bias −14.8→−8.5, элит −28.6→−24.0 (helps the tails)
  • BUT эконом +5.8→+18.1, комфорт −4.6→+5.3, overall MAPE 14.6→17.2, bias −2.9→+8.9 (worse)

Root-cause (Monte-Carlo, true sold/asking = const 0.84): the tier derivation bins SOLD deals by sold-ppm² against ASKING-percentile bounds (t33/t66 of listings), then divides within-tier medians of mismatched populations — a ratio-of-truncated-medians artifact. A simulation with a constant 0.84 reproduces the prod tier values (0.94/0.99/0.96) and the deal split (57/27/15% vs listings 33/33/33) almost exactly → the 0.84→0.99 gradient is 100% spurious. Correct binning (both sides by asking) is nearly flat (0.83→0.85); the true price-tier signal is ~2-3pp.

Conclusion: within-price-tier sold/asking is uncomputable from asking-less deals. The valid conditioning is non-price observables — the per-rooms blend (0.84) + the hedonic year+area (#2004), which is the statistically-correct version of price-segment correction. Hybrid (high-tier only) and re-derive are both moot (the high-tier 0.96 is also an artifact; re-derive needs per-deal asking the deals lack).

Dead tier path removed (footgun — flag flip degraded prod): branch fix/tradein-remove-tier-ratio-footgun. Tier tables (mig 098) left inert; optional DROP follow-up.

## Tier-aware ratio (#928) — measured + diagnosed dead-end (removed) Ran the live full-spine harness (700 prod deals) with `tier_aware_ratio_enabled` OFF vs ON: - бизнес bias −14.8→−8.5, элит −28.6→−24.0 (helps the tails) - BUT эконом +5.8→**+18.1**, комфорт −4.6→+5.3, **overall MAPE 14.6→17.2**, bias −2.9→+8.9 (worse) **Root-cause (Monte-Carlo, true sold/asking = const 0.84):** the tier derivation bins SOLD deals by sold-ppm² against ASKING-percentile bounds (t33/t66 of listings), then divides within-tier medians of mismatched populations — a **ratio-of-truncated-medians artifact**. A simulation with a *constant* 0.84 reproduces the prod tier values (0.94/0.99/0.96) and the deal split (57/27/15% vs listings 33/33/33) almost exactly → the 0.84→0.99 gradient is 100% spurious. Correct binning (both sides by asking) is nearly flat (0.83→0.85); the true price-tier signal is ~2-3pp. **Conclusion:** within-price-tier sold/asking is **uncomputable from asking-less deals**. The valid conditioning is non-price observables — the per-rooms blend (0.84) + the hedonic year+area (#2004), which is the statistically-correct version of price-segment correction. Hybrid (high-tier only) and re-derive are both moot (the high-tier 0.96 is also an artifact; re-derive needs per-deal asking the deals lack). Dead tier path removed (footgun — flag flip degraded prod): branch `fix/tradein-remove-tier-ratio-footgun`. Tier tables (mig 098) left inert; optional DROP follow-up.
Author
Owner

IMV / Tier-S harness-extension — 5th measured dead-end (algo frontier closed)

Extended the harness (--resolve-house-id, #2025) to resolve each deal's house_id and fire the Tier-S canonical analog path + Avito-IMV anchor (prod fires them; the harness hard-coded None). Ran on/off, 700 prod deals:

  • Resolution coverage: 303/700 (43%) resolve a house_id; only 59 (8.4%) are IMV-reachable.
  • expected_sold per-segment OFF vs ON ≈ identical — overall MAPE 14.52→14.49 (noise), бизнес −14.97→−14.97, элит −28.56→−28.56 (zero movement), range-coverage unchanged.
  • Why: Avito-IMV covers mid-market, not elite (doesn't reach the underpriced elite deals); Tier-S canonical feeds the radius-median pool that already underprices elite. House-resolution is inert for accuracy.

Algo frontier — CLOSED (5 measured dead-ends)

g(es) recalibration · price-tier ratio (artifact) · corridor-clamp (inert) · outlier-filter (noise) · IMV/Tier-S (inert). The one shipped accuracy win remains the hedonic year+area (#2004). The residual бизнес/элит underprice is irreducibly unit-level (finish/class/view — not on ДКП deals). No further measurable algorithmic lever exists in the current data; the only paths are structural: forward-logging of live estimates + the premium_building→manual-review routing (#2006/#2019/#2021/#2022, shipped) for the high-value tail.

## IMV / Tier-S harness-extension — 5th measured dead-end (algo frontier closed) Extended the harness (`--resolve-house-id`, #2025) to resolve each deal's house_id and fire the Tier-S canonical analog path + Avito-IMV anchor (prod fires them; the harness hard-coded `None`). Ran on/off, 700 prod deals: - **Resolution coverage: 303/700 (43%) resolve a house_id; only 59 (8.4%) are IMV-reachable.** - **expected_sold per-segment OFF vs ON ≈ identical** — overall MAPE 14.52→14.49 (noise), **бизнес −14.97→−14.97, элит −28.56→−28.56 (zero movement)**, range-coverage unchanged. - Why: Avito-IMV covers mid-market, not elite (doesn't reach the underpriced elite deals); Tier-S canonical feeds the radius-median pool that already underprices elite. House-resolution is **inert for accuracy**. ### Algo frontier — CLOSED (5 measured dead-ends) g(es) recalibration · price-tier ratio (artifact) · corridor-clamp (inert) · outlier-filter (noise) · IMV/Tier-S (inert). The one shipped accuracy win remains the **hedonic year+area** (#2004). The residual бизнес/элит underprice is **irreducibly unit-level** (finish/class/view — not on ДКП deals). No further measurable algorithmic lever exists in the current data; the only paths are structural: forward-logging of live estimates + the premium_building→manual-review routing (#2006/#2019/#2021/#2022, shipped) for the high-value tail.
Author
Owner

Триаж roadmap (tech-analyst, 2026-07-04, git archaeology + code grep):

  • Premium-building список — DONE (139_premium_houses.sql MV + 142_premium_buildings_curated.sql + _is_premium_building() estimator.py:3616)
  • Manual-review флаг — DONE (_manual_review() estimator.py:3666, триггеры premium/high-value/wide-range/elite-ppm2, UI banner)
  • Description-mining — PARTIAL: infer_repair_state_from_text подключён широко (avito/cian/domclick/yandex detail). parse_house_class — только на yandex-новострое; avito использует структурное поле "Класс жилья" (#2003/PR #2359), yandex-secondary/cian/domclick house_class из текста не парсят нигде. Не завожу issue автоматически — фаззи scope (structured-field vs текст, риск false-positive), нужен твой приоритет-колл.
  • Композит year+floor+area — PARTIAL: year+area шипнуты, floor реализован и протестирован, но забыт на неслитой ветке feat/tradein-hedonic-ground-floor (tip fe69d6e7, 356 коммитов позади main) → вынесено в отдельный узкий issue #2382 (ребейз+ревалидация+мерж).
  • Forward-logging — инфраструктура есть (каждая оценка уже пишется в trade_in_estimates с полными inputs/outputs), но консьюмера для forward-валидации против будущих реальных продаж нет — открытый мониторинг без чёткого DoD, не actionable в текущем виде.

Issue оставляю открытым — не весь roadmap закрыт (#2382 + description-mining extension решение за тобой).

Триаж roadmap (tech-analyst, 2026-07-04, git archaeology + code grep): - **Premium-building список** — DONE (`139_premium_houses.sql` MV + `142_premium_buildings_curated.sql` + `_is_premium_building()` estimator.py:3616) - **Manual-review флаг** — DONE (`_manual_review()` estimator.py:3666, триггеры premium/high-value/wide-range/elite-ppm2, UI banner) - **Description-mining** — PARTIAL: `infer_repair_state_from_text` подключён широко (avito/cian/domclick/yandex detail). `parse_house_class` — только на yandex-новострое; avito использует структурное поле "Класс жилья" (#2003/PR #2359), yandex-secondary/cian/domclick house_class из текста не парсят нигде. Не завожу issue автоматически — фаззи scope (structured-field vs текст, риск false-positive), нужен твой приоритет-колл. - **Композит year+floor+area** — PARTIAL: year+area шипнуты, **floor реализован и протестирован, но забыт на неслитой ветке** `feat/tradein-hedonic-ground-floor` (tip fe69d6e7, 356 коммитов позади main) → вынесено в отдельный узкий issue #2382 (ребейз+ревалидация+мерж). - **Forward-logging** — инфраструктура есть (каждая оценка уже пишется в `trade_in_estimates` с полными inputs/outputs), но консьюмера для forward-валидации против будущих реальных продаж нет — открытый мониторинг без чёткого DoD, не actionable в текущем виде. Issue оставляю открытым — не весь roadmap закрыт (#2382 + description-mining extension решение за тобой).
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
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#2002
No description provided.