Contents

20250722 meeting

The cover image shows the prediction result for Day 1 after training on 250 days of data. The predicted time is 11:30 AM on September 7, 2024.

Introduction

This experiment aims to predict the next data point by exploring the linear relationship between spatial basis functions and real data.

Experiment

In this experiment, the original three-dimensional spatiotemporal data (5000 locations, 250 days, 24 hours) is first standardized for each location’s time series, followed by subtracting the mean at each corresponding time point. Using MRTS, a spatial basis matrix of shape (5000, 5000) is computed for each location, and linear regression is performed. The $SSSD^{S4}$ model is then used to predict the next period’s $\mathbb{\beta}$ and $\mathbb{\varepsilon}$ in the linear regression.

The experiment focuses on the region of China, with 5000 locations selected using a fixed random seed, and training with 3,800 iterations.

A portion of the code is shown below:

  • Time series standardization for each location
1
2
3
4
train_ts_mean = np.mean(stacked_train, axis=1)  # (24, 5000)
train_ts_std = np.std(stacked_train, axis=1, ddof=0)  # (24, 5000)
for i in range(24):  # Time series standardization for each location
    stacked_train[i] = (stacked_train[i] - train_ts_mean[i]) / train_ts_std[i]
  • Subtracting Spatial Mean

    To simplify computation, the average across all spatial locations is subtracted in this step. In the future, we plan to implement a more refined approach, such as subtracting the previous spatial mean, and then adding it back after predicting $\mathbb{\beta}$ and $\mathbb{\varepsilon}$ for the next period.

1
2
3
train_sp_mean = np.mean(stacked_train, axis=2)  # (24, 250)
for i in range(24):  # Centralization of each spatial point at time t
    stacked_train[i] = stacked_train[i] - np.mean(train_sp_mean[i][:, None])

The following code should be modified.

1
   stacked_train[i] = stacked_train[i] - train_sp_mean[i][:, None]
  • Code for spatial basis and linear regression model
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
## mrts
mrts = MRTS(locs = torch.tensor(locations_choose), k = locations_choose.shape[0]).forward()
mrts = np.asarray(mrts)

## linear model
betas_all = []
residuals_all = []

X = mrts                     # shape: (5000, 5000)
X_pinv = np.linalg.pinv(X)   # shape: (5000, 5000)

for i in range(24):
    y = stacked_train[i].T   # shape: (5000, 250)
    beta = X_pinv @ y        # shape: (5000, 250)
    y_hat = X @ beta         # shape: (5000, 250)
    residuals = y - y_hat    # shape: (5000, 250)

    betas_all.append(beta.T)
    residuals_all.append(residuals.T)

## beta and residual
betas_all = np.stack(betas_all)         # (24, 250, 5000) 5000 is not location, it is beta
residuals_all = np.stack(residuals_all) # (24, 250, 5000)

The following shows the first 40 $\mathbb{\beta}$, $\mathbb{\varepsilon}$, and QQ plots.

  • $\mathbb{\beta}$
gallery_made_with_nanogallery_beta
  • $\mathbb{\varepsilon}$
gallery_made_with_nanogallery_residual
  • QQ plots
gallery_made_with_nanogallery_qqplots

This experiment only predicts the next 10 periods, using the $SSSD^{S4}$ model to forecast data for these 10 future periods. The original training set (5000, 250, 24) is extended by 10 days to form (5000, 260, 24) data points, filling in the future 10 days. The number of iterations is set to 3,800 for all runs.

Below are the parameters used in this experiment.

