JuliaGaussianProcesses / TemporalGPs.jl

Fast inference for Gaussian processes in problems involving time. Partly built on results from https://proceedings.mlr.press/v161/tebbutt21a.html
MIT License
117 stars 5 forks source link

Recursive (online) GP example #128

Open JoachimSchaeffer opened 7 months ago

JoachimSchaeffer commented 7 months ago

Hi everyone,

Thanks for creating and sharing this great package!

I'm just getting started looking into the package and was wondering how to update a TemporalGP for new data that becomes available.

To be more precise, I have time series data, with x in R3 and y in R1 for every time step, unevenly sampled in time and containing gaps. I'd like to make a GP forecast for a few days and then update the GP every couple of days once this new data becomes available.

Could you share an example of such a case? (I am happy to support it if it's something that currently is not there but could be done with reasonable effort). How would you go about solving this using TemporalGPs?

willtebbutt commented 7 months ago

Hi @JoachimSchaeffer -- thanks for opening this issue.

We don't at present have a good way to incrementally update the posterior as new data arrives. I know this is a bit odd, but it's because the package is designed around the AbstractGPs API, and is expected to work in batch mode.

I'd be open to suggestions for how to tackle this problem. I agree that it ought to be straightforward, but we'd need a good API.

JoachimSchaeffer commented 7 months ago

@willtebbutt, thanks for your quick response.

Adding the relevant AbstractGP reference: https://juliagaussianprocesses.github.io/AbstractGPs.jl/dev/concrete_features/#Sequential-Conditioning

AbstractGPs with exact GPs handle this under the hood by updating the covariance matrix, which works by just calling posterior again p_fx = posterior(f(x[1:3], 0.1), y[1:3]) p_p_fx = posterior(p_fx(x[4:10], 0.1), y[4:10])

For approximate/variational posterior, the API is slightly different: p_fx1 = posterior(VFE(f(Z)), f(x[1:7], 0.1), y[1:7]) u_p_fx1 = update_posterior(p_fx1, f(x[8:10], 0.1), y[8:10])

I don't have a strong preference regarding API, but I feel like update_posterior is more verbose and would help comprehension.

willtebbutt commented 7 months ago

Ohhh that's a fair point -- yeah, we should just implement that API (I had completely forgotten we had implemented that haha).

Is this something that you're interested in tackling yourself?

JoachimSchaeffer commented 7 months ago

Unfortunately, I'm just starting with using and learning Julia and don't feel ready yet to tackle it myself. But I could have a look at the PR, test it and hopefully contribute another example as soon as my results are published (:

willtebbutt commented 7 months ago

Cool. I'm also up to my eyes in work at the minute, so don't really have time to look at it currently. Maybe someone else will come along and have a go at it!