Skip to content

Commit bb65534

Browse files
authored
Merge pull request #39 from probsys/20251103-fsaad-gpsum
20251103 fsaad gpsum
2 parents 6f04c6f + ae4b426 commit bb65534

9 files changed

Lines changed: 706 additions & 61 deletions

File tree

docs/src/api.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ AutoGP.observation_noise_variances
143143
AutoGP.decompose
144144
AutoGP.extract_kernel
145145
AutoGP.split_kernel_sop
146+
AutoGP.predict_sum
147+
AutoGP.predict_mvn_sum
146148
```
147149

148150
## [Serialization](@id model_serialization)

docs/src/gp.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ AutoGP.GP.ChangePoint
6969
```@docs
7070
AutoGP.Distributions.MvNormal
7171
AutoGP.Distributions.quantile
72+
AutoGP.GP.infer_gp_sum
7273
```
7374

7475

docs/src/tutorials/decomposition.ipynb

Lines changed: 105 additions & 40 deletions
Large diffs are not rendered by default.

docs/src/tutorials/decomposition.md

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ import AutoGP
2020
using CSV
2121
using Dates
2222
using DataFrames
23+
using Printf
2324
using PythonPlot
25+
using Statistics
2426
```
2527

2628

@@ -58,7 +60,7 @@ ax.scatter(df_test.ds, df_test.y, marker="o", color="w", edgecolor="k", label="T
5860

5961

6062

61-
Python: <matplotlib.collections.PathCollection object at 0x713940142a80>
63+
Python: <matplotlib.collections.PathCollection object at 0x7367187bbe30>
6264

6365

6466

@@ -107,7 +109,7 @@ ax.scatter(df_test.ds, df_test.y, marker="o", color="w", edgecolor="k", label="T
107109

108110

109111

110-
Python: <matplotlib.collections.PathCollection object at 0x7138acd17d10>
112+
Python: <matplotlib.collections.PathCollection object at 0x7367183731a0>
111113

112114

113115

@@ -638,7 +640,6 @@ axes[2].set_title("STRUCTURE: GE")
638640

639641

640642

641-
Python: Text(0.5, 1.0, 'STRUCTURE: GE')
642643

643644

644645

@@ -709,37 +710,71 @@ println("Model $(idx) - NO PER"); display(AutoGP.covariance_kernels(model_b)[idx
709710

710711

711712

713+
We can obtain predictions from the sum-of-products using [`AutoGP.GP.predict_sum`](@ref).
714+
712715

713716
```julia
714-
forecasts_a = AutoGP.predict(model_a, ds_query .+ Day(1); quantiles=[0.025, 0.975]);
715-
forecasts_b = AutoGP.predict(model_b, ds_query .+ Day(1); quantiles=[0.025, 0.975]);
717+
forecasts_sum = AutoGP.predict_sum(model, ds_query, AutoGP.GP.Periodic; quantiles=[0.025, 0.975]);
716718
```
717719

718720

719721
```julia
720-
fig, axes = PythonPlot.subplots(figsize=(10,14), nrows=2, tight_layout=true)
721-
for (ax, m, f) in zip(axes, [model_a, model_b], [forecasts_a, forecasts_b])
722-
for i=1:AutoGP.num_particles(m)
723-
subdf = f[f.particle.==i,:]
724-
ax.plot(subdf[!,"ds"], subdf[!,"y_mean"], color="k", linewidth=.5)
725-
ax.fill_between(subdf.ds, subdf[!,"y_0.025"], subdf[!,"y_0.975"]; color="tab:blue", alpha=0.05)
722+
title = ["ALL", "PER", "NOPER"]
723+
nrows = AutoGP.num_particles(model)
724+
fig, axes = PythonPlot.subplots(ncols=3, nrows=nrows, figsize=(26,5*nrows))
725+
for particle=1:AutoGP.num_particles(model)
726+
f = forecasts_sum[forecasts_sum.particle .== particle,:]
727+
for (component, ax) in zip(0:2, axes[particle-1])
728+
subdf = f[f.component .== component,:]
729+
ax.plot(subdf[!,"ds"], subdf[!,"y_mean"], color="k", linewidth=1)
730+
ax.fill_between(subdf.ds, subdf[!,"y_0.025"], subdf[!,"y_0.975"]; color="tab:blue", alpha=0.5)
731+
ax.scatter(df_train.ds, df_train.y, marker="o", color="k", label="Observed Data")
732+
ax.scatter(df_test.ds, df_test.y, marker="o", color="w", edgecolor="k", label="Test Data")
733+
w = @sprintf("%1.2f", maximum(subdf.weight))
734+
ax.set_title("Particle $(particle) - Component $(title[component+1]) - Weight $(w)")
735+
ax.set_ylim([5000, 7500])
726736
end
727-
ax.scatter(df_train.ds, df_train.y, marker="o", color="k", label="Observed Data")
728-
ax.scatter(df_test.ds, df_test.y, marker="o", color="w", edgecolor="k", label="Test Data")
729737
end
730-
axes[0].set_title("STRUCTURE: PER")
731-
axes[1].set_title("STRUCTURE: NO PER")
738+
fig.savefig("forecasts-joint.png", dpi=150)
739+
```
740+
741+
742+
743+
![png](decomposition_files/decomposition_37_0.png)
744+
745+
746+
747+
748+
749+
750+
751+
752+
753+
Using [`AutoGP.GP.predict_mvn_sum`](@ref) gives the overall mixture of Gaussians.
754+
755+
756+
```julia
757+
ds_probe = vcat(df_train.ds, df_test.ds)
758+
mvn, indexes = AutoGP.predict_mvn_sum(model, ds_probe, AutoGP.GP.Periodic);
759+
760+
overall_predictions = mean(mvn)[indexes.Y]
761+
seasonal_predictions = mean(mvn)[indexes.F[1]]
762+
nonseasonal_predictions = mean(mvn)[indexes.F[2]]
763+
fig, ax = PythonPlot.subplots(figsize=(10,6))
764+
ax.plot(ds_probe, seasonal_predictions, marker=".", color="k")
765+
ax.plot(ds_probe, nonseasonal_predictions, marker=".", color="k")
766+
ax.scatter(df_train.ds, df_train.y, marker=".")
767+
ax.scatter(df_test.ds, df_test.y, marker="o", edgecolor="k", facecolor="w")
732768
```
733769

734770

735771

736-
![png](decomposition_files/decomposition_36_0.png)
772+
![png](decomposition_files/decomposition_39_0.png)
737773

738774

739775

740776

741777

742778

743-
Python: Text(0.5, 1.0, 'STRUCTURE: NO PER')
744779

745780

1.72 MB
Loading
45.2 KB
Loading

0 commit comments

Comments
 (0)