【问题标题】:R: Confidence intervals on non-linear fit with a non-analytic modelR:使用非分析模型进行非线性拟合的置信区间
【发布时间】:2018-01-11 01:26:26
【问题描述】:

我需要用非分析模型拟合 x-y 数据。我有一个函数f(x) 以数值方式计算每个x 的模型,但没有解析方程。为了拟合,我在 R 中使用optim。我最小化模型和数据之间的 RMS。它运行良好并返回合理的参数。

我想找到最佳拟合参数的置信区间(或至少是标准误)。我在互联网上发现这可以从 Hessian 矩阵中完成,但前提是最大化对数似然函数。我不知道该怎么做,我只有xyf(x) 从中找到RMS。唉,我没有很好的方法来估计 y 上的错误。

如何找到拟合参数的置信区间?

编辑:也许 R 中的一个示例可能有助于解释我的要求。这个例子使用了一个简单的解析函数来拟合数据,在我的真实案例中这个函数是非解析的,所以我不能使用,例如,nls

set.seed(666)

# generate data
x <- seq(100) / 100
y <- 0.5 * x + rnorm(100, sd = 0.03) + 0.2

# function to fit
f <- function(x, a, b) {
  a * x + b
}

# error function to minimise: RMS
errfun <- function(par, x, y) {
  a <- par[1]
  b <- par[2]
  err <- sqrt(sum((f(x, a, b) - y)^2))
}

# use optim to fit the model to the data
par <- c(1, 0)
res <- optim(par, errfun, gr=NULL, x, y)

# best-fitting parameters
best_a <- res$par[1]
best_b <- res$par[2]

最佳拟合参数是 a = 0.50 和 b = 0.20。我需要找到这些的 95% 置信区间。

【问题讨论】:

  • 如果没有(简单的)可能性分析表达式,您可能最好使用(非参数)引导程序。计算从 x 替换采样的许多不同 x* 的 f(x*)。
  • 如何从引导程序中找到置信区间?我的定义不是很清楚,我适合数据的函数是 f(x; a, b, c),其中 a, b 和 c 是模型参数。
  • 我已经把它变成了一个完整的答案。希望这更有帮助(假设您使用标准符号 y 作为结果,x 作为数据,f(x) 是某种估计器,a,b,c 是独立模型参数(例如迭代次数)不依赖于x)。

标签: r non-linear-regression


【解决方案1】:

这是引导程序的工作:

(1) 创建大量合成数据集x*。这些是通过从x 采样创建的,并替换与x 中相同数量的数据。例如,如果您的数据是 (1,2,3,4,5,6),那么 x* 可能是 (5,2,4,4,2,3)(请注意,值可能会出现多次,或者根本不会出现,因为我们正在采样替换)

(2) 对于每个x*,计算f(x*)。如果还有其他不依赖于数据的参数,请不要更改它们。 (所以f(x,a,b,c) 变为f(x*,a,b,c),只要a,b,c 不依赖于x。将这些数量称为f*

(3) 你可以从这些f* 中估计任何你想要的东西。如果您想要f(x) 的标准差,请取f* 的标准差。如果您想要 95% 的置信区间,请取 f* 的 2.5 到 97.5 个百分位数的范围。更正式地说,如果你想估计g(f(x)),你估计它为g(f(x*))

我应该说这是对引导程序非常实用的解释。我已经掩盖了许多理论细节,但引导程序几乎是普遍适用的(基本上只要您尝试估计的事物确实存在,通常就可以了)。

将此应用于您在代码中给出的示例:

x <- seq(100) / 100
y <- 0.5 * x + rnorm(100, sd = 0.03) + 0.2

# function to fit
f <- function(x, a, b) {
  a * x + b
}

# error function to minimise: RMS
errfun <- function(par, x, y) {
  a <- par[1]
  b <- par[2]
  err <- sqrt(sum((f(x, a, b) - y)^2))
}

# this is the part where we bootstrap
# use optim to fit the model to the data
best_a <- best_b <- numeric(10000)
for(i in 1:10000){
  j <- sample(100,replace=TRUE)
  x.boot <- x[j]; y.boot <- y[j]
par <- c(1, 0)
res <- optim(par, errfun, gr=NULL, x.boot, y.boot)

# best-fitting parameters
best_a[i] <- res$par[1]
best_b[i] <- res$par[2]
}
# now, we look at the *vector* best_a
# for example, if you want the standard deviation of a,
sd(best_a)
# or a 95% confidence interval for b,
quantile(best_b,c(0.025,0.975))

【讨论】:

  • 谢谢您,JDL。这是一个非常清楚的解释。但是,我需要拟合参数 a、b 和 c 的置信区间。也就是说,除了最适合的 a 之外,我还需要 a_lo 和 a_up,例如,a 的 95% CI。
  • 那么这些是f(x)的部分结果。通过将它们放在括号中,它们看起来像是用户指定的。 f(x) 允许包含多个元素。
  • 抱歉,我仍然看不到引导 x 如何帮助我解决问题。我扩展了问题以包含一个简单的示例。也许你可以解释一下如何在这个例子中应用引导程序。
  • 啊!我现在明白了!它从数据 (x, y) 中进行替换采样,拟合每个样本并找到参数 a* 和 b*。我在我的生活中做了很多引导,但还没有看到这种方法。但现在我发现这是完全有道理的。非常感谢您的努力!
  • 很高兴能帮上忙 :)
猜你喜欢
  • 1970-01-01
  • 2018-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-23
  • 2012-06-29
  • 1970-01-01
  • 2021-05-08
相关资源
最近更新 更多