This repository contains the code for Dynamic Online Ensembles of Basis Expansions (DOEBE), published in Transactions on Machine Learning Research (TMLR). The paper proposes a generalization of online Gaussian process methods using the random feature approximation to general basis expansions, including Hilbert space Gaussian processes.
The DOEBE paper is available open-access on OpenReview. If you use any code or results from this project, please consider citing the orignal paper:
@article{
waxman2024doebe,
title={Dynamic Ensembles of Basis Expansions},
author={Daniel Waxman and Petar M. Djuri\'c},
journal={Transactions on Machine Learning Research},
issn={2835-8856},
year={2024},
url={https://openreview.net/forum?id=aVOzWH1Nc5},
}
To install DOEBE, you can download the git repository and install the package using pip
:
git clone https://github.com/DanWaxman/DynamicOnlineBasisExpansions
cd DynamicOnlineBasisExpansions/src
pip install -e .
Examples used for experiments in the paper can be found in experiments/
. In general, creating a DOEBE starts with a list of DOEBE.models.DOBE
instances. After instantiating a list of DOBE
models, hyperparameters can be tuned with empirical Bayes via doebe.pretrain(X, y)
. After that, the DOEBE model can be fit to data with doebe.fit(X, y)
. See a minimal example below, which is a fragment of experiments/experiment_2.py
.
import jax
import jax.numpy as jnp
import numpy as np
from DOEBE.doebe import DOEBE
from DOEBE.models import *
jax.config.update(
"jax_enable_x64", True
) # Use double precision, especially for empirical Bayes
from experiment_utils import *
# Get data
X, y = get_data("Kuka #1")
# Prepare GP lengthscale initialization as mentioned in the paper
d = X.shape[1]
L = np.max([np.abs(np.min(X, axis=0)), np.abs(np.max(X, axis=0))], axis=0) * 1.5
M = 100 // d
# Choose one model to be static, and one to be dynamic
var_eps_vals = [0.0, 1e-3]
# Create DOEBE Model of HSGPs
ls_guess = jnp.ones(d)
dogp_list = [
DOAddHSGP(L, M, d, ls_guess, 1.0, var_eps, 0.25) for var_eps in var_eps_vals
]
doebe = DOEBE(dogp_list)
print("Pretraining DOEBE")
doebe.pretrain(X[:1000], y[:1000])
print("Fitting DOEBE")
y_mean, y_var, ws = doebe.fit(X[1000:], y[1000:], return_ws=True)
To use a SDOEBE (for example, the E-DOEBE discussed in the paper), the API is overall similar besides the inclusion of a Q matrix:
# Create SDOEBE/E-DOEBE Model
delta = 1e-2
dogp_list = [
DOAddHSGP(L, M, d, ls_guess, 1.0, var_eps, 0.25) for var_eps in var_eps_vals
]
Q = jnp.array([[1 - delta, delta], [delta, 1 - delta]])
sdoebe = SDOEBE(dogp_list, Q)
print("Pretraining E-DOEBE")
sdoebe.pretrain(X[:1000], y[:1000])
print("Fitting E-DOEBE")
y_mean, y_var, ws = sdoebe.fit(X[1000:], y[1000:], return_ws=True)