model.yaml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
wavenet:
  # WaveNet model parameters
  input_channels: 24  # Number of input channels
  output_channels: 24  # Number of output channels
  residual_layers: 26  # Number of residual layers
  residual_channels: 64  # Number of channels in residual blocks
  skip_channels: 64  # Number of channels in skip connections

  # Diffusion step embedding dimensions
  diffusion_step_embed_dim_input: 128  # Input dimension
  diffusion_step_embed_dim_hidden: 512  # Middle dimension
  diffusion_step_embed_dim_output: 512  # Output dimension

  # Structured State Spaces sequence model (S4) configurations
  s4_max_sequence_length: 250  # Maximum sequence length
  s4_state_dim: 64  # State dimension
  s4_dropout: 0.0  # Dropout rate
  s4_bidirectional: true  # Whether to use bidirectional layers
  s4_use_layer_norm: true  # Whether to use layer normalization

diffusion:
  # Diffusion model parameters
  T: 200  # Number of diffusion steps
  beta_0: 0.0001  # Initial beta value
  beta_T: 0.02  # Final beta value

training.yaml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# Training configuration
batch_size: 500  # Batch size
output_directory: "./results/surface air temperature/beta"  # Output directory for checkpoints and logs
ckpt_iter: "max"  # Checkpoint mode (max or min)
iters_per_ckpt: 100  # Checkpoint frequency (number of epochs)
iters_per_logging: 100  # Log frequency (number of iterations)
n_iters: 60000  # Maximum number of iterations
learning_rate: 0.0005  # Learning rate

# Additional training settings
only_generate_missing: true  # Generate missing values only
use_model: 2  # Model to use for training
masking: "forecast"  # Masking strategy for missing values
missing_k: 10  # Number of missing values

# Data paths
data:
  train_path: "./datasets/surface air temperature/beta/train_betas.npy"  # Path to training data

inference.yaml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# Inference configuration
batch_size: 500  # Batch size for inference
output_directory: "./results/surface air temperature/inference/beta"  # Output directory for inference results
ckpt_path: "./results/surface air temperature/beta"  # Path to checkpoint for inference
trials: 1 # Replications

# Additional training settings
only_generate_missing: true  # Generate missing values only
use_model: 2  # Model to use for training
masking: "forecast"  # Masking strategy for missing values
missing_k: 10  # Number of missing values

# Data paths
data:
  test_path: "./datasets/surface air temperature/beta/test_betas.npy"  # Path to test data

Imputation

During imputation, data is restored in the reverse order of previous processing steps. Specifically, linear data reconstruction is performed first, followed by adding back the spatial mean and reversing the temporal standardization.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
## inference
beta_inference_data = inference_data_concatenate(beta_inference_path).transpose(1, 2, 0)  # (24, 260, 5000)
residual_inference_data = inference_data_concatenate(residual_inference_path).transpose(1, 2, 0)  # (24, 260, 5000)

X = mrts                                     # shape: (5000, 5000)
y_inference = []
for i in tqdm(range(24)):
    beta = beta_inference_data[i].T          # shape: (5000, 260)
    residual = residual_inference_data[i].T  # shape: (5000, 260)
    y_hat = X @ beta + residual              # shape: (5000, 260)

    y_inference.append(y_hat)                # (24, 5000, 260)

y_inference = np.array(y_inference)
y_inference = y_inference.transpose(0, 2, 1)  # (24, 260, 5000)

for i in range(24):
    y_inference[i] = y_inference[i] + np.mean(train_sp_mean[i][:, None])

for i in range(24):
    y_inference[i] = y_inference[i] * train_ts_std[i] + train_ts_mean[i]

Results

The imputation results are shown below, presenting the filled data for the first 40 locations over 260 days and 24 hours.

gallery_made_with_nanogallery_location-value-ts

The following shows the ground truth and imputation results for 260 days, with the last 10 days being missing values.

The following are the experimental results for all days (ALL) and the imputed days (Future).

MethodValue
MSPE (All)275.036719
MSPE (Future)73.921309
MAPE (All)11.352546
MAPE (Future)6.607120
MSPE% (All)0.040497
MSPE% (Future)0.022734
MAPE% (All)0.040497
MAPE% (Future)0.022734

The following are the experimental results for the first 10 locations.

