text_html_output_1.png
BACK = 36
features = ['utrend', 'atrend', 'ntrend', 'lng', 'lat', 'rate0', 'rate1', 'rate2', 'rate3', 'rate4', 'rate_sum', 'last_rate1', 'last_rate2', 'last_rate3', 'last_rate4']
CLIPS = {1: 0.00225, 2: 0.005, 3: 0.011, 4: 0.015, 5: 0.024, 6: 0.032}
for LEAD in range(1, 7):
    print(f'Forecast month ahead {LEAD}...')
    raw[f'pred{LEAD}'] = raw[f'lag{LEAD}'].copy()
    raw[f'k{LEAD}'] = 0.0
    for fold in range(29, 40 + LEAD + 1):
        ind = raw.dcount <= fold - LEAD
        tmp = raw.loc[ind].copy().reset_index(drop=True)
        tmp['target'] = tmp.groupby('cfips')['active'].shift(-LEAD)
        tmp['target'] = tmp['target'] / tmp['active'] - 1
        tmp['target'] = tmp['target'].clip(-1.0, 1.0)
        tmp[f'last_active'] = tmp.groupby('cfips')['active'].transform('last')
        for t in range(5):
            tmp[f'lag{t}'] = tmp.groupby('cfips')['active'].shift(t)
            tmp[f'lag{t}'] = tmp.groupby('cfips')[f'lag{t}'].ffill()
            tmp[f'rate{t}'] = tmp[f'active'] / tmp[f'lag{t}'] - 1
            tmp[f'rate{t}'] = tmp[f'rate{t}'].clip(-1.0, 1.0)
            tmp[f'last_rate{t}'] = (tmp[f'last_active'] - tmp[f'lag{t}']) / tmp[f'last_active']
            tmp[f'last_rate{t}'] = tmp[f'last_rate{t}'].clip(-1.0, 1.0)
            ind = tmp.dcount >= 5
            tmp.loc[ind, f'rate{t}'] = tmp.loc[ind, f'rate{t}'].fillna(0)
            tmp.loc[ind, f'last_rate{t}'] = tmp.loc[ind, f'last_rate{t}'].fillna(0)
        tmp[f'rate_sum'] = (4 * tmp['rate0'] + 3 * tmp['rate1'] + 2 * tmp['rate2'] + 1 * tmp['rate3']) / 10
        model = skSVR(C=0.5, kernel='rbf', degree=3, gamma='scale', coef0=0.0, tol=1e-06, epsilon=0.1, cache_size=200, verbose=False, max_iter=-1)
        ind = tmp.target.notnull() & (tmp.active != 0) & (tmp.dcount >= fold - LEAD - BACK) & (tmp[features].isnull().sum(1) == 0) & (tmp[f'lag{LEAD}'] > 0)
        model.fit(tmp.loc[ind, features], tmp.loc[ind, 'target'])
        ind = tmp.dcount == fold - LEAD
        tmp.loc[ind, f'k{LEAD}'] = model.predict(tmp.loc[ind, features])
        ypred = tmp.loc[ind, [f'k{LEAD}', 'cfips']].set_index('cfips')[f'k{LEAD}'].to_dict()
        del model
        gc.collect()
        ind = raw.dcount == fold
        raw.loc[ind, f'k{LEAD}'] = raw.loc[ind, 'cfips'].map(ypred).fillna(0)
        raw[f'pred{LEAD}'] = (raw[f'lag{LEAD}'] * (raw[f'k{LEAD}'].fillna(0) + 1).clip(1, 1 + CLIPS[LEAD])).round()
        ind = raw.dcount == fold
        smape0 = smape(raw.loc[ind, 'active'], raw.loc[ind, f'lag{LEAD}'])
        smape1 = smape(raw.loc[ind, 'active'], raw.loc[ind, f'pred{LEAD}'])
        print(f'month {fold}, smape gain: {smape0 - smape1:0.4f}')
    raw[f'pred{LEAD}'] = raw[f'lag{LEAD}'] * (raw[f'k{LEAD}'].fillna(0) + 1).clip(1, 1 + CLIPS[LEAD])
    raw[f'pred{LEAD}'] = raw[f'pred{LEAD}'].round()
    ind = (raw.dcount >= 29) & (raw.dcount <= 40)
    smape0 = smape(raw.loc[ind, 'active'], raw.loc[ind, f'lag{LEAD}'])
    smape1 = smape(raw.loc[ind, 'active'], raw.loc[ind, f'pred{LEAD}'])
    print(f'Forecast {LEAD}, total smape gain: {smape0 - smape1:0.4f}')
    print()