fix(tradein/estimate): убрать квартал соседа из квартального индекса (координатный резолв — за флагом OFF) #2839

Merged
bot-backend merged 3 commits from fix/quarter-target-from-neighbour into main 2026-08-12 15:55:25 +00:00
Collaborator

Что поставляется

половина состояние измерено
снятие фолбэка на кадастр аналога включено да — бэктест 277 сделок, −0.55 пп MAPE
координатный резолв квартала цели за флагом, OFF (estimate_quarter_from_coords_enabled) точность резолва — да (92.1% на 25 м); эффект на ЦЕНУ — нет

Поставляемое поведение = «нет своего квартала → нет поправки». Координатная половина в коде есть, дефолтом мертва, с критерием приёмки и датой-предохранителем в config.py.

Что не так (origin/main)

estimator.py:3131:

target_quarter: str | None = _quarter_from_cadastre(target_house_cadnum)
if target_quarter is None:
    for lot in listings_clean:
        cq = _quarter_from_cadastre(lot.get("building_cadastral_number"))
        if cq is not None:
            target_quarter = cq
            break

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 вниз).

метрика эталон стало Δ
expected_sold.overall.mape 13.18 12.63 −0.55
calibration.low.mape 13.2 12.67 −0.53
студии mape 19.38 16.96 −2.42
3к mape 9.34 7.79 −1.55
2к mape 18.26 17.39 −0.87
комфорт mape 11.80 10.14 −1.66
бизнес mape 14.65 13.65 −1.00

Ухудшилось:

метрика эталон стало Δ
сегмент эконом mape 13.71 14.20 +0.49
сегмент эконом bias 2.54 3.33 +0.79
4+ mape 16.30 16.38 +0.08 (bias при этом 3.34 → −1.32, по модулю лучше)
студии p75 34.32 38.82 +4.50
бизнес p25 −22.93 −27.15 −4.22

Не изменились: покрытие (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.

порог ответ выдан чужой квартал «здания нет» точность покрытие
15 м 475 26 1923 94.5% 19.8%
25 м 748 59 1650 92.1% 31.2%
30 м 873 87 1525 90.0% 36.4%
50 м 1341 271 1057 79.8% 55.9%
100 м 2090 644 308 69.2% 87.2%

Два исхода разведены намеренно: «здания нет» честно отменяет поправку, «квартал чужой» даёт молчаливо неверную. Промах стоит 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 оценок со своим кадастром)

Здесь координаты приходят от геокодера, а не из справочника домов, и результат хуже:

порог ответ выдан совпало
50 м 9 3
25 м 3 3

Попадания на 0 м и 4 м; промахи на 32 м (Горный Щит, квартал вообще из другого блока) и 39 м (Малышева 84). Малышева 84 — ровно тот кейс из таблицы денег ниже, где координатный квартал двигал цену на −20.6%: квартал был неверный. n мал, но это единственная выборка ровно того входа, что в проде, и она поддерживает и порог 25 м, и флаг OFF.

💰 Денежный эффект того, что реально включается

Флаг OFF → все 15 исторических применений теряют поправку, цена = текущая ÷ применённый множитель:

адрес было × Δ цены
Белинского 86, Шефская 62 ×2 0.60 +66.7%
Космонавтов 7б ×2 0.73 +37.0%
Белинского 86 ×2 0.76 +31.6%
Ст. Большевиков 82к2, Педагогическая 15 0.79 +26.6%
Белинского 86 0.80 +25.0%
Советская 51 ×3 1.03 −2.9%
Фрунзе 31 1.08 −7.4%
Малышева 84 1.09 −8.3%

Диапазон −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:

>       assert est.median_price_rub == round(_BASE_PPM2 * _AREA)
E       AssertionError: assert 4000000 == 6000000
FAILED test_neighbour_cadastre_no_longer_sets_target_quarter

