问题
I noticed that I can fit parameter vector, as below, using nls
. This let's me decide the number of parameters I want to fit. As in the example below; where I am fitting y = k + a_1 x^2 + a_2 x^3 + a_3 x^3
. I can simply change the number of initial values, which change the number of co-efficients to estimate.
But, this approach doesn't work with nls2
. It just treats fits the y = k + a_1 * x
, three times!
My questions is how to get nls2
to determine the number of parameters to fit based on the initial values - or something similar - as in the case with nls
.
I don't have a lot of experience with nls
or similar packages. So, I am trying to mend that. I am guessing nls2
has more capabilities than nls
...
Data and model to fit
x <- c(32,64,96,118,126,144,152.5,158)
y <- c(99.5,104.8,108.5,100,86,64,35.3,15)
model_fun <- function(x, int_sep, para) {
int_sep + rowSums(sapply(1:length(para), function(i) para[i] * x^i))
}
With nls
package
mod_nls <- nls(y ~ model_fun(x, int_sep, para),
start = list(int_sep = 0, para=c(1, 1, 1)))
mod_nls
# Nonlinear regression model
# model: y ~ model_fun(x, int_sep, para)
# data: parent.frame()
# int_sep para1 para2 para3
# 1.269e+02 -1.626e+00 2.910e-02 -1.468e-04
# residual sum-of-squares: 65.87
#
# Number of iterations to convergence: 1
# Achieved convergence tolerance: 1.732e-07
With nls2
package
mod_nls2 <- nls2(y ~ model_fun(x, int_sep, para),
start = list(int_sep = 0, para=c(1, 1, 1)))
mod_nls2
# Nonlinear regression model
# model: y ~ model_fun(x, int_sep, para)
# data: parent.frame()
# int_sep para
# 143.0438 -0.5966
# residual sum-of-squares: 3661
#
# Number of iterations to convergence: 1
# Achieved convergence tolerance: 7.602e-09
(edit: I am not interested in this particular model - it seems like an easy example)
回答1:
nls2
converts the start=
argument to a data frame internally so if you provide it in a form such that as.data.frame(as.list(start))
works (where in the example "works" means it creates a data frame with 1 row and 2 columns, one column for each of the two parameters -- note that data frame columns can hold complex objects) then you should be OK:
nls2(y ~ model_fun(x, int_sep, para),
start = list(int_sep = 0, para = I(t(c(1, 1, 1)))))
回答2:
You don't need to guess regarding the capabilities of nls2
. Read the documentation. You could report this issue on the package bug tracker, but I suspect @G.Grothendieck won't fix it unless you provide the fix.
Anyway, I would change your function.
model_fun <- function(x, int_sep, ...) {
para <- c(...)
#I prefer matrix algebra over a loop:
int_sep + c(tcrossprod(para, outer(x, seq_along(para), "^")))
}
library(nls2)
mod_nls2 <- nls2(y ~ model_fun(x, int_sep, alpha1, alpha2, alpha3),
start = list(int_sep = 0, alpha1 = 1, alpha2 = 1, alpha3 = 1))
mod_nls2
#Nonlinear regression model
# model: y ~ model_fun(x, int_sep, alpha1, alpha2, alpha3)
# data: <environment>
# int_sep alpha1 alpha2 alpha3
# 1.269e+02 -1.626e+00 2.910e-02 -1.468e-04
# residual sum-of-squares: 65.87
#
#Number of iterations to convergence: 1
#Achieved convergence tolerance: 1.732e-07
来源:https://stackoverflow.com/questions/46986535/nls2-treats-vectored-initial-values-as-single-elements-unlike-nls