【问题标题】:How to predict out-of-sample observations with depmixS4 package in R?如何使用 R 中的 depmixS4 包预测样本外观察结果?
【发布时间】:2021-03-26 14:35:17
【问题描述】:

我有一系列单变量数据,我想使用 R 上的 depmixS4 包在其上拟合隐马尔可夫模型。我的最终目标是预测下一个 k data 系列的观察结果(假设 k = 10)。我对预测新状态并不真正感兴趣(这很重要,但不是我的最终目标),但我想预测数据系列的下一个值。

这是一段sn-p代码:

# My series
data = rnorm(10000)
df_1_col = data.frame(data)
colnames(df_1_col) <- c('obs')

# Model
mod <- depmix(obs ~ 1, data = draws, nstates = n_state)
fit.mod <- fit(mod)

此时我不知道如何预测下一个样本外值。我想要类似于 forecast 包中的 forecast 函数的东西。

我尝试使用以下代码:

state_ests <- posterior(fit.mod)
pred_resp <- matrix(0, ncol = n_state, nrow = 10)

for(i in 1:n_state) {
  pred_resp[,i] <- predict(fit.mod@response[[i]][[1]])
}

使用此代码,predict 函数会生成多个预测值,这些预测值等于对data 的观察次数,因此它是不正确的。

我怎样才能做这个非常基本的操作?我是 HMM 的新手,但我已经尝试查看许多资源,但没有找到任何信息。谢谢:)

【问题讨论】:

    标签: r time-series prediction hidden-markov-models


    【解决方案1】:

    像您调用的库一样,经常使用的 HMM 通常是一对一的。一对一,我的意思是:您已经注意到预测序列长度与输入(观察)长度相同。

    图来自Andrej Karpathy

    对于一对多,您可能想尝试 LSTMs,它适用于 one[input]-to-many[output]、many[input]-to-[many]输出等。这应该允许您进行一些短期预测。有很多答案 (like this one) 可以直观地说明这可能是如何工作的。如果您不想使用深度学习模型,也许可以看看 卡尔曼滤波器

    【讨论】:

    • 我对使用深度学习模型不感兴趣。我的问题更侧重于如何使用“经典”模型预测时间序列场景中的值
    • 我明白了。 HMM 可能不是您预测的最佳模型。 Kalyan 过滤器可能更合适。
    【解决方案2】:

    隐马尔可夫模型以隐状态为条件对观察到的变量进行建模。因此,预测观察到的变量需要一个预测隐藏状态的中间步骤。一旦你有了隐藏状态的预测概率,你就可以从观察变量的边际分布中预测观察变量,例如

    P(Y[T+k]|Y[1:T]) = \sum_i P(Y[T+k]|S[T+k] = i) * P(S[T+k] = i|Y[1:T])

    您可以通过将 P(S[T]|Y[1:T]) 与状态转移矩阵相乘来获得预测的状态分布。

    library(depmixS4)
    
    n_state <- 2
    
    # My series
    draws <- data.frame(obs=rnorm(10000))
    
    # Model
    mod <- depmix(obs ~ 1, data = draws, nstates = n_state, stationary=TRUE)
    fit.mod <- fit(mod)
    
    # extract the state-transition matrix
    transition_mat <- rbind(getpars(getmodel(fit.mod,"transition",1)),getpars(getmodel(fit.mod,"transition",2)))
    
    # extract the probability of the states at the final time point in the data (t=T)
    # this will act as a "prior" to compute the forecasted state distributions
    prior_vec <- as.numeric(posterior(fit.mod)[1000,-1])
    
    # state-wise predictions for the observed variables
    pred_r_by_state <- c(getpars(getmodel(fit.mod,"response",1))[1],
                         getpars(getmodel(fit.mod,"response",2))[1])
    
    # for T + 1
    # the forecasted state distribution is (prior_vec %*% transition_mat)
    # so hence the prediction of the observed variable is
    sum(pred_r_by_state * (prior_vec %*% transition_mat))
    
    # for T + 2
    # the forecasted state distribution is (prior_vec %*% transition_mat %*% transition_mat)
    # so hence the prediction of the observed variable is
    sum(pred_r_by_state * (prior_vec %*% transition_mat %*% transition_mat))
    
    # for T + 3
    sum(pred_r_by_state * (prior_vec %*% transition_mat %*% transition_mat %*% transition_mat))
    
    # etc
    

    您可能想要使用包含%^% 运算符的expm 包,因此您可以使用

    transition_mat %^% 3 
    

    而不是

    transition_mat %*% transition_mat %*% transition_mat
    

    如果模型在观察到的预测变量的模型中包含协变量,您还需要考虑这些变量,即在计算 pred_r_by_state 时尝试以某种方式预测这些变量的值。

    【讨论】:

    • 太好了,非常感谢!当您拨打pred_by_r_state 时,您基本上使用的是一个非常简单的模型。有没有办法在每个州内使用类似 Arima 模型的东西?
    猜你喜欢
    • 2015-08-22
    • 2020-05-23
    • 1970-01-01
    • 1970-01-01
    • 2018-08-26
    • 1970-01-01
    • 1970-01-01
    • 2021-10-26
    • 2018-06-12
    相关资源
    最近更新 更多