SPB Git

spb/wp29_uqo

Public
2.6 KB · 40 lines python
1import json, numpy as np, pandas as pd2r=json.load(open('out/results.json')); fc=pd.read_csv('out/forecasts.csv')3d=pd.read_csv('data/ip_predictors.csv')4out=[]5def chk(name,cond): out.append((name,bool(cond))); print(('PASS' if cond else 'FAIL'),name)6chk('180 rows', len(fc)==180)7chk('60 per model', (fc.model.value_counts()==60).all())8chk('horizon all 1', (fc.horizon==1).all())9chk('target = origin + 1 month', (pd.to_datetime(fc.target_date)==pd.to_datetime(fc.origin_date)+pd.DateOffset(months=1)).all())10chk('first/last origin', fc.origin_date.min()=='2021-09-01' and fc.origin_date.max()=='2026-08-01')11# independent re-implementation, slicing raw data <= t positionally (leakage-proof by construction)12ip=d.ip_growth.values; months=list(d.month)13X_all=np.column_stack([ip, np.r_[np.nan,ip[:-1]], np.r_[np.nan,np.nan,ip[:-2]], d.oil_chg, d.fedfunds, d.permit_chg, d.neworder_chg, d.tcu])14i0=months.index('1992-03-01'); im=months.index('1992-04-01')15maxdiff=0; maxleak=016for t in pd.date_range('2021-09-01','2026-08-01',freq='MS').strftime('%Y-%m-%d'):17    it=months.index(t)18    if True:19        Xa=X_all[:it+1].copy(); y=ip[:it+1].copy()   # only data dated <= t20        X=Xa[i0:it]; Y=y[i0+1:it+1]21        mu=X.mean(0); sd=X.std(0,ddof=1); Z=(X-mu)/sd; yb=Y.mean()22        b=np.linalg.inv(Z.T@Z+50*np.eye(8))@Z.T@(Y-yb)23        f=yb+((Xa[it]-mu)/sd)@b24        g=fc[(fc.origin_date==t)&(fc.model=='ridge')].forecast.iloc[0]25        maxdiff=max(maxdiff,abs(f-g))26    m=ip[im:it+1].mean(); maxdiff=max(maxdiff,abs(m-fc[(fc.origin_date==t)&(fc.model=='mean')].forecast.iloc[0]))27    maxdiff=max(maxdiff,abs(ip[it]-fc[(fc.origin_date==t)&(fc.model=='naive')].forecast.iloc[0]))28    maxdiff=max(maxdiff,abs(ip[it+1]-fc[(fc.origin_date==t)&(fc.model=='naive')].actual.iloc[0]))29chk(f'independent re-implementation matches forecasts (max abs diff {maxdiff:.2e})', maxdiff<1e-8)30for m in ['naive','mean','ridge']:31    e=fc[fc.model==m].forecast-fc[fc.model==m].actual32    chk(f'rmse_{m} recomputed', abs(np.sqrt((e**2).mean())-r[f'rmse_{m}'])<1e-9)  # CSV stores 10 decimals33    chk(f'mae_{m} recomputed', abs(e.abs().mean()-r[f'mae_{m}'])<1e-9)  # CSV stores 10 decimals34    chk(f'rmse_{m}>0 and rmse>=mae', r[f'rmse_{m}']>0 and r[f'rmse_{m}']>=r[f'mae_{m}'])35chk('rel_impr naive identity', abs(r['rel_improvement_vs_naive']-(1-r['rmse_ridge']/r['rmse_naive']))<1e-15)36chk('rel_impr mean identity', abs(r['rel_improvement_vs_mean']-(1-r['rmse_ridge']/r['rmse_mean']))<1e-15)37ex=pd.read_csv('out/exclusions.csv')38chk('exclusion ledger sums', r['n_input_rows']['ip_predictors.csv']-ex.n_removed.sum()==r['n_analysed']==413)39chk('n_train first origin = 354 (1992-03..2021-08)', r['n_train_first_origin']==354)40
Files · main
Menu

Theme