You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在R中通过最小化加权平方误差和来估计二元高斯模型的7个参数?

如何在R中通过最小化加权平方误差和来估计二元高斯模型的7个参数?

嘿,这个需求我帮你拆解一步步实现,完全在R里就能搞定,不用额外的复杂包,核心用基础函数加dplyr做数据处理,optim做优化就行。咱们一步步来:

1. 先给数据分网格(创建分组)

你提到的边界是(-2%, -1%, 0%, 1%, 2%, 3%, 4%, 5%, 6%),首先得把这些边界转成数值(假设你的ipi是百分比数值,比如-2代表-2%,如果是字符串要先转成数值)。然后用cut()函数把ipi分别分到对应的区间里,再把两个区间组合成唯一的网格分组ID。

示例代码:

# 加载dplyr方便数据处理
library(dplyr)

# 定义边界(如果你的数据超出-2到6的范围,可以在首尾加-Inf/Inf)
bins <- c(-2, -1, 0, 1, 2, 3, 4, 5, 6)

# 给i和pi分箱,生成网格分组
data <- data %>%
  mutate(
    i_bin = cut(i, breaks = bins, include.lowest = TRUE),
    pi_bin = cut(pi, breaks = bins, include.lowest = TRUE),
    grid_group = paste(i_bin, pi_bin, sep = "_")  # 生成唯一分组标识
  )

2. 计算每个网格的统计量(中位数、样本数、标准差、权重)

接下来按每个网格分组,计算你需要的所有统计量:X的中位数、i的中位数、pi的中位数、样本数、X的标准差,还有最终的权重。这里要注意处理标准差为0的情况(比如某个网格里X全相同),可以加个极小值避免除以0。

示例代码:

grid_stats <- data %>%
  group_by(grid_group) %>%
  summarise(
    X_med = median(X, na.rm = TRUE),
    i_med = median(i, na.rm = TRUE),
    pi_med = median(pi, na.rm = TRUE),
    n = n(),
    sd_X = sd(X, na.rm = TRUE),
    # 计算权重,处理sd_X为0的特殊情况
    weight = sqrt(n) / ifelse(sd_X == 0, 1e-6, sd_X)
  ) %>%
  ungroup()

# 过滤掉没有数据的空网格
grid_stats <- grid_stats %>% filter(n > 0)

3. 定义你的7参数二元高斯模型预测函数

这里关键是要把你的7参数模型写成一个函数,输入参数向量和(i_med, pi_med),输出预测的X值。因为你没写具体的模型形式,我举个常见的7参数模型例子(你需要替换成自己的实际模型逻辑):

# 示例7参数模型:请根据你的二元高斯模型修改这个函数!
# params是长度为7的向量,对应你的7个参数
model_pred <- function(params, i, pi) {
  mu1 <- params[1]   # i的均值参数
  mu2 <- params[2]   # pi的均值参数
  sigma1 <- params[3] # i的标准差参数
  sigma2 <- params[4] # pi的标准差参数
  rho <- params[5]    # 相关系数参数
  alpha <- params[6]  # 回归系数1
  beta <- params[7]   # 回归系数2
  
  # 这里写你的模型预测逻辑,示例仅作参考
  X_pred <- alpha*(i - mu1)/sigma1 + beta*(pi - mu2)/sigma2 + rho*i*pi
  return(X_pred)
}

注意:一定要把这个函数改成你实际的7参数二元高斯模型形式,这是整个流程的核心!

4. 定义加权平方误差和的目标函数

目标函数就是计算每个网格的(预测值 - X中位数)的平方乘以权重,然后求和,我们要最小化这个值:

objective_function <- function(params, grid_stats) {
  # 计算每个网格的预测值
  X_pred <- model_pred(params, grid_stats$i_med, grid_stats$pi_med)
  # 计算加权平方误差和
  weighted_sse <- sum(grid_stats$weight * (X_pred - grid_stats$X_med)^2)
  return(weighted_sse)
}

5. 用optim函数做优化求解

接下来需要给参数设置初始值,初始值的选择很重要,最好根据数据的统计量来设置(比如μ1设为i的均值,σ1设为i的标准差等)。然后调用optim()函数:

# 设置初始值(根据你的模型调整,这里是示例)
init_params <- c(
  mean(data$i, na.rm = TRUE),  # mu1初始值
  mean(data$pi, na.rm = TRUE), # mu2初始值
  sd(data$i, na.rm = TRUE),    # sigma1初始值
  sd(data$pi, na.rm = TRUE),   # sigma2初始值
  cor(data$i, data$pi, use = "complete.obs"), # rho初始值
  1,  # alpha初始值
  1   # beta初始值
)

# 运行优化,用L-BFGS-B算法支持参数约束(比如标准差必须为正,相关系数在-1到1之间)
optim_result <- optim(
  par = init_params,
  fn = objective_function,
  grid_stats = grid_stats,
  method = "L-BFGS-B",
  # 设置参数约束范围,根据你的模型调整
  lower = c(-Inf, -Inf, 1e-6, 1e-6, -0.999, -Inf, -Inf),
  upper = c(Inf, Inf, Inf, Inf, 0.999, Inf, Inf)
)

# 查看优化结果
print(optim_result)
# 提取最终估计的参数
final_params <- optim_result$par

一些实用提示

  • 如果你的模型有特定的参数约束(比如方差必须为正,相关系数在-1到1之间),一定要在optim里设置lowerupper参数,用L-BFGS-B方法支持约束优化。
  • 初始值尽量贴近真实值,否则优化可能收敛到局部最优解,可以多试几个不同的初始值看看结果是否稳定。
  • 如果你的数据里有缺失值,记得在计算统计量的时候用na.rm=TRUE处理。

备注:内容来源于stack exchange,提问作者Luca Dibo

火山引擎 最新活动