Review found the hedonic factor (≤1.30) was applied AFTER the estimate_expected_sold_le_asking clamp, so expected_sold could exceed the asking headline (median) by up to ~26% for new/small lots — an overpay risk that violated the default-True le_asking invariant. Fix: re-assert le_asking right after the hedonic block and before the calibrated-PI range block. Final order: ratio clamp -> hedonic factor -> le_asking re-clamp -> calibrated PI range (range still wraps the clamped point). round(median_ppm2) keeps expected_sold_per_m2 an int. The re-clamp does NOT materially erode the новостройка/бизнес benefit (бизнес bias -9.15->-10.19, MAPE held 12.87) and actually improves overall expected_sold MAPE on the frozen fixture (14.24->13.23) by capping over-corrections that overshot actual sold prices. Adds tests/test_estimator_hedonic.py (hermetic, no DB): factor magnitude vs OFF, both clamp boundaries, neutral year term for target_year=None, and the le_asking invariant under hedonic ON. Baseline regenerated; gate green. Also clarifies the config comment: the quoted held-out fit metrics (18.5->16.1 etc., n=2366) are distinct from the 277-deal backtest fixture (18.63->13.23).
154 lines
3.1 KiB
JSON
154 lines
3.1 KiB
JSON
{
|
|
"calibration": {
|
|
"high": {
|
|
"coverage_pct": null,
|
|
"mape_pct": null,
|
|
"n": 0,
|
|
"n_covered": 0
|
|
},
|
|
"low": {
|
|
"coverage_pct": 81.82,
|
|
"mape_pct": 13.23,
|
|
"n": 275,
|
|
"n_covered": 225
|
|
},
|
|
"medium": {
|
|
"coverage_pct": 100.0,
|
|
"mape_pct": 14.64,
|
|
"n": 2,
|
|
"n_covered": 2
|
|
}
|
|
},
|
|
"confidence_order": [
|
|
"high",
|
|
"medium",
|
|
"low"
|
|
],
|
|
"expected_sold": {
|
|
"overall": {
|
|
"mape_pct": 13.23,
|
|
"median_bias_pct": -2.87,
|
|
"n": 277,
|
|
"n_no_analogs": 0,
|
|
"p25_pct": -14.43,
|
|
"p75_pct": 12.51
|
|
},
|
|
"per_rooms": {
|
|
"0": {
|
|
"label": "студия",
|
|
"mape_pct": 19.38,
|
|
"median_bias_pct": 18.1,
|
|
"n": 37,
|
|
"n_no_analogs": 0,
|
|
"p25_pct": 1.66,
|
|
"p75_pct": 33.53
|
|
},
|
|
"1": {
|
|
"label": "1к",
|
|
"mape_pct": 10.97,
|
|
"median_bias_pct": -3.47,
|
|
"n": 93,
|
|
"n_no_analogs": 0,
|
|
"p25_pct": -12.48,
|
|
"p75_pct": 6.98
|
|
},
|
|
"2": {
|
|
"label": "2к",
|
|
"mape_pct": 17.39,
|
|
"median_bias_pct": -11.71,
|
|
"n": 74,
|
|
"n_no_analogs": 0,
|
|
"p25_pct": -23.37,
|
|
"p75_pct": -0.36
|
|
},
|
|
"3": {
|
|
"label": "3к",
|
|
"mape_pct": 9.77,
|
|
"median_bias_pct": -3.08,
|
|
"n": 43,
|
|
"n_no_analogs": 0,
|
|
"p25_pct": -10.26,
|
|
"p75_pct": 5.77
|
|
},
|
|
"4": {
|
|
"label": "4+",
|
|
"mape_pct": 20.27,
|
|
"median_bias_pct": 8.54,
|
|
"n": 30,
|
|
"n_no_analogs": 0,
|
|
"p25_pct": -3.78,
|
|
"p75_pct": 23.54
|
|
}
|
|
},
|
|
"per_segment": {
|
|
"бизнес": {
|
|
"mape_pct": 12.87,
|
|
"median_bias_pct": -10.19,
|
|
"n": 46,
|
|
"p25_pct": -22.6,
|
|
"p75_pct": -1.31
|
|
},
|
|
"комфорт": {
|
|
"mape_pct": 11.61,
|
|
"median_bias_pct": -4.07,
|
|
"n": 104,
|
|
"p25_pct": -15.64,
|
|
"p75_pct": 7.38
|
|
},
|
|
"премиум": {
|
|
"mape_pct": 68.92,
|
|
"median_bias_pct": -68.92,
|
|
"n": 1,
|
|
"p25_pct": -68.92,
|
|
"p75_pct": -68.92
|
|
},
|
|
"эконом": {
|
|
"mape_pct": 15.17,
|
|
"median_bias_pct": 4.28,
|
|
"n": 120,
|
|
"p25_pct": -6.59,
|
|
"p75_pct": 26.09
|
|
},
|
|
"элит": {
|
|
"mape_pct": 33.2,
|
|
"median_bias_pct": -33.2,
|
|
"n": 6,
|
|
"p25_pct": -42.75,
|
|
"p75_pct": -22.4
|
|
}
|
|
}
|
|
},
|
|
"headline": {
|
|
"ask_median_ppm2": 147545.8502510892,
|
|
"deal_median_ppm2": 125063.0,
|
|
"spread_pct": 17.98
|
|
},
|
|
"range_coverage": {
|
|
"overall": {
|
|
"coverage_pct": 81.95,
|
|
"n": 277,
|
|
"n_covered": 227
|
|
},
|
|
"per_confidence": {
|
|
"high": {
|
|
"coverage_pct": null,
|
|
"n": 0,
|
|
"n_covered": 0
|
|
},
|
|
"low": {
|
|
"coverage_pct": 81.82,
|
|
"n": 275,
|
|
"n_covered": 225
|
|
},
|
|
"medium": {
|
|
"coverage_pct": 100.0,
|
|
"n": 2,
|
|
"n_covered": 2
|
|
}
|
|
}
|
|
},
|
|
"sharpness": {
|
|
"median_rel_width": 0.743,
|
|
"n": 277
|
|
}
|
|
}
|