Local GP and Prediction Windows

[1]:
import gpflow as gpf
import numpy as np

from tsipy.correction import SignalGenerator
from tsipy.fusion import LocalGPModel, SVGPModel, create_windows
from tsipy.fusion.kernels import MultiWhiteKernel
from tsipy.fusion.utils import (
    build_and_concat_label_mask,
    build_and_concat_label_mask_output,
)
from tsipy.utils import sort_inputs, plot_signals, plot_signals_and_confidence

Parameters

[2]:
random_seed = 1
pred_window_width = 0.2
fit_window_width = 0.6
normalization = True
clipping = True
n_inducing_pts = 200
max_iter = 2000

Generate Dataset

[3]:
signal_generator = SignalGenerator(
    length=10_000, add_degradation=False, random_seed=random_seed
)

x_a, y_a = signal_generator["a"]
x_b, y_b = signal_generator["b"]

x_a = build_and_concat_label_mask(x_a, label=1)
x_b = build_and_concat_label_mask(x_b, label=2)
x_out = build_and_concat_label_mask_output(signal_generator.x)

# Concatenate signals and sort by x[:, 0]
x = np.vstack((x_a, x_b))
y = np.reshape(np.hstack((y_a, y_b)), newshape=(-1, 1))
x, y = sort_inputs(x, y, sort_axis=0)
[4]:
_, ax_ful = plot_signals(
    [
        (x_a[:, 0], y_a, "$a$", {}),
        (x_b[:, 0], y_b, "$b$", {}),
    ],
)
../_images/notebooks_demo_localgp_6_0.png

Create Windows

[5]:
windows = create_windows(
    x,
    y,
    pred_window_width=pred_window_width,
    fit_window_width=fit_window_width,
    verbose=True,
)

        Data
---------------------------------------------------------------------------
    x:                                            (11025, 2)
        - Range:                                  0.000,    1.000
    y:                                            (11025, 1)
        - Range:                                  9.508,   16.669

        Windows Creation
---------------------------------------------------------------------------
Windows:
    Window:                                       0
        - Prediction:                                 -inf,    0.200
        - Training:                                   0.000,    0.400
        - Data indices:                               0,     4446
        - x, y:                                       (4447, 2), (4447, 1)
    Window:                                       1
        - Prediction:                                 0.200,    0.400
        - Training:                                   0.000,    0.600
        - Data indices:                               0,     6631
        - x, y:                                       (6632, 2), (6632, 1)
    Window:                                       2
        - Prediction:                                 0.400,    0.600
        - Training:                                   0.200,    0.800
        - Data indices:                               2216,     8839
        - x, y:                                       (6624, 2), (6624, 1)
    Window:                                       3
        - Prediction:                                 0.600,    0.800
        - Training:                                   0.400,    1.000
        - Data indices:                               4446,    11024
        - x, y:                                       (6579, 2), (6579, 1)
    Window:                                       4
        - Prediction:                                 0.800,      inf
        - Training:                                   0.600,    1.000
        - Data indices:                               6631,    11024
        - x, y:                                       (4394, 2), (4394, 1)

Visualize Windows

Bounds of prediction windows are shown as solid vertical bars. The center of prediction window is the dashed vertical bar. For each prediction window, we train a model given the points in the corresponding fit window – data points in it are shown with a scatter plot.

[6]:
for window in windows:
    x_window = window.x
    y_window = window.y

    fig, ax = plot_signals([
        (signal_generator.x, signal_generator.y, "GT", {"c": "tab:red"})
    ])

    for label, label_str in zip([1, 2], ["a", "b"]):
        label_indices = np.equal(x_window[:, 1], label)

        ax.scatter(
            x_window[label_indices, 0],
            y_window[label_indices, 0],
            label=label_str
        )

    ax.axvline(x=window.x_pred_start, color="k")
    ax.axvline(x=window.x_pred_end, color="k")
    ax.axvline(x=window.x_pred_mid, color="k", ls="--")
    ax.set_xlim(*ax_ful.get_xlim())
    ax.set_ylim(*ax_ful.get_ylim())
    ax.legend(loc="upper left")
../_images/notebooks_demo_localgp_10_0.png
../_images/notebooks_demo_localgp_10_1.png
../_images/notebooks_demo_localgp_10_2.png
../_images/notebooks_demo_localgp_10_3.png
../_images/notebooks_demo_localgp_10_4.png

Visualize Local GP

Kernel and Fusion Model

