多元卡尔曼滤波器数组赋值与协变量引入技术问询
Hey there! Let's work through your multivariate Kalman Filter issue and get that model capturing cross-variable dependencies like it should.
First, Why Your Current Model Acts Like Separate Univariate Models
The main problem with your code is how you've set up the trend component and noise matrices:
- When using
SSMtrend(1)with a 6-variate time series, you're telling KFAS to use a single shared trend across all 6 variables, not individual trends for each variable. - Your
Hararray is a 6x6x100 matrix filled with 0.01, but since the state dimension is only 1 (fromSSMtrend(1)), KFAS can't properly interpret the 6x6 Q matrix. This effectively forces the model to treat each variable independently, hence matching univariate results.
Fixing the Multivariate Structure
To model dependent trends across variables, we need to:
- Assign individual trends to each variable
- Use non-diagonal covariance matrices for state noise (
Q) and observation noise (H) to capture cross-variable dependencies
Here's revised code with these fixes:
library("KFAS") set.seed(123) # For reproducibility n <- 100 # Generate your original data dx <- data.frame( a1=cumsum(sample(c(-1, 1), n, TRUE)), a2=cumsum(sample(c(-1, 1), n, TRUE)), a3=cumsum(sample(c(-1, 1), n, TRUE)), a4=cumsum(sample(c(-1, 1), n, TRUE)), a5=cumsum(sample(c(-1, 1), n, TRUE)), a6=cumsum(sample(c(-1, 1), n, TRUE)) ) mx <- as.matrix(dx) # 1. Create a positive-definite state noise covariance matrix (Q) # This captures dependencies between the trends of different variables Q_base <- matrix(runif(6*6, -0.005, 0.005), nrow=6) Q_cov <- t(Q_base) %*% Q_base + diag(0.01, 6) # Ensure matrix is positive-definite Q_mat <- array(Q_cov, dim = c(6, 6, n)) # Replicate for time-varying (or use static if preferred) # 2. Create a positive-definite observation noise covariance matrix (H) H_base <- matrix(runif(6*6, -0.002, 0.002), nrow=6) H_cov <- t(H_base) %*% H_base + diag(0.005, 6) H_mat <- array(H_cov, dim = c(6, 6, n)) # 3. Build the multivariate model with individual trends per variable model1 <- SSModel( mx ~ SSMtrend(rep(1, 6), Q = Q_mat), # rep(1,6) = 1st-order trend for each of 6 variables H = H_mat ) dkf <- KFS(model1) dkf
Adding Covariates to Capture Dependencies
If you want to include covariates to model cross-variable relationships, you have two options:
Option 1: Fixed-Effect Covariates
Add covariates directly to the model formula (treats covariate coefficients as fixed):
# Generate example covariates dx$x1 <- rnorm(n) # Covariate 1 dx$x2 <- rnorm(n) # Covariate 2 # Create covariate matrix (exclude intercept since trend handles level) cov_matrix <- model.matrix(~ x1 + x2, data = dx)[, -1] # Build model with fixed-effect covariates model_cov_fixed <- SSModel( mx ~ cov_matrix + SSMtrend(rep(1, 6), Q = Q_mat), H = H_mat ) dkf_fixed <- KFS(model_cov_fixed) dkf_fixed
Option 2: Random-Effect Covariates
Use SSMregression to model covariate coefficients as random (great if you expect coefficients to vary over time):
# Build model with random-effect covariates model_cov_random <- SSModel( mx ~ SSMtrend(rep(1, 6), Q = Q_mat) + SSMregression(cov_matrix, Q = diag(0.01, ncol(cov_matrix))), # Q for random coefficients H = H_mat ) dkf_random <- KFS(model_cov_random) dkf_random
Key Takeaways
- Use
SSMtrend(rep(1, n_vars))to assign individual trends to each variable - Use non-diagonal
QandHmatrices to model cross-variable dependencies - Covariates can be added as fixed effects (direct formula) or random effects (
SSMregression) to enhance model performance over univariate setups
内容的提问来源于stack exchange,提问作者adam.888
相关产品推荐
相关产品推荐