(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 квартал не совпал с кварталом ближайшего к цели здания.
  • «Выключение поправки уводит цену от сделок» (мой вывод по n=9) — опровергнуто бэктестом на 277 сделках: MAPE 13.18 → 12.63. Срез n=9 из тела PR убран как шум.
  • «Порог 50 м обоснован» (моя же формулировка в первом коммите) — опровергнуто: 79.8% против 92.1% на 25 м; константа была заимствована, а не измерена.
  • «Улучшение равномерное» — нет: эконом хуже на +0.49 пп, хвосты студий и бизнеса толще.
  • Дефект не областной: все 15 применений — Екатеринбург.

Test plan

  • решение владельца по денежному эффекту снятия поправки (−8.3% … +66.7%, 15 оценок) и по ухудшению сегмента эконом
  • после мержа: docker logs tradein-backend | grep quarter_index — блок должен молчать на оценках без кадастра DaData
  • флаг координатного резолва не включать до выполнения критерия приёмки (дедлайн 2026-09-12)

Refs #2583

## Что поставляется | половина | состояние | измерено | |---|---|---| | **снятие фолбэка на кадастр аналога** | **включено** | да — бэктест 277 сделок, −0.55 пп MAPE | | координатный резолв квартала цели | **за флагом, OFF** (`estimate_quarter_from_coords_enabled`) | точность резолва — да (92.1% на 25 м); эффект на ЦЕНУ — **нет** | Поставляемое поведение = «нет своего квартала → нет поправки». Координатная половина в коде есть, дефолтом мертва, с критерием приёмки и датой-предохранителем в `config.py`. ## Что не так (origin/main) `estimator.py:3131`: ```python target_quarter: str | None = _quarter_from_cadastre(target_house_cadnum) if target_quarter is None: for lot in listings_clean: cq = _quarter_from_cadastre(lot.get("building_cadastral_number")) if cq is not None: target_quarter = cq break ``` `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 вниз). | метрика | эталон | стало | Δ | |---|---|---|---| | **expected_sold.overall.mape** | 13.18 | **12.63** | **−0.55** | | calibration.low.mape | 13.2 | 12.67 | −0.53 | | студии mape | 19.38 | 16.96 | −2.42 | | 3к mape | 9.34 | 7.79 | −1.55 | | 2к mape | 18.26 | 17.39 | −0.87 | | комфорт mape | 11.80 | 10.14 | −1.66 | | бизнес mape | 14.65 | 13.65 | −1.00 | **Ухудшилось:** | метрика | эталон | стало | Δ | |---|---|---|---| | **сегмент эконом mape** | 13.71 | **14.20** | **+0.49** | | сегмент эконом bias | 2.54 | 3.33 | +0.79 | | 4+ mape | 16.30 | 16.38 | +0.08 (bias при этом 3.34 → −1.32, по модулю лучше) | | студии p75 | 34.32 | 38.82 | +4.50 | | бизнес p25 | −22.93 | −27.15 | −4.22 | Не изменились: покрытие (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`. | порог | ответ выдан | **чужой квартал** | «здания нет» | точность | покрытие | |---|---|---|---|---|---| | 15 м | 475 | 26 | 1923 | **94.5%** | 19.8% | | 25 м | 748 | 59 | 1650 | **92.1%** | 31.2% | | 30 м | 873 | 87 | 1525 | 90.0% | 36.4% | | **50 м** | 1341 | **271** | 1057 | **79.8%** | 55.9% | | 100 м | 2090 | 644 | 308 | 69.2% | 87.2% | Два исхода разведены намеренно: «здания нет» честно отменяет поправку, «квартал чужой» даёт молчаливо неверную. Промах стоит **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 оценок со своим кадастром) Здесь координаты приходят от геокодера, а не из справочника домов, и результат **хуже**: | порог | ответ выдан | совпало | |---|---|---| | 50 м | 9 | **3** | | 25 м | 3 | **3** | Попадания на 0 м и 4 м; промахи на 32 м (Горный Щит, квартал вообще из другого блока) и 39 м (Малышева 84). **Малышева 84 — ровно тот кейс из таблицы денег ниже, где координатный квартал двигал цену на −20.6%: квартал был неверный.** n мал, но это единственная выборка ровно того входа, что в проде, и она поддерживает и порог 25 м, и флаг OFF. ## 💰 Денежный эффект того, что реально включается Флаг OFF → все 15 исторических применений теряют поправку, цена = текущая ÷ применённый множитель: | адрес | было × | Δ цены | |---|---|---| | Белинского 86, Шефская 62 ×2 | 0.60 | **+66.7%** | | Космонавтов 7б ×2 | 0.73 | +37.0% | | Белинского 86 ×2 | 0.76 | +31.6% | | Ст. Большевиков 82к2, Педагогическая 15 | 0.79 | +26.6% | | Белинского 86 | 0.80 | +25.0% | | Советская 51 ×3 | 1.03 | −2.9% | | Фрунзе 31 | 1.08 | −7.4% | | Малышева 84 | 1.09 | −8.3% | Диапазон **−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: ``` > assert est.median_price_rub == round(_BASE_PPM2 * _AREA) E AssertionError: assert 4000000 == 6000000 FAILED test_neighbour_cadastre_no_longer_sets_target_quarter ``` (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 квартал не совпал с кварталом ближайшего к цели здания. - «Выключение поправки уводит цену от сделок» (мой вывод по n=9) — **опровергнуто** бэктестом на 277 сделках: MAPE 13.18 → 12.63. Срез n=9 из тела PR убран как шум. - «Порог 50 м обоснован» (моя же формулировка в первом коммите) — **опровергнуто**: 79.8% против 92.1% на 25 м; константа была заимствована, а не измерена. - «Улучшение равномерное» — нет: эконом хуже на +0.49 пп, хвосты студий и бизнеса толще. - Дефект не областной: все 15 применений — Екатеринбург. ## Test plan - [ ] решение владельца по денежному эффекту снятия поправки (−8.3% … +66.7%, 15 оценок) и по ухудшению сегмента эконом - [ ] после мержа: `docker logs tradein-backend | grep quarter_index` — блок должен молчать на оценках без кадастра DaData - [ ] флаг координатного резолва не включать до выполнения критерия приёмки (дедлайн 2026-09-12) Refs #2583
bot-backend added 1 commit 2026-08-12 15:18:13 +00:00
fix(tradein/estimate): квартал цели — по её координатам, а не из кадастра аналога
Some checks failed
CI Trade-In / browser-tests (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) Failing after 3m57s
CI Trade-In / changes (pull_request) Successful in 8s
CI / changes (pull_request) Successful in 8s
CI Trade-In / frontend-checks (pull_request) Has been skipped
2bf9e76a10
`target_quarter` для квартального индекса (#764) резолвился так: свой кадастр
цели (DaData) → а если пусто, кадастр ПЕРВОГО аналога с кадастром. Пусто оно
в 15 из 15 применений на проде, то есть «индекс квартала цели» на витрине
всегда был индексом квартала соседа.

Замер 2026-08-12 (прод, 1081 оценка):
- 15/15 применений — house_cadnum пуст; аналог-донор квартала стоял в 201-4087 м
  от цели (медиана ~580 м);
- индексы кварталов на такой дистанции расходятся в 1.15-1.23 раза по медиане
  и в 1.6-1.8 по p90 → множитель на витрине был чужой;
- индекс при этом НЕ шум: корреляция с независимой медианой живых объявлений
  того же квартала r(log)=0.84 (307 кварталов), 0.88 на плотных (n_deals>=50) —
  поэтому чужой квартал это реальный сдвиг цены, а не безобидная неточность.

Фикс: квартал цели снимается по СОБСТВЕННЫМ координатам цели — ближайшее здание
в cad_buildings_local (ЕКБ-зеркало Росреестра, 47 111 зданий) в пределах 50 м,
тем же geo-nearest приёмом и с тем же порогом, каким уже заполняется
listings.building_cadastral_number (tasks/cadastral_geo_match). Нет здания
в 50 м → поправки нет: это честнее, чем взять квартал соседа.

Эффект на 15 исторических применений: 7 теряют поправку (ближайшее здание
59-180 м), 8 пересчитываются от своего квартала; диапазон изменения цены
−25.0% … +66.7%.
Light1YT added 1 commit 2026-08-12 15:36:03 +00:00
test(tradein/backtest): эталон гейта после снятия квартала соседа
All checks were successful
CI Trade-In / changes (pull_request) Successful in 13s
CI / changes (pull_request) Successful in 13s
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 4m6s
86cb294949
Гейт `test_backtest_regression_gate` реплеит замороженную фикстуру (277 сделок)
прямо через `_price_from_inputs` с `target_house_cadnum=None`, минуя
`estimate_quality`. То есть на фикстуре меряется ровно снятие поправки по кварталу
СОСЕДА (координатный резолв в реплей не попадает — его делает вызывающий код).

Затронуто 30 сделок из 277 (10.8% — сходится с прод-оценкой поверхности ~10%);
множитель цены стало/было: min 0.704, медиана 1.019, max 1.661 (17 вверх / 13 вниз).

Сдвиг метрик (эталон → стало):
  expected_sold.overall.mape_pct   13.18 → 12.63  (−0.55)
  calibration.low.mape_pct          13.2 → 12.67  (−0.53)
  студии mape                      19.38 → 16.96  (−2.42)
  3к mape                           9.34 →  7.79  (−1.55)
  2к mape                          18.26 → 17.39  (−0.87)
  комфорт mape                     11.80 → 10.14  (−1.66)
  бизнес mape                      14.65 → 13.65  (−1.00)
УХУДШИЛОСЬ:
  эконом mape                      13.71 → 14.20  (+0.49), bias 2.54 → 3.33
  4+ mape                          16.30 → 16.38  (+0.08), bias 3.34 → −1.32
  хвосты: студии p75 34.32 → 38.82, бизнес p25 −22.93 → −27.15

Покрытие (82.09/82.16), sharpness (0.743), n по всем бакетам и headline не менялись.
Атрибуция: на origin/main регенерация тем же путём даёт эталон байт-в-байт,
расхождение появляется ровно от правки резолва квартала.
Light1YT added 1 commit 2026-08-12 15:48:44 +00:00
fix(tradein/estimate): координатный резолв квартала — за флагом OFF, порог 25 м
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI / changes (pull_request) Successful in 9s
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 3m58s
CI Trade-In / browser-tests (pull_request) Has been skipped
b13880ff15
Точность самого резолва измерена против НЕЗАВИСИМОЙ истины: 2398 домов ЕКБ, где
квартал известен из кадастра DaData (ответ на адрес, а не KNN-подсказка — см.
house_dedup_merge.py:126; вырожденный 66:41:0000000 у 146 домов исключён).

  порог   ответ выдан   чужой квартал   точность   покрытие
   15 м        475            26          94.5%      19.8%
   25 м        748            59          92.1%      31.2%
   50 м       1341           271          79.8%      55.9%
  100 м       2090           644          69.2%      87.2%

Порог 50 м, заимствованный у cadastral_geo_match, замером НЕ подтверждён: каждый
пятый ответ — чужой квартал, а промах стоит 1.111× по медиане и 1.447× в p90
(отношение индексов чужого и своего квартала). Порог 25 м обоснован замером.

Разделение: снятие фолбэка на кадастр аналога поставляется включённым (измерено
бэктестом, −0.55 пп MAPE), координатный резолв — за
estimate_quarter_from_coords_enabled=False. Причина: точность РЕЗОЛВА измерена,
эффект поправки на точность ЦЕНЫ — нет (фикстура гейта идёт с
target_house_cadnum=None и координатный путь не проходит). Критерий приёмки и
дата-предохранитель (2026-09-12) записаны в config рядом с флагом.

На рабочем тракте (координаты оценок, а не домов справочника) точность ниже:
из 20 оценок со своим кадастром ответ в 50 м выдан 9 раз, совпал 3; в 25 м —
3 ответа, 3 совпадения. Попадания на 0-4 м, промахи на 32-39 м. Один из промахов —
Малышева 84, тот самый кейс, где координатный квартал двигал цену на −20.6%.
bot-backend changed title from fix(tradein/estimate): квартал цели — по её координатам, а не из кадастра аналога to fix(tradein/estimate): убрать квартал соседа из квартального индекса (координатный резолв — за флагом OFF) 2026-08-12 15:49:53 +00:00
bot-backend merged commit 9a89c34971 into main 2026-08-12 15:55:25 +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#2839
No description provided.