Metriclocation 0location 1location 2location 3location 4location 5location 6location 7location 8location 9
MSPE (All)5.25526210.02698214.82048711.32723321.76603010.16399712.02822727.28116415.93013812.857481
MSPE (Future)3.3568096.47403514.73264210.66481113.9678948.50294112.17420114.51222713.8999788.035698
MAPE (All)1.8284302.5308523.2305152.7704083.8560132.5370442.7927644.2071243.2204592.865893
MAPE (Future)1.3852292.0760083.5607893.0160313.3856092.5519443.0870123.2424863.0982112.263944
MSPE% (All)0.0060740.0084650.0107170.0092040.0128190.0084250.0092390.0139150.0106480.009491
MSPE% (Future)0.0046190.0069980.0119530.0101420.0113760.0085670.0103230.0108230.0103380.007556
MAPE% (All)0.0060740.0084650.0107170.0092040.0128190.0084250.0092390.0139150.0106480.009491
MAPE% (Future)0.0046190.0069980.0119530.0101420.0113760.0085670.0103230.0108230.0103380.007556

Control Group

To verify the effectiveness of the above modifications, the following control group experiment was conducted. For fairness, the number of iterations was also set to 3,800, and the data, after temporal standardization, was input into the $SSSD^{S4}$ model to predict the next 10 days. The experimental results are shown below.

gallery_made_with_nanogallery_location-value-ts_control

Here are the control group experiment results, focusing on all days (ALL) and the imputed days (Future).

Method (Control)Value
MSPE (All)33.366627
MSPE (Future)21.066000
MAPE (All)4.087378
MAPE (Future)3.584273
MSPE% (All)0.014458
MSPE% (Future)0.012363
MAPE% (All)0.014458
MAPE% (Future)0.012363

Below are the experimental results for the top 10 locations in the control group.

Metriclocation 0location 1location 2location 3location 4location 5location 6location 7location 8location 9
MSPE (All)10.08742220.62824232.42920325.99424726.91630924.31629423.36177122.52578926.6756389.733860
MSPE (Future)9.85914622.75444242.28782729.44016130.57431636.25718331.12337125.59259433.91875118.377745
MAPE (All)2.4437043.6766705.0091524.4648254.5964674.1879944.1393864.0708034.4076892.394271
MAPE (Future)2.5367534.2754346.3365795.2149185.3530995.7447325.2379204.6423705.3605643.896869
MSPE% (All)0.0080980.0122780.0166220.0148400.0152770.0138980.0136750.0134490.0145650.007949
MSPE% (Future)0.0084600.0144160.0212720.0175270.0180020.0192900.0175220.0155050.0178970.013019
MAPE% (All)0.0080980.0122780.0166220.0148400.0152770.0138980.0136750.0134490.0145650.007949
MAPE% (Future)0.0084600.0144160.0212720.0175270.0180020.0192900.0175220.0155050.0178970.013019

Conclusion

Even after embedding into the spatial domain, the prediction error remains higher than that of pure time series forecasting. However, this might be due to the smaller prediction region, which results in higher overall accuracy compared to the previous setup that randomly sampled 5,000 locations from one-fourth of the globe. It may be worthwhile to re-examine the linear regression process and reconsider how to handle the spatial average per unit time so that the results retain temporal characteristics.

Epilogue

https://raw.githubusercontent.com/Josh-test-lab/website-assets-repository/refs/heads/main/posts/1140722%20meeting/To%20be%20continued.jpg
To be continued!

Environment

  • Local Operating System: Windows 11 24H2
    • Programming Language: Python 3.12.9
  • Computing Platform: National Center for High-Performance Computing (NCHC) – Taiwan AI Cloud
    • Operating System: Ubuntu
    • Miniconda
    • GPU: NVIDIA Tesla V100 32GB GPU
    • CUDA 12.8 driver
    • Programming Language: Python 3.10.16 for Linux

Further Learning

References