DepmixS4修复状态顺序-R

我正在使用软件包depmixS4使HMM适合时间序列数据。这是一些高容量和低容量数据的示例。

在getpars函数中,我们可以看到参数值估算值。

正在发生的事情是,密度中的前两个值有时是低容量状态,有时后两个值是低容量状态。有什么办法可以解决(也许设置初始优先级?)


set.seed(1)
a <- data.frame(v1 = c(rnorm(n = 100,sd = 10),rnorm(n=100,sd = 1)))
a <- sample(a)
my_model <- depmixS4::depmix(response = v1 ~ 1,nstates = 2,data = a)
fitted_model <- depmixS4::fit(my_model)
getpars(fitted_model)

for (i in 100:200) {
  my_model2 <- depmixS4::depmix(response = v1 ~ 1,data = a[1:i,drop = FALSE])
  fitted_model2 <- depmixS4::fit(my_model2)
  pars <- getpars(fitted_model2)
  if (pars[8] > 8) {
    print(i)
  }
}

lytaianly 回答:DepmixS4修复状态顺序-R

这称为标签切换

其中交换状态标签的模型(例如,将状态1重新标​​记为状态2,将状态2重新标记为状态1)具有相同的可能性,因此都是有效的最大似然解。

您可以尝试通过以下方式“解决”此问题:

  • 设置参数的初始值(尽管不能保证,但EM算法可能会收敛到特定的解决方案!)
  • 或者通过设置顺序约束(例如,强制状态1的平均值大于状态2的平均值)。这样的约束可以提供给depmixS4中的fit方法(请参见?fit中的示例);
  • 最后一个选择是切换适合的depmixS4对象的标签。

这是一个重新标记我以前使用过的合适的depmix对象的功能(虽然测试不好!)

label_switch <- function(mod,labels) {
  # labels is vector,first element is new integer label  for original state integer 1,second is new integer label for original state integer 2,etc.
  if(!is(mod,"depmix") || !is(mod,"depmix.fitted")) stop("this function is for depmix models")
  n_states <- mod@nstates
  if(length(labels) != n_states || length(unique(labels)) != n_states || !(all(labels) %in% 1:n_states)) {
    stop("labels needs to be a vector of unique integers between 1 and",n_states)
  }
  inv_labels <- sapply(1:n_states,function(x) which(labels == x))
  tmp <- mod
  # relabel prior
  ppars <- getpars(mod@prior)
  fpars <- getpars(mod@prior,which="fixed")
  out_pars <- as.numeric(t(matrix(ppars,nrow=length(ppars)/n_states,byrow = TRUE)[,inv_labels]))
  out_fixed <- as.logical(t(matrix(fpars,nrow=length(fpars)/n_states,inv_labels]))
  if(!tmp@prior@family$link=="identity") tmp@prior@family$base <- labels[tmp@prior@family$base]
  # relabel transition
  for(i in 1:n_states) {
    ppars <- getpars(mod@transition[[inv_labels[i]]])
    fpars <- getpars(mod@transition[[inv_labels[i]]],which="fixed")
    out_pars <- c(out_pars,as.numeric(t(matrix(ppars,inv_labels])))
    out_fixed <- c(out_fixed,as.logical(t(matrix(fpars,inv_labels])))
    tmp@transition[[i]] <- mod@transition[[inv_labels[i]]]
    if(!tmp@transition[[i]]@family$link=="identity") tmp@transition[[i]]@family$base <- labels[tmp@transition[[i]]@family$base]
    #out_pars <- c(out_pars,getpars(mod@transition[[inv_labels[i]]]))
  }
  # relabel response
   for(i in 1:n_states) {
    out_pars <- c(out_pars,unlist(lapply(mod@response[[inv_labels[i]]],getpars)))
    out_fixed <- c(out_fixed,getpars,which="fixed")))
   }
  tmp <- setpars(tmp,out_fixed,which="fixed")
  tmp <- setpars(tmp,out_pars)
  if(is(tmp,"depmix.fitted")) tmp@posterior <- viterbi(tmp)
  return(tmp)
}
本文链接:https://www.f2er.com/3167280.html

大家都在问