[7]:
# Kernel
matern_kernel = gpf.kernels.Matern12(active_dims=[0])
white_kernel = MultiWhiteKernel(labels=(1, 2), active_dims=[1])
kernel = matern_kernel + white_kernel

# Fusion Model
local_model = SVGPModel(
    kernel=kernel,
    num_inducing_pts=n_inducing_pts,
    normalization=True,
    clipping=True,
)
fusion_model = LocalGPModel(
    model=local_model,
    pred_window_width=pred_window_width,
    fit_window_width=fit_window_width,
    normalization=normalization,
    clipping=clipping,
)

Training

[8]:
fusion_model.fit(
    x, y, max_iter=max_iter, random_seed=random_seed, verbose=True
)

y_out_mean, y_out_std = fusion_model(x_out, verbose=True)
Window
    - Prediction:                                 -inf,    0.200
    - Training:                                   0.000,    0.400
    - Data indices:                               0,     4446
    - x, y:                                       (4447, 2), (4447, 1)
    - n_ind_pts/time_unit                         335.000

    - Step      1/2000:                           -10392.235
    - Step    400/2000:                           -4702.954
    - Step    800/2000:                           -1835.324
    - Step   1200/2000:                           -375.766
    - Step   1600/2000:                           -186.645
    - Step   2000/2000:                           445.191
Window
    - Prediction:                                 0.200,    0.400
    - Training:                                   0.000,    0.600
    - Data indices:                               0,     6631
    - x, y:                                       (6632, 2), (6632, 1)
    - n_ind_pts/time_unit                         333.333

    - Step      1/2000:                           -14693.820
    - Step    400/2000:                           -6223.203
    - Step    800/2000:                           -1272.324
    - Step   1200/2000:                           1168.763
    - Step   1600/2000:                           1836.540
    - Step   2000/2000:                           2624.166
Window
    - Prediction:                                 0.400,    0.600
    - Training:                                   0.200,    0.800
    - Data indices:                               2216,     8839
    - x, y:                                       (6624, 2), (6624, 1)
    - n_ind_pts/time_unit                         333.333

    - Step      1/2000:                           -15075.140
    - Step    400/2000:                           -6060.785
    - Step    800/2000:                           -1497.411
    - Step   1200/2000:                           581.294
    - Step   1600/2000:                           1070.016
    - Step   2000/2000:                           1918.390
Window
    - Prediction:                                 0.600,    0.800
    - Training:                                   0.400,    1.000
    - Data indices:                               4446,    11024
    - x, y:                                       (6579, 2), (6579, 1)
    - n_ind_pts/time_unit                         333.389

    - Step      1/2000:                           -14903.845
    - Step    400/2000:                           -5974.357
    - Step    800/2000:                           -1404.789
    - Step   1200/2000:                           817.392
    - Step   1600/2000:                           1621.555
    - Step   2000/2000:                           2279.438
Window
    - Prediction:                                 0.800,      inf
    - Training:                                   0.600,    1.000
    - Data indices:                               6631,    11024
    - x, y:                                       (4394, 2), (4394, 1)
    - n_ind_pts/time_unit                         335.084

    - Step      1/2000:                           -10122.312
    - Step    400/2000:                           -4136.870
    - Step    800/2000:                           -1074.186
    - Step   1200/2000:                           19.079
    - Step   1600/2000:                           681.084
    - Step   2000/2000:                           882.566
Window
    - Prediction:                                 -inf,    0.200
    - Training:                                   0.000,    0.400
    - Data indices:                               0,     4446
    - x, y:                                       (4447, 2), (4447, 1)

    - x_window:                                   (2002, 2)
    - y_mean:                                     (2002, 1)
    - y_std:                                      (2002, 1)
    - Indices:                                    0    2001
Window
    - Prediction:                                 0.200,    0.400
    - Training:                                   0.000,    0.600
    - Data indices:                               0,     6631
    - x, y:                                       (6632, 2), (6632, 1)

    - x_window:                                   (2000, 2)
    - y_mean:                                     (2000, 1)
    - y_std:                                      (2000, 1)
    - Indices:                                    2002    4001
Window
    - Prediction:                                 0.400,    0.600
    - Training:                                   0.200,    0.800
    - Data indices:                               2216,     8839
    - x, y:                                       (6624, 2), (6624, 1)

    - x_window:                                   (1999, 2)
    - y_mean:                                     (1999, 1)
    - y_std:                                      (1999, 1)
    - Indices:                                    4002    6000
