You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在R中绘制非齐次隐马尔可夫模型(NHMM)各状态的分布

绘制非齐次隐马尔可夫模型各状态分布的实现方法

你拟合的模型包含4个高斯分布的响应变量、4个隐状态,可按以下步骤提取参数并绘图:

步骤1:提取各状态的高斯分布参数

depmixS4拟合结果中高斯响应的标准差默认以对数形式存储,需转换为原始值:

library(ggplot2)
library(depmixS4)

n_states <- NHMM.fit@nstates
n_responses <- length(NHMM.fit@response)

# 构建各状态、各响应的参数表
state_params <- data.frame()
for (state in 1:n_states) {
  for (resp in 1:n_responses) {
    mean_val <- NHMM.fit@response[[state]][[resp]]@parameters$coefficients
    sd_val <- exp(NHMM.fit@response[[state]][[resp]]@parameters$sd)
    resp_name <- names(NHMM.fit@response[[state]])[resp]
    state_params <- rbind(state_params, data.frame(
      state = factor(state),
      response = resp_name,
      mean = mean_val,
      sd = sd_val
    ))
  }
}

步骤2:多响应分面绘制各状态分布

该方法可以同时展示4个响应变量下不同状态的概率密度分布:

# 生成密度计算用的网格数据
plot_data <- data.frame()
for (i in 1:nrow(state_params)) {
  param_row <- state_params[i, ]
  x_vals <- seq(param_row$mean - 3*param_row$sd, param_row$mean + 3*param_row$sd, length.out = 100)
  density_vals <- dnorm(x_vals, mean = param_row$mean, sd = param_row$sd)
  plot_data <- rbind(plot_data, data.frame(
    state = param_row$state,
    response = param_row$response,
    x = x_vals,
    density = density_vals
  ))
}

# 绘图
ggplot(plot_data, aes(x = x, y = density, color = state, fill = state)) +
  geom_line(linewidth = 1) +
  geom_area(alpha = 0.2, position = "identity") +
  facet_wrap(~response, scales = "free") +
  labs(x = "变量取值", y = "概率密度", color = "隐状态", fill = "隐状态") +
  theme_bw()

可选:单变量快速绘图(base R版本)

如果仅需快速查看单个响应的状态分布,可使用基础绘图函数实现:

# 以第一个响应变量Clust1.North为例
resp_id <- 1
state_colors <- c("#E41A1C", "#377EB8", "#4DAF4A", "#984EA3")

# 确定x轴范围
x_lim <- range(sapply(1:n_states, function(s) {
  m <- NHMM.fit@response[[s]][[resp_id]]@parameters$coefficients
  sd <- exp(NHMM.fit@response[[s]][[resp_id]]@parameters$sd)
  c(m - 3*sd, m + 3*sd)
}))

# 绘制画布
plot(NA, xlim = x_lim, ylim = c(0, max(sapply(1:n_states, function(s) {
  m <- NHMM.fit@response[[s]][[resp_id]]@parameters$coefficients
  sd <- exp(NHMM.fit@response[[s]][[resp_id]]@parameters$sd)
  dnorm(m, mean = m, sd = sd)
}))), xlab = "Clust1.North取值", ylab = "概率密度")

# 逐个添加状态分布曲线
for (s in 1:n_states) {
  m <- NHMM.fit@response[[s]][[resp_id]]@parameters$coefficients
  sd <- exp(NHMM.fit@response[[s]][[resp_id]]@parameters$sd)
  curve(dnorm(x, mean = m, sd = sd), add = TRUE, col = state_colors[s], lwd = 2)
}

# 添加图例
legend("topright", legend = paste0("状态", 1:n_states), col = state_colors, lwd = 2)

可选:双变量联合状态分布绘制

如果需要查看两个响应变量在各状态下的联合分布,可使用以下代码:

# 以Clust1.North和Clust2.North两个响应为例
target_resps <- c("Clust1.North", "Clust2.North")
target_params <- subset(state_params, response %in% target_resps)
# 转换为宽表
wide_params <- reshape(target_params, idvar = "state", timevar = "response", direction = "wide")

joint_data <- data.frame()
for (s in 1:n_states) {
  sp <- subset(wide_params, state == s)
  # 生成二维网格
  x_vals <- seq(sp$mean.Clust1.North - 3*sp$sd.Clust1.North, sp$mean.Clust1.North + 3*sp$sd.Clust1.North, length.out = 50)
  y_vals <- seq(sp$mean.Clust2.North - 3*sp$sd.Clust2.North, sp$mean.Clust2.North + 3*sp$sd.Clust2.North, length.out = 50)
  grid <- expand.grid(x = x_vals, y = y_vals)
  # 计算联合密度(depmixS4默认多响应变量独立)
  grid$density <- dnorm(grid$x, sp$mean.Clust1.North, sp$sd.Clust1.North) * dnorm(grid$y, sp$mean.Clust2.North, sp$sd.Clust2.North)
  grid$state <- factor(s)
  joint_data <- rbind(joint_data, grid)
}

# 分面绘制热力图
ggplot(joint_data, aes(x = x, y = y, fill = density)) +
  geom_tile() +
  scale_fill_viridis_c() +
  facet_wrap(~state) +
  labs(x = "Clust1.North", y = "Clust2.North", fill = "联合密度") +
  theme_bw()

内容的提问来源于stack exchange,提问作者Burcu Tezcan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 07:00:03