fix(tradein/estimate): убрать квартал соседа из квартального индекса (координатный резолв — за флагом OFF) #2839
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#2839
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/quarter-target-from-neighbour"
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?
Что поставляется
estimate_quarter_from_coords_enabled)Поставляемое поведение = «нет своего квартала → нет поправки». Координатная половина в коде есть, дефолтом мертва, с критерием приёмки и датой-предохранителем в
config.py.Что не так (origin/main)
estimator.py:3131:target_house_cadnum=dadata.house_cadnum, пуст в 15 из 15 применений на проде → квартал ЦЕЛИ всегда приходил из кадастра первого попавшегося аналога (донор в 201-4087 м, медиана ~580 м).Guard-2при таком резолве тавтологичен: квартал-донор по построению есть среди аналогов.Индексы кварталов на дистанции донора расходятся в 1.15-1.23× по медиане и 1.6-1.8× в p90. Индекс не шум: корреляция с независимой медианой живых объявлений того же квартала
r(log)=0.837(307 кварталов),0.880на плотных.Измерение 1 — снятие фолбэка (бэктест, 277 сделок)
test_backtest_regression_gateреплеит фикстуру через_price_from_inputsсtarget_house_cadnum=None, то есть меряет ровно снятие квартала соседа. Затронуто 30 из 277 (10.8%), множитель стало/было min 0.704 / медиана 1.019 / max 1.661 (17 вверх, 13 вниз).Ухудшилось:
Не изменились: покрытие (82.16/82.09), sharpness 0.743, n во всех бакетах, headline. 28 полей из 96. Эталон перегенерирован документированной командой; на
origin/mainта же команда даёт закоммиченный файл байт-в-байт (гейт зелёный) → расхождение атрибутировано правке.Про эконом отдельно. Он ухудшился именно от снятия поправки — значит чужой квартал ему случайно помогал. Станет ли эконому лучше при ПРАВИЛЬНОМ квартале — ответить нельзя: фикстура координатный путь не проходит. Поэтому «эконом не хуже 14.20» вписан прямым пунктом в критерий приёмки флага.
Измерение 2 — точность координатного резолва против известной истины
Истина независима от механизма:
houses.cadastral_number— это ответ DaData на адресную строку, не KNN-подсказка (house_dedup_merge.py:126; 2648 значений, все сdadata_enriched_at). Вырожденный66:41:0000000(146 домов) исключён → 2398 домов ЕКБ. Прогнан ровно тот запрос, что в_lookup_target_quarter_by_coords.Два исхода разведены намеренно: «здания нет» честно отменяет поправку, «квартал чужой» даёт молчаливо неверную. Промах стоит 1.111× по медиане и 1.447× в p90 (отношение индексов чужого и своего квартала, 183 промаха с обоими индексами).
Точность по дистанции: 1-5 м — 98.4%, 5-15 м — 92.3%, 15-30 м — 82.8%, 30-50 м — 58.4%, 50-100 м — 45.9%. Медиана дистанции у промахнувшихся 34.7 м против 18.2 м у попавших. Гистограмма дистанций не имеет пика в нуле (0-1 м всего 8 домов) → координаты домов не сняты с тех же зданий, проверка не круговая.
Вывод: порог 50 м замером НЕ подтверждён. Он был заимствован у
cadastral_geo_match.DEFAULT_THRESHOLD_M, а не измерен. В этом PR порог 25 м (92.1%).Концентрация промахов по блокам кварталов на 50 м: 66:41:04 — 27.8%, 66:41:01 — 27.1%, 66:41:07 — 26.3%, 66:41:03 — 4.1%. Явного «одного плохого района» нет, промахи размазаны — это дистанция, а не локальный дефект зеркала.
Измерение 3 — рабочий тракт (20 оценок со своим кадастром)
Здесь координаты приходят от геокодера, а не из справочника домов, и результат хуже:
Попадания на 0 м и 4 м; промахи на 32 м (Горный Щит, квартал вообще из другого блока) и 39 м (Малышева 84). Малышева 84 — ровно тот кейс из таблицы денег ниже, где координатный квартал двигал цену на −20.6%: квартал был неверный. n мал, но это единственная выборка ровно того входа, что в проде, и она поддерживает и порог 25 м, и флаг OFF.
💰 Денежный эффект того, что реально включается
Флаг OFF → все 15 исторических применений теряют поправку, цена = текущая ÷ применённый множитель:
Диапазон −8.3% … +66.7%, поверхность 15 из 1081 (1.4%). При включённом флаге на 25 м добавилось бы ~3% оценок (по выборке рабочего тракта — 3 из 20) — но это цифра для отдельного решения, не для этого мержа.
Критерий приёмки флага (записан ДО факта, 2026-08-12)
В
config.pyрядом с флагом: перезахватить фикстуру с заполненным координатным кварталом и получить overall MAPE не хуже 12.63 И сегмент эконом не хуже 14.20 при доле затронутых сделок ≥5%. Если к 2026-09-12 замер не сделан — флаг и_lookup_target_quarter_by_coordsудалить, а не оставлять «на вырост».Тесты
tests/test_estimator_quarter_from_own_coords.py— 4 теста, включаяtest_coords_resolver_dormant_by_default(флаг OFF → резолвер не зовётся вовсе). Красный прогон на origin/main:(5 аналогов в дешёвом квартале index 0.8 + 5 в дорогом 1.6, свой кадастр неизвестен: старый код брал квартал первого аналога → ×0.667 без единого факта о цели.)
Пересечение с #2836
Нет: #2836 правит
weight_total == 0(строки ~3198-3240), здесь — резолвtarget_quarter(~3131-3137), config и вызывающий код. NB для #2836: он тоже двигает спину и, вероятно, потребует своей регенерации эталона гейта.Опровергнутые предпосылки
listings_clean» — не спасает: донор в 201-4087 м, в 15/15 квартал не совпал с кварталом ближайшего к цели здания.Test plan
docker logs tradein-backend | grep quarter_index— блок должен молчать на оценках без кадастра DaDataRefs #2583
fix(tradein/estimate): квартал цели — по её координатам, а не из кадастра аналогаto fix(tradein/estimate): убрать квартал соседа из квартального индекса (координатный резолв — за флагом OFF)