Window
    - Prediction:                                 0.600,    0.800
    - Training:                                   0.400,    1.000
    - Data indices:                               4446,    11024
    - x, y:                                       (6579, 2), (6579, 1)

    - x_window:                                   (2000, 2)
    - y_mean:                                     (2000, 1)
    - y_std:                                      (2000, 1)
    - Indices:                                    6001    8000
Window
    - Prediction:                                 0.800,      inf
    - Training:                                   0.600,    1.000
    - Data indices:                               6631,    11024
    - x, y:                                       (4394, 2), (4394, 1)

    - x_window:                                   (1999, 2)
    - y_mean:                                     (1999, 1)
    - y_std:                                      (1999, 1)
    - Indices:                                    8001    9999
[9]:
_ = plot_signals_and_confidence(
    [(x_out[:, 0], y_out_mean, y_out_std, "LocalGP")]
)
../_images/notebooks_demo_localgp_16_0.png

Visualize Predictions per Window

A GP model is trained independently in each window. Here, we visualize prediction and training windows together with the distribution of inducing points.

[10]:
for window_id, window in enumerate(fusion_model.windows):
    y_out_mean_window, y_out_std_window = fusion_model.predict_window(
        x_out, window_id=window_id, verbose=True
    )

    fig, ax = plot_signals_and_confidence(
        [
            (x_out[:, 0], y_out_mean_window, y_out_std_window, "LocalGP-W"),
        ],
    )
    ax.plot(signal_generator.x, signal_generator.y, label="GT", c="tab:red")

    ax.axvline(
        x=max(window.x_pred_start, x_out[0, 0]), color="tab:orange", ls="--"
    )
    ax.axvline(
        x=min(window.x_pred_end, x_out[-1, 0]), color="tab:orange", ls="--"
    )
    ax.axvline(x=window.x_pred_mid, color="k", ls="--")
    ax.axvline(x=max(window.x_fit_start, x_out[0, 0]), color="tab:orange")
    ax.axvline(x=min(window.x_fit_end, x_out[-1, 0]), color="tab:orange")
    ax.set_xlim(*ax_ful.get_xlim())
    ax.set_ylim(*ax_ful.get_ylim())

    if window.model.x_inducing is not None:
        x_inducing = window.model.x_inducing
        x_inducing = window.model._nc.denormalize_x(x_inducing)
        x_inducing = fusion_model._nc.denormalize_x(x_inducing)
        y_inducing = np.mean(y_out_mean) * np.ones_like(x_inducing)

        ax.plot(
            x_inducing[:, 0],
            y_inducing,
            "k|",
            mew=1,
            label="SVGP $x_{ind}$",
        )
Window
    - Prediction:                                 -inf,    0.200
    - Training:                                   0.000,    0.400
    - Data indices:                               0,     4446
    - x, y:                                       (4447, 2), (4447, 1)

    - x_window:                                   (10000, 2)
    - y_mean:                                     (10000, 1)
    - y_std:                                      (10000, 1)
Window
    - Prediction:                                 0.200,    0.400
    - Training:                                   0.000,    0.600
    - Data indices:                               0,     6631
    - x, y:                                       (6632, 2), (6632, 1)

    - x_window:                                   (10000, 2)
    - y_mean:                                     (10000, 1)
    - y_std:                                      (10000, 1)
Window
    - Prediction:                                 0.400,    0.600
    - Training:                                   0.200,    0.800
    - Data indices:                               2216,     8839
    - x, y:                                       (6624, 2), (6624, 1)

    - x_window:                                   (10000, 2)
    - y_mean:                                     (10000, 1)
    - y_std:                                      (10000, 1)
Window
    - Prediction:                                 0.600,    0.800
    - Training:                                   0.400,    1.000
    - Data indices:                               4446,    11024
    - x, y:                                       (6579, 2), (6579, 1)

    - x_window:                                   (10000, 2)
    - y_mean:                                     (10000, 1)
    - y_std:                                      (10000, 1)
Window
    - Prediction:                                 0.800,      inf
    - Training:                                   0.600,    1.000
    - Data indices:                               6631,    11024
    - x, y:                                       (4394, 2), (4394, 1)

    - x_window:                                   (10000, 2)
    - y_mean:                                     (10000, 1)
    - y_std:                                      (10000, 1)
../_images/notebooks_demo_localgp_18_1.png
../_images/notebooks_demo_localgp_18_2.png
../_images/notebooks_demo_localgp_18_3.png
../_images/notebooks_demo_localgp_18_4.png
../_images/notebooks_demo_localgp_18_5.png
[ ]: