docs(tradein/estimator): докстринг домового IMV-якоря говорит правду о таблице (#2674) #2852
No reviewers
Labels
No labels
Fable 5 ревью
GG-форсайт
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
feedback/max
generative
needs-discussion
needs-human
observability
pause-bots
performance
priority/p0
priority/p1
priority/p2
priority/p3
scope/backend
scope/db
scope/devops
scope/frontend
scope/qa
scrapers
security
site-finder
stage/1
stage/2
status/blocked
status/done
status/needs-analysis
status/needs-fix
status/qa
status/ready
status/review
status/wip
tech-debt
tradein
ux
week ревью 1
wontfix
ИРД
вторичка
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#2852
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/house-imv-anchor-era"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Что это
Докстринг-фикс, один файл, исполняемого кода не касается. Перебазирован на
origin/mainуже с влитым #2816.Изначально в этой ветке была своя правка базиса ремонта — оказалась дублем открытого тогда #2816, снята. Осталось то, чего не сделал ни один PR.
Что чинится
_fetch_house_imv_anchorобещал: «house_imv_evaluationsпопулирована (~2951 домов, fresh)». Неправда по обоим пунктам. Утверждение пережило #2816: тот дописал ниже блок проrenovation_type, а ложь строкой выше прочитал и оставил — ровно тот сценарий, ради которого докстринги и правят отдельно.Замер 2026-08-12, прод:
UNIQUE(house_id)→ORDER BYв запросе выбирает из ≤1 кандидата, а не ранжирует)'cosmetic'vs мода по объявлениям домаhouses.house_typeДва решения, отвергнутые замером — записаны, чтобы не предлагали заново
Гейт эры/свежести. Band-совместимая строка есть у 224 оценок из 1081, и все 224 дореформенные. Свежих 47 не хватает ни на одну. Гейт не отсёк бы плохое, а выключил бы механизм.
Массовая переоценка. 1628 из 2633 домов уже в
imv_status='ok', батч берёт толькоpending/transient_error— для них обновление не «через 300 суток», а никогда; впереди 7144 дома при ~25/прогон ≈ 286 суток. И корень не в свежести: строка, спрошенная в модальном ремонте ДОМА, всё равно не в базисе ремонта клиента — это #2677/#2816.Test plan
pytest tests/на перебазированной ветке — 4327 passed, 21 skippedtest_2677_house_anchor_repair_basis.py+test_estimator_imv_blend.py+test_backtest_regression_gate.py— 24 passedd823ba10;ruff checkчистоscrape_runs status='running'— 0 строк, процессов скрейпера 0Refs #2674, #2677
Порог блендa `anchor > median × 1.15` сравнивал два числа в РАЗНЫХ базах. `median_price` к этому моменту уже умножена на `_repair_coefficient(repair_state)` (блок 4b), то есть описывает квартиру С РЕМОНТОМ ЦЕЛИ. Якорь — цена квартиры в том классе отделки, в котором строку спросили у Авито: 2633 из 2680 строк house_imv_evaluations спрошены с литералом renovation_type='cosmetic' (до фикса параметров 06.08), свежие 47 — в модальном ремонте ДОМА. Ни то, ни другое не есть ремонт цели. Знак ошибки детерминирован ремонтом цели, и это видно на проде (1081 оценка, из них 127 Tier-D с band-совместимым якорем): - цель needs_repair: медиана ×0.94, якорь нет → порог берётся «на халяву». 6 из 14 живых блендов — такие; 5 из 6 после приведения к общей базе исчезают. - цель good/excellent (23 оценки): медиана ×1.05/×1.10 → порог недостижим, бленд не срабатывал НИ РАЗУ. Множитель — отношение уже существующих `_REPAIR_COEF`, обратное отображение вокабуляра Авито — существующий `_IMV_REPAIR_MAP`. Второй таблицы не заводим. Незнакомый/пустой класс с любой стороны → 1.0 (прежнее поведение). Сводка AvitoImvSummary продолжает показывать СЫРУЮ цифру Авито — она так и подписана. `_REPAIR_COEF` проверен данными (прод 2026-08-12, парное сравнение ppm² ВНУТРИ дома, база standard): needs_repair 0.946 при коэффициенте 0.94, good 1.039 при 1.05, excellent 1.113 при 1.10 (61/289/84 домов-пар) — эвристика попадает в измеренное, отдельный множитель не нужен. Гейт «не брать дореформенные строки» рассмотрен и ОТКЛОНЁН замером: он снимает якорь у 224 оценок из 224 (все 224 сидят на дореформенных строках), чтобы убрать 5 ложных срабатываний — 14 блендов и +16.6 млн ₽ коррекции превращаются в 0. Массовая переоценка тоже не чинит дефект: даже при идеально свежих строках, спрошенных в модальном ремонте дома, бленд у целей good/excellent срабатывает 2 раза из 23 вместо 0 — база всё равно не та. Докстринг `_fetch_house_imv_anchor` обещал «~2951 домов, fresh» — неправда по обоим пунктам. Заменён на замер с датой: 2680 строк, 2633 (98.2%) старше 40 суток, 2366 — один прогон 24.05; естественное обновление их не чинит, потому что 1628 из 2633 домов уже в imv_status='ok', а батч выбирает pending/transient_error, где сейчас 7144 дома при темпе ~25/прогон. Тесты двусторонние: на origin/main цель excellent даёт 6 600 000 вместо 7 425 000 (бленд подавлен), цель needs_repair — 6 120 000 вместо 5 640 000 (ложный бленд). Refs #2674fix(tradein/estimator): домовой IMV-якорь и медиана — в одной базе ремонта (#2674)to docs(tradein/estimator): докстринг домового IMV-якоря говорит правду о таблице (#2674)95e3b209cetod823ba10c1