<jupyter_start><jupyter_text>Boosting for Time-Series Prediction<jupyter_code>import tigercontrol
import jax.numpy as np
from tigercontrol.utils.optimizers import *
from tigercontrol.experiments import Experiment
import jax.random as random
from tigercontrol.utils import generate_key<jupyter_output>/Users/paulag/anaconda3/lib/python3.6/site-packages/jax/lib/xla_bridge.py:130: UserWarning: No GPU/TPU found, falling back to CPU.
  warnings.warn('No GPU/TPU found, falling back to CPU.')<jupyter_text>Simulated Data  Setting I: Sanity Check We start with a simple sanity check, in which we generate stationary time-series data assuming the $LQR$ controller with $AR_{dyn} = [0.6, −0.5, 0.4, −0.4, 0.3]$, $MA_{dyn} = [0.3, −0.2]$, and normally distributed noise terms $w_t ∼ N (0, 0.3^2)$.<jupyter_code>ar_dyn = np.array([0.6, -0.5, 0.4, -0.4, 0.3])
ma_dyn = np.array([0.3, -0.2])
mean, noise_magnitude = 0, 0.3<jupyter_output><empty_output><jupyter_text>We will compare the controllers LQR-OGD and LQR-ONS against their boosted counterparts (with $N = 5$ weak learners). Following the experiments and results of [1], our autoregressive controllers use history $p = 10$ and learning rate $0.00001$.<jupyter_code>N, p, lr = 5, 10, 0.0001
ogd = OGD(learning_rate=lr)
ons = ONS(learning_rate=lr)<jupyter_output><empty_output><jupyter_text>We can now initialize the experiment:<jupyter_code>T = 10000
exp = Experiment()

exp.initialize(timesteps = T)

exp.add_environment('LQR', {'p' : ar_dyn, 'q' : ma_dyn, 'c' : mean, 'noise_magnitude' : noise_magnitude}, name = 'I')

exp.add_controller('AutoRegressor', {'p' : p, 'optimizer': ogd}, name = 'OGD')
exp.add_controller('AutoRegressor', {'p' : p, 'optimizer': ons}, name = 'ONS')

exp.add_controller('DynaBoost', {'controller_id' : 'AutoRegressor', 'controller_params' : {'p' : p, 'optimizer': ogd},
                'N': N, 'reg' : 0.0}, name = 'LQR-OGD')
exp.add_controller('DynaBoost', {'controller_id' : 'AutoRegressor', 'controller_params' : {'p' : p, 'optimizer': ons},
                'N': N, 'reg' : 0.0}, name = 'LQR-ONS')
exp.scoreboard()
exp.graph()<jupyter_output><empty_output><jupyter_text>Setting II: Changing coefficients We generate non-stationary time-series data assuming the $LQR$ controller, such that the coefficients are slowly changing with time. Specifically, we set $AR_{dyn}(t) = [−0.4,−0.5,0.4,0.4,0.1] \cdot \left(\frac{t}{10^4}\right) + [0.6,−0.4,0.4,−0.5,0.4] \cdot \left(1 - \frac{t}{10^4}\right)$, $MA_{dyn} = [0.32, −0.2]$ and noise terms $w_t ∼ Unif[-.5, .5]$.<jupyter_code>ar_dyn = [np.array([-0.4,-0.5,0.4,0.4,0.1])* t / 10000 + 
          np.array([0.6,-0.4,0.4,-0.5,0.4]) * (1 - t / 10000)
          for t in range(T)]

ma_dyn = np.array([0.32, -0.2])
mean, noise_magnitude, noise_distribution = 0, 0.5, 'unif'
exp.add_environment('LQR', {'p' : ar_dyn, 'q' : ma_dyn, 'c' : mean,
                'noise_magnitude' : noise_magnitude, 'noise_distribution' : noise_distribution},
                name = 'II')
