def voorspellers(c, archief):
    data = archief[2:219]  # 217 verleden-dagen, week geen trainingsdata
    train, val, test = data[:-70], data[-70:-35], data[-35:]
    assert train[-1]["doel_dag"] < "2021-03-07"
    def features(r):
        t, s = float(r["prognose_T_C"]), float(r["prognose_zonuren"])
        return [max(12-t, 0), max(3-t, 0)**2, s]
    X = np.array([features(r) for r in train])
    mean, scale = X.mean(axis=0), X.std(axis=0)
    scale[scale == 0] = 1
    def ontwerp(rows):
        x = np.array([features(r) for r in rows])
        return np.column_stack([np.ones(len(rows)), (x-mean)/scale])
    Y = np.array([[float(r["vraag_ref_kWh"]), float(r["pv48_kWh"])] for r in train])
    beta = np.linalg.lstsq(ontwerp(train), Y, rcond=None)[0]
    def voorspel(r):
        try:
            x = np.asarray(features(r), dtype=float)
        except (ValueError, TypeError, KeyError):
            return None
        if not np.isfinite(x).all():
            return None
        # Extrapolatie buiten het verstrekte proefgebied: onthouding.
        if float(r["prognose_T_C"]) < -15 or float(r["prognose_T_C"]) > 30:
            return None
        pred = np.r_[1, (x-mean)/scale]@beta
        return np.maximum(pred, 0).tolist()
    scores = {}
    for naam, rows in (("validatie", val), ("test", test)):
        y = np.array([[float(r["vraag_ref_kWh"]), float(r["pv48_kWh"])] for r in rows])
        yp = np.maximum(ontwerp(rows)@beta, 0)
        base = np.array([[float(r["laatste_complete_vraag_kWh"]),
            float(r["laatste_complete_pv48_kWh"])] for r in rows])
        scores[naam] = {"dagen": len(rows), "model_RMSE_kWh":
            np.sqrt(np.mean((yp-y)**2, axis=0)).tolist(),
            "basis_RMSE_kWh": np.sqrt(np.mean((base-y)**2, axis=0)).tolist(),
            "prognose_T_RMSE_K": math.sqrt(np.mean([
                (float(r["prognose_T_C"])-float(r["gerealiseerd_T_C"]))**2 for r in rows])),
            "prognose_zonuren_RMSE_h": math.sqrt(np.mean([
                (float(r["prognose_zonuren"])-float(r["gerealiseerde_zonuren"]))**2 for r in rows]))}
    return {"train_dagen": len(train), "train_van": train[0]["doel_dag"],
        "train_tot": train[-1]["doel_dag"],
        "validatie_van": val[0]["doel_dag"], "validatie_tot": val[-1]["doel_dag"],
        "test_van": test[0]["doel_dag"], "test_tot": test[-1]["doel_dag"],
        "scores_status": "ACHTERAF_SYNTHETISCH", "beta": beta.tolist(),
        "mean": mean.tolist(), "scale": scale.tolist(), "scores": scores}, voorspel
