From 31b207be936c19f70eb987e772cdabfb6f2e253f Mon Sep 17 00:00:00 2001 From: lekss361 Date: Wed, 16 Sep 2026 16:43:12 +0000 Subject: [PATCH] =?UTF-8?q?=D0=92=D1=8B=D0=BA=D0=BB=D1=8E=D1=87=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20=D0=B3=D0=B5=D0=B4=D0=BE=D0=BD=D0=B8=D1=87=D0=B5?= =?UTF-8?q?=D1=81=D0=BA=D1=83=D1=8E=20=D0=BA=D0=BE=D1=80=D1=80=D0=B5=D0=BA?= =?UTF-8?q?=D1=86=D0=B8=D1=8E=20=E2=80=94=20=D0=BE=D0=BD=D0=B0=20=D1=81?= =?UTF-8?q?=D1=82=D0=B0=D0=BB=D0=B0=20=D1=87=D0=B8=D1=81=D1=82=D1=8B=D0=BC?= =?UTF-8?q?=20=D0=B7=D0=B0=D0=BD=D0=B8=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC?= =?UTF-8?q?=20=D1=86=D0=B5=D0=BD=D1=8B=20(#3538)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tradein-mvp/backend/app/core/config.py | 22 ++- .../tests/fixtures/backtest_baseline.json | 146 +++++++++--------- 2 files changed, 94 insertions(+), 74 deletions(-) diff --git a/tradein-mvp/backend/app/core/config.py b/tradein-mvp/backend/app/core/config.py index 485484d8..594ebe58 100644 --- a/tradein-mvp/backend/app/core/config.py +++ b/tradein-mvp/backend/app/core/config.py @@ -430,7 +430,27 @@ class Settings(BaseSettings): # эконом/комфорт/премиум лучше, элит без изменений (no harm). # После фактора заново применяется le_asking-кламп (expected_sold ≤ asking). # OFF ⇒ точно старое поведение expected_sold. - estimate_hedonic_correction_enabled: bool = True + # ВЫКЛЮЧЕНА 2026-09-16. Замер на проде показал, что коррекция превратилась в + # чистое занижение цены: она двигает точку вниз и НЕ покупает за это точности. + # Контролируемый эксперимент — одна и та же выборка (--engine full --sample 2000 + # --since 2025-06-01 --spread scattered --seed 42 --resolve-house-id), меняется + # ровно эта переменная: + # регион ВКЛ bias/MAPE/покрытие ВЫКЛ bias/MAPE/покрытие + # 77 Москва -9.1 / 20.5 / 69.0 -4.1 / 19.7 / 71.2 + # 50 область -12.1 / 19.4 / 75.4 -10.4 / 19.2 / 74.8 + # 66 обл. целиком -17.1 / 23.0 / 66.7 -12.4 / 23.2 / 66.2 + # 66 только ЕКБ -17.4 / 21.2 / 69.8 -14.2 / 21.3 / 69.9 + # Последняя строка решающая: ЕКБ — ровно та выборка, на которой коэффициенты + # перефитили 30.08.2026 (#3248, n=1269). Даже там выключение снимает 3.2 пункта + # занижения при неизменных MAPE и покрытии. Механика понятна из самих + # коэффициентов: b_larea=0, поэтому фактор = exp(-0.0140 + 0.0769*(year-2000)/20 + # - 0.0745*[floor==1]), и для дома 1980 года это 0.913, то есть -8.7%. Жилой фонд + # в выборке преимущественно старый → фактор systematically < 1 → минус к цене. + # Коэффициенты фитили на остатке log(actual_sold/expected_sold) ПРИ ТОЙ базе, + # какая была тогда; база с тех пор уехала (area-бакетный ratio #2620, коэффициент + # asking->sold пересчитан по регионам 15.09), а хедонику не пересчитывали. + # ВКЛЮЧАТЬ ОБРАТНО только вместе с перефитом и замером всех четырёх строк выше. + estimate_hedonic_correction_enabled: bool = False # #3248 (перефит 2026-08-30, n=1269 из свежей прод-фикстуры ЕКБ 1600 сделок). # # Прежние значения (b0=0.6146, year=0.1220, larea=-0.1603, first=-0.1248) зафичены diff --git a/tradein-mvp/backend/tests/fixtures/backtest_baseline.json b/tradein-mvp/backend/tests/fixtures/backtest_baseline.json index 4758c633..12017ca0 100644 --- a/tradein-mvp/backend/tests/fixtures/backtest_baseline.json +++ b/tradein-mvp/backend/tests/fixtures/backtest_baseline.json @@ -2,21 +2,21 @@ "calibration": { "high": { "coverage_pct": 75.0, - "mape_pct": 25.94, + "mape_pct": 19.6, "n": 8, "n_covered": 6 }, "low": { - "coverage_pct": 87.41, - "mape_pct": 14.06, + "coverage_pct": 83.59, + "mape_pct": 15.64, "n": 1562, - "n_covered": 1076 + "n_covered": 1029 }, "medium": { - "coverage_pct": 73.33, - "mape_pct": 18.64, + "coverage_pct": 70.0, + "mape_pct": 27.59, "n": 30, - "n_covered": 22 + "n_covered": 21 } }, "confidence_order": [ @@ -26,111 +26,111 @@ ], "expected_sold": { "overall": { - "mape_pct": 14.28, - "median_bias_pct": -1.61, + "mape_pct": 15.88, + "median_bias_pct": 2.87, "n": 1269, "n_no_analogs": 0, - "p25_pct": -14.08, - "p75_pct": 14.6 + "p25_pct": -10.88, + "p75_pct": 22.98 }, "per_area_bucket": { "0 <30": { - "mape_pct": 16.51, - "median_bias_pct": -3.13, + "mape_pct": 19.76, + "median_bias_pct": -1.49, "n": 161, - "p25_pct": -14.08, - "p75_pct": 22.87 + "p25_pct": -16.45, + "p75_pct": 34.7 }, "1 30-44": { - "mape_pct": 14.06, - "median_bias_pct": -2.33, + "mape_pct": 15.64, + "median_bias_pct": 4.37, "n": 503, - "p25_pct": -14.49, - "p75_pct": 12.58 + "p25_pct": -10.58, + "p75_pct": 22.86 }, "2 44-62": { - "mape_pct": 12.48, - "median_bias_pct": -0.39, + "mape_pct": 13.86, + "median_bias_pct": 4.15, "n": 379, - "p25_pct": -11.23, - "p75_pct": 14.65 + "p25_pct": -7.92, + "p75_pct": 23.85 }, "3 62-85": { - "mape_pct": 15.24, - "median_bias_pct": -1.94, + "mape_pct": 15.97, + "median_bias_pct": -2.33, "n": 179, - "p25_pct": -14.98, - "p75_pct": 15.27 + "p25_pct": -12.1, + "p75_pct": 18.18 }, "4 >=85": { - "mape_pct": 20.88, - "median_bias_pct": -10.36, + "mape_pct": 20.46, + "median_bias_pct": -4.97, "n": 47, - "p25_pct": -24.08, - "p75_pct": 13.38 + "p25_pct": -26.03, + "p75_pct": 7.15 } }, "per_rooms": { "0": { "label": "студия", - "mape_pct": 16.51, - "median_bias_pct": -3.13, + "mape_pct": 19.76, + "median_bias_pct": -1.49, "n": 161, "n_no_analogs": 0, - "p25_pct": -14.08, - "p75_pct": 22.87 + "p25_pct": -16.45, + "p75_pct": 34.7 }, "1": { "label": "1к", - "mape_pct": 14.06, - "median_bias_pct": -2.33, + "mape_pct": 15.64, + "median_bias_pct": 4.37, "n": 503, "n_no_analogs": 0, - "p25_pct": -14.49, - "p75_pct": 12.58 + "p25_pct": -10.58, + "p75_pct": 22.86 }, "2": { "label": "2к", - "mape_pct": 12.48, - "median_bias_pct": -0.39, + "mape_pct": 13.86, + "median_bias_pct": 4.15, "n": 379, "n_no_analogs": 0, - "p25_pct": -11.23, - "p75_pct": 14.65 + "p25_pct": -7.92, + "p75_pct": 23.85 }, "3": { "label": "3к", - "mape_pct": 15.24, - "median_bias_pct": -1.94, + "mape_pct": 15.97, + "median_bias_pct": -2.33, "n": 179, "n_no_analogs": 0, - "p25_pct": -14.98, - "p75_pct": 15.27 + "p25_pct": -12.1, + "p75_pct": 18.18 }, "4": { "label": "4+", - "mape_pct": 20.88, - "median_bias_pct": -10.36, + "mape_pct": 20.46, + "median_bias_pct": -4.97, "n": 47, "n_no_analogs": 0, - "p25_pct": -24.08, - "p75_pct": 13.38 + "p25_pct": -26.03, + "p75_pct": 7.15 } }, "per_segment": { "бизнес": { - "mape_pct": 16.86, - "median_bias_pct": -16.84, + "mape_pct": 19.58, + "median_bias_pct": -19.58, "n": 144, - "p25_pct": -25.83, - "p75_pct": -9.36 + "p25_pct": -27.32, + "p75_pct": -12.79 }, "комфорт": { - "mape_pct": 12.14, - "median_bias_pct": -5.9, + "mape_pct": 10.68, + "median_bias_pct": -5.78, "n": 425, - "p25_pct": -16.66, - "p75_pct": 4.9 + "p25_pct": -15.88, + "p75_pct": 4.49 }, "премиум": { "mape_pct": null, @@ -140,18 +140,18 @@ "p75_pct": null }, "эконом": { - "mape_pct": 15.17, - "median_bias_pct": 6.26, + "mape_pct": 20.17, + "median_bias_pct": 18.98, "n": 697, - "p25_pct": -6.89, - "p75_pct": 28.97 + "p25_pct": 1.25, + "p75_pct": 41.97 }, "элит": { - "mape_pct": 31.18, - "median_bias_pct": -31.18, + "mape_pct": 36.11, + "median_bias_pct": -36.11, "n": 3, - "p25_pct": -46.94, - "p75_pct": -28.1 + "p25_pct": -44.21, + "p75_pct": -32.72 } } }, @@ -162,9 +162,9 @@ }, "range_coverage": { "overall": { - "coverage_pct": 87.0, + "coverage_pct": 83.22, "n": 1269, - "n_covered": 1104 + "n_covered": 1056 }, "per_confidence": { "high": { @@ -173,14 +173,14 @@ "n_covered": 6 }, "low": { - "coverage_pct": 87.41, + "coverage_pct": 83.59, "n": 1231, - "n_covered": 1076 + "n_covered": 1029 }, "medium": { - "coverage_pct": 73.33, + "coverage_pct": 70.0, "n": 30, - "n_covered": 22 + "n_covered": 21 } } },