exp.scoreboard()
exp.graph()<jupyter_output><empty_output><jupyter_text>Setting III: Abrupt change We again generate a non-stationary LQR process, but here coefficients change abruptly. For the first half of time steps we use $\alpha = [0.6, -0.5, 0.4, -0.4, 0.3]$ and $\beta = [0.3, -0.2]$. For the second half, we set $\alpha = [-0.4, −0.5, 0.4, 0.4, 0.1]$ and $\beta = [−0.3, 0.2]$. The noise terms are uniformly distributed on $[-.5, .5]$.<jupyter_code>ar_dyn = [np.array([0.6,-0.5,0.4,-0.4,0.3]) for _ in range(T // 2)] + \
         [np.array([-0.4,-0.5,0.4,0.4,0.1]) for _ in range(T // 2 + T % 2)]

ma_dyn = [np.array([0.3, -0.2]) for _ in range(T // 2)] + \
         [np.array([-0.3, 0.2]) for _ in range(T // 2 + T % 2)]

mean, noise_magnitude, noise_distribution = 0, 0.5, 'unif'
exp.add_environment('LQR', {'p' : ar_dyn, 'q' : ma_dyn, 'c' : mean,
                'noise_magnitude' : noise_magnitude, 'noise_distribution' : noise_distribution},
                name = 'III')
exp.scoreboard()
exp.graph()<jupyter_output><empty_output><jupyter_text>Setting IV: Correlated noise We consider an LQR process generated by $\alpha = [0.11, -0.5]$ and $\beta = [0.41, -0.39, -0.685, 0.1]$. The noise terms are now correlated; each noise term is normally distributed, with expectation thatis the value of the previous noise term, such that $w_t ∼ N(w_{t−1},0.32)$, and then clip $w_t$ to be in the range $[−1, 1]$.<jupyter_code>ar_dyn = np.array([0.11, -0.5])
ma_dyn = np.array([0.41, -0.39, -0.685, 0.1])
mean = 0
noise_magnitude = 0.3
def generate_noise(T, noise_magnitude):
    noise_list = [noise_magnitude * random.normal(generate_key())]
    for t in range(T - 1):
        next_noise = noise_list[t] + noise_magnitude * random.normal(generate_key())
        next_noise = min(1, next_noise)
        next_noise = max(-1, next_noise)
        noise_list.append(next_noise)
    return noise_list
noise_list = generate_noise(T + ma_dyn.shape[0] + 1, noise_magnitude)
exp.add_environment('LQR', {'p' : ar_dyn, 'q' : ma_dyn, 'noise_list' : noise_list, 'c' : mean},
                name = 'IV')
exp.scoreboard()
exp.graph()<jupyter_output><empty_output><jupyter_text>Real World Data  I. Predicting CO contaminate concentration We provide results on real-world time-series data, from the UCI Machine Learning Repository. The data contains 2764 instances of hourly averaged measurements of air quality properties from an Italian city throughout one year, as measured by chemical sensors. Specifically, our goal was to predict the level of CO contaminate concentration.<jupyter_code>T = 2700
exp = Experiment()

exp.initialize(timesteps = T)

exp.add_environment('UCI-Indoor')

exp.add_controller('AutoRegressor', {'p' : p, 'optimizer': ogd}, name = 'OGD')
exp.add_controller('AutoRegressor', {'p' : p, 'optimizer': ons}, name = 'ONS')

exp.add_controller('DynaBoost', {'controller_id' : 'AutoRegressor', 'controller_params' : {'p' : p, 'optimizer': ogd},
                'N': N, 'reg' : 0.0}, name = 'LQR-OGD')
exp.add_controller('DynaBoost', {'controller_id' : 'AutoRegressor', 'controller_params' : {'p' : p, 'optimizer': ons},
                'N': N, 'reg' : 0.0}, name = 'LQR-ONS')
exp.scoreboard()
exp.graph()<jupyter_output><empty_output><jupyter_text>II. Predicting El Nino<jupyter_code>T = 5900
exp = Experiment()

exp.initialize(timesteps = T)

exp.add_environment('ENSO', {'input_signals' : ['oni'], 'timeline' : 1})
exp.add_environment('ENSO', {'input_signals' : ['oni'], 'timeline' : 3})
exp.add_environment('ENSO', {'input_signals' : ['oni'], 'timeline' : 6})
exp.add_environment('ENSO', {'input_signals' : ['oni'], 'timeline' : 12})

exp.add_controller('AutoRegressor', {'p' : p, 'optimizer': ogd}, name = 'OGD')
exp.add_controller('AutoRegressor', {'p' : p, 'optimizer': ons}, name = 'ONS')

exp.add_controller('DynaBoost', {'controller_id' : 'AutoRegressor', 'controller_params' : {'p' : p, 'optimizer': ogd},
                'N': N, 'reg' : 0.0}, name = 'LQR-OGD')
exp.add_controller('DynaBoost', {'controller_id' : 'AutoRegressor', 'controller_params' : {'p' : p, 'optimizer': ons},
                'N': N, 'reg' : 0.0}, name = 'LQR-ONS')
exp.scoreboard()
exp.graph()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.17710793165717462, 'fraction_numerical': 0.039033199055424364, 'mean_word_length': 4.313653136531365, 'pattern_counts': {'":': 0, '<': 36, '<?xml version=': 0, '>': 36, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '229158', 'license': 'Apache-2.0', 'n_tokens_mistral': 2885, 'n_tokens_neox': 2658, 'n_words': 675, 'path': 'research/notebooks/Boosting Experiments.ipynb', 'repo_name': 'MinRegret/TigerControl', 'size': '7199'}