All checks were successful
CI Trade-In / browser-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 / changes (pull_request) Successful in 9s
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 Trade-In / backend-tests (pull_request) Successful in 4m32s
Флаг anchor_tier оставался равным anchor_tier_fetched ("A"/"C"), когда якорь
фактически НЕ строился — сброс делал только low-conf гейт (#audit-1), но не
Tier C corridor-гейт (#1795) и не сама _compute_same_building_anchor, когда
она отклоняет кандидата (комплов меньше estimate_sb_min_comps). Дальше по коду
залипший флаг читается как «headline построил якорь» и молча глушит IMV/Yandex
blend (#651, гейт `anchor_tier is None`) и quarter-index correction (#764
Guard-1a) — притом что радиусный headline их не получал.
Замер: 154 из 996 сделок теряют tier-флаг этой правкой, и у всех 154 изменение
цены ровно 0.000% — чинится именно залипший ФЛАГ, не ценообразование (баланс
метрик бэктеста подтверждает: единственная дельта в baseline — новая канарейка
unrecorded_lookup_calls, все остальные метрики побитово те же).
- estimator.py: сброс `anchor_tier = None` единой веткой `if anchor is None`
после всех трёх гейтов (Tier C / low-conf / _compute_same_building_anchor);
display-only IMV-карточка больше не гейтится по `anchor_tier is not None`
(иначе терялась в щели «тир добыт, якорь не построен, headline подавлен»).
- backtest_estimator.py: quarter_index_lookup/quarter_indexes_lookup в реплее
отвечают «промах» (None/{}), если сброс флага открыл путь, которого не было
в замороженной фикстуре, вместо падения с RuntimeError; счётчик таких промахов
уходит в baseline как unrecorded_lookup_calls (точное целое, канарейка на
расхождение реплея с захватом). Заодно пиннится estimate_dedup_analogs_enabled
= False внутри replay_fixture (было только в самом гейте) — иначе штатная
регенерация baseline (--from-fixture --update-baseline) писала baseline,
который тест не совпадал бы никогда.
- backtest_baseline.json: перегенерирован штатным путём, unrecorded_lookup_calls=0.
Выделено из #2656/PR #2661 — фильтры свежести (scraped_at) в якоре дома и в
знаменателе коэффициента выкупа остаются в исходном PR как отдельная, более
спорная правка (двигает деньги: знаменатель просаживается на ~1.3% по бакетам).
155 lines
3.1 KiB
JSON
155 lines
3.1 KiB
JSON
{
|
|
"calibration": {
|
|
"high": {
|
|
"coverage_pct": null,
|
|
"mape_pct": null,
|
|
"n": 0,
|
|
"n_covered": 0
|
|
},
|
|
"low": {
|
|
"coverage_pct": 82.09,
|
|
"mape_pct": 12.67,
|
|
"n": 276,
|
|
"n_covered": 220
|
|
},
|
|
"medium": {
|
|
"coverage_pct": 100.0,
|
|
"mape_pct": 6.99,
|
|
"n": 1,
|
|
"n_covered": 1
|
|
}
|
|
},
|
|
"confidence_order": [
|
|
"high",
|
|
"medium",
|
|
"low"
|
|
],
|
|
"expected_sold": {
|
|
"overall": {
|
|
"mape_pct": 12.63,
|
|
"median_bias_pct": -3.74,
|
|
"n": 269,
|
|
"n_no_analogs": 0,
|
|
"p25_pct": -15.17,
|
|
"p75_pct": 8.67
|
|
},
|
|
"per_rooms": {
|
|
"0": {
|
|
"label": "студия",
|
|
"mape_pct": 16.96,
|
|
"median_bias_pct": 16.96,
|
|
"n": 35,
|
|
"n_no_analogs": 0,
|
|
"p25_pct": 1.5,
|
|
"p75_pct": 38.82
|
|
},
|
|
"1": {
|
|
"label": "1к",
|
|
"mape_pct": 11.06,
|
|
"median_bias_pct": -4.61,
|
|
"n": 93,
|
|
"n_no_analogs": 0,
|
|
"p25_pct": -14.43,
|
|
"p75_pct": 8.15
|
|
},
|
|
"2": {
|
|
"label": "2к",
|
|
"mape_pct": 17.39,
|
|
"median_bias_pct": -11.71,
|
|
"n": 74,
|
|
"n_no_analogs": 0,
|
|
"p25_pct": -23.07,
|
|
"p75_pct": -0.36
|
|
},
|
|
"3": {
|
|
"label": "3к",
|
|
"mape_pct": 7.79,
|
|
"median_bias_pct": -4.05,
|
|
"n": 43,
|
|
"n_no_analogs": 0,
|
|
"p25_pct": -10.26,
|
|
"p75_pct": 3.82
|
|
},
|
|
"4": {
|
|
"label": "4+",
|
|
"mape_pct": 16.38,
|
|
"median_bias_pct": -1.32,
|
|
"n": 24,
|
|
"n_no_analogs": 0,
|
|
"p25_pct": -14.91,
|
|
"p75_pct": 15.41
|
|
}
|
|
},
|
|
"per_segment": {
|
|
"бизнес": {
|
|
"mape_pct": 13.65,
|
|
"median_bias_pct": -10.54,
|
|
"n": 46,
|
|
"p25_pct": -27.15,
|
|
"p75_pct": -1.31
|
|
},
|
|
"комфорт": {
|
|
"mape_pct": 10.14,
|
|
"median_bias_pct": -5.01,
|
|
"n": 101,
|
|
"p25_pct": -15.49,
|
|
"p75_pct": 4.37
|
|
},
|
|
"премиум": {
|
|
"mape_pct": 68.92,
|
|
"median_bias_pct": -68.92,
|
|
"n": 1,
|
|
"p25_pct": -68.92,
|
|
"p75_pct": -68.92
|
|
},
|
|
"эконом": {
|
|
"mape_pct": 14.2,
|
|
"median_bias_pct": 3.33,
|
|
"n": 115,
|
|
"p25_pct": -8.69,
|
|
"p75_pct": 27.3
|
|
},
|
|
"элит": {
|
|
"mape_pct": 33.2,
|
|
"median_bias_pct": -33.2,
|
|
"n": 6,
|
|
"p25_pct": -42.75,
|
|
"p75_pct": -22.4
|
|
}
|
|
}
|
|
},
|
|
"headline": {
|
|
"ask_median_ppm2": 145883.6593586467,
|
|
"deal_median_ppm2": 125063.0,
|
|
"spread_pct": 16.65
|
|
},
|
|
"range_coverage": {
|
|
"overall": {
|
|
"coverage_pct": 82.16,
|
|
"n": 269,
|
|
"n_covered": 221
|
|
},
|
|
"per_confidence": {
|
|
"high": {
|
|
"coverage_pct": null,
|
|
"n": 0,
|
|
"n_covered": 0
|
|
},
|
|
"low": {
|
|
"coverage_pct": 82.09,
|
|
"n": 268,
|
|
"n_covered": 220
|
|
},
|
|
"medium": {
|
|
"coverage_pct": 100.0,
|
|
"n": 1,
|
|
"n_covered": 1
|
|
}
|
|
}
|
|
},
|
|
"sharpness": {
|
|
"median_rel_width": 0.743,
|
|
"n": 269
|
|
},
|
|
"unrecorded_lookup_calls": 0
|
|
}
|