我是R的新手,我遇到了一个我不明白的问题。我已经找到了有关R中nls功能如何工作的文档或答案,但我找不到任何东西。
Test = data.frame(x = c(5, 10, 15, 25), y = c(5, 8, 12, 16))
fun = function(x, a, b) {
cat("a =", a, ", b =", b, "\n")
a*(x**b)
}
nls(y ~ fun(x, a, b), data = Test, start = list(a = 1.613, b = 0.718), trace = TRUE)
输出如下:
a = 1.613 , b = 0.718
a = 1.613 , b = 0.718
a = 1.613 , b = 0.718
a = 1.613 , b = 0.718
0.7964401 : 1.613 0.718
a = 1.612723 , b = 0.7177708
a = 1.612723 , b = 0.7177708
a = 1.612723 , b = 0.7177708
0.7960992 : 1.6127232 0.7177708
a = 1.612698 , b = 0.7177761
a = 1.612698 , b = 0.7177761
a = 1.612698 , b = 0.7177762
0.7960992 : 1.6126980 0.7177761
Nonlinear regression model
model: y ~ fun(x, a, b)
data: Test
a b
1.6127 0.7178
residual sum-of-squares: 0.7961
Number of iterations to convergence: 2
Achieved convergence tolerance: 1.43e-06
它表示需要两次迭代才能收敛,但看起来它已经运行了10次,并且只更改了两次参数值。是否有一个原因?我无法找到nls如何计算参数猜测的解释。
我试图将600个数据点放到一个大型函数中,因此这需要花费大量额外的不必要的时间。
答案 0 :(得分:1)
在我看来,nls使用Gauss-Newton算法,它需要雅可比计算,因此您可以看到雅可比值的数值计算。
使用以下代码可以看到调用不完全相同:
Test = data.frame(x = c(5, 10, 15, 25), y = c(5, 8, 12, 16))
fun = function(x, a, b) {
cat("a =", sprintf("%0.10f",a), ", b =", sprintf("%0.10f",b), "\n")
a*(x**b)
}
nls(y ~ fun(x, a, b), data = Test, start = list(a = 1.613, b = 0.718), trace = TRUE)
它只打印更多小数。通过对所有参数进行微小的扰动来估计雅可比。
a = 1.6130000000 , b = 0.7180000000
a = 1.6130000000 , b = 0.7180000000
a = 1.6130000240 , b = 0.7180000000
a = 1.6130000000 , b = 0.7180000107
0.7964401 : 1.613 0.718
a = 1.6127231539 , b = 0.7177708205
a = 1.6127231779 , b = 0.7177708205
a = 1.6127231539 , b = 0.7177708312
0.7960992 : 1.6127232 0.7177708
a = 1.6126979985 , b = 0.7177761452
a = 1.6126980225 , b = 0.7177761452
a = 1.6126979985 , b = 0.7177761559
0.7960992 : 1.6126980 0.7177761
Nonlinear regression model
model: y ~ fun(x, a, b)
data: Test
a b
1.6127 0.7178
residual sum-of-squares: 0.7961
Number of iterations to convergence: 2
Achieved convergence tolerance: 1.43e-06
因此,这些调用对于nls计算jacobian是必须的。