import numpy as np, pytest from traite import hedonique as h def test_mco_recupere_parametres(): rng = np.random.default_rng(1) n = 2000; x = rng.normal(size=(n, 2)); X = np.column_stack([np.ones(n), x]) y = X @ np.array([12.0, 0.5, -0.2]) + rng.normal(0, 0.1, n) r = h.mco(X, y) assert np.allclose(r["beta"], [12.0, 0.5, -0.2], atol=0.02) and r["r2"] > 0.9 def test_indice_dummies(): idx = h.indice_dummies_temps(np.array([0.05, 0.10])) assert idx[0] == 100 and idx[1] == pytest.approx(100 * np.exp(0.05)) def test_ventes_repetees_recupere_indice(): rng = np.random.default_rng(7) vrai = np.array([0, 0.04, 0.09, 0.13, 0.20]) # log-indice n = 3000 t1 = rng.integers(0, 4, n); t2 = np.array([rng.integers(a + 1, 5) for a in t1]) p1 = np.exp(12 + rng.normal(0, 0.3, n) + vrai[t1]); p2 = p1 * np.exp(vrai[t2] - vrai[t1] + rng.normal(0, 0.05, n)) r = h.ventes_repetees_bmn(p1, p2, t1, t2, 5) assert np.allclose(np.log(r["indice"] / 100), vrai, atol=0.01) cs = h.ventes_repetees_case_shiller(p1, p2, t1, t2, 5) assert np.allclose(np.log(cs["indice"] / 100), vrai, atol=0.01) def test_statistiques_ratio_parfaites(): P = np.array([300e3, 400e3, 500e3, 600e3]); V = P * 0.95 s = h.statistiques_ratio(V, P) assert s["ratio_median"] == pytest.approx(0.95) and s["COD"] == pytest.approx(0.0) and s["PRD"] == pytest.approx(1.0) and abs(s["PRB"]) < 1e-9 # régressivité : ratios plus élevés pour les biens bon marché → PRD > 1, PRB < 0 V2 = P * np.array([1.05, 1.0, 0.95, 0.90]) s2 = h.statistiques_ratio(V2, P) assert s2["PRD"] > 1 and s2["PRB"] < 0 and s2["COD"] > 0 def test_moran_detecte_autocorrelation(): rng = np.random.default_rng(3) coords = rng.uniform(0, 10, (300, 2)) W = h.matrice_poids_knn(coords, 6) assert np.allclose(W.sum(1), 1) x_alea = rng.normal(size=300) x_spat = coords[:, 0] + rng.normal(0, 0.5, 300) assert abs(h.moran_i(x_alea, W)["z"]) < 3 assert h.moran_i(x_spat, W)["z"] > 5 def test_sar_recupere_rho(): rng = np.random.default_rng(11) n = 400; coords = rng.uniform(0, 10, (n, 2)); W = h.matrice_poids_knn(coords, 5) X = np.column_stack([np.ones(n), rng.normal(size=n)]); beta = np.array([1.0, 0.8]); rho = 0.5 e = rng.normal(0, 0.3, n) y = np.linalg.solve(np.eye(n) - rho * W, X @ beta + e) r = h.sar_lag_mv(y, X, W) assert abs(r["rho"] - rho) < 0.1 and np.allclose(r["beta"], beta, atol=0.15)