【发布时间】:2019-05-20 03:10:14
【问题描述】:
这是我第一次尝试在 R 中拟合非线性模型,所以请多多包涵。
问题
我试图理解为什么nls() 给我这个错误:
Error in nlsModel(formula, mf, start, wts): singular gradient matrix at initial parameter estimates
假设
从我在 SO 的其他问题中读到的内容,可能是因为:
- 我的模型不连续,或者
- 我的模型过度确定,或者
- 错误的起始参数值选择
因此,我正在寻求有关如何克服此错误的帮助。我可以更改模型并仍然使用nls(),还是需要使用minpack.lm 包中的nls.lm,就像我在其他地方看到的那样?
我的方法
以下是有关模型的一些详细信息:
- 模型是一个不连续函数,一种阶梯类型的函数(见下图)
- 一般来说,模型中的步数可以是可变的,但它们对于特定的拟合事件是固定的
显示问题的 MWE
MWE代码简述
-
step_fn(x, min = 0, max = 1):在区间内返回1的函数(min,max] 和0否则;对不起这个名字,我现在意识到它不是一个真正的步进函数......interval_fn()会我猜更合适。 -
staircase(x, dx, dy):step_fn()函数的总和。dx是 steps 的宽度向量,即max - min,dy是每个 step 的y增量。 -
staircase_formula(n = 1L):生成一个formula对象,该对象表示由函数staircase()(与nls()函数一起使用)建模的模型。 - 请注意,我在下面的示例中使用了
purrr和glue包。
代码
step_fn <- function(x, min = 0, max = 1) {
y <- x
y[x > min & x <= max] <- 1
y[x <= min] <- 0
y[x > max] <- 0
return(y)
}
staircase <- function(x, dx, dy) {
max <- cumsum(dx)
min <- c(0, max[1:(length(dx)-1)])
step <- cumsum(dy)
purrr::reduce(purrr::pmap(list(min, max, step), ~ ..3 * step_fn(x, min = ..1, max = ..2)), `+`)
}
staircase_formula <- function(n = 1L) {
i <- seq_len(n)
dx <- sprintf("dx%d", i)
min <-
c('0', purrr::accumulate(dx[-n], .f = ~ paste(.x, .y, sep = " + ")))
max <- purrr::accumulate(dx, .f = ~ paste(.x, .y, sep = " + "))
lhs <- "y"
rhs <-
paste(glue::glue('dy{i} * step_fn(x, min = {min}, max = {max})'),
collapse = " + ")
sc_form <- as.formula(glue::glue("{lhs} ~ {rhs}"))
return(sc_form)
}
x <- seq(0, 10, by = 0.01)
y <- staircase(x, c(1,2,2,5), c(2,5,2,1)) + rnorm(length(x), mean = 0, sd = 0.2)
plot(x = x, y = y)
lines(x = x, y = staircase(x, dx = c(1,2,2,5), dy = c(2,5,2,1)), col="red")
my_data <- data.frame(x = x, y = y)
my_model <- staircase_formula(4)
params <- list(dx1 = 1, dx2 = 2, dx3 = 2, dx4 = 5,
dy1 = 2, dy2 = 5, dy3 = 2, dy4 = 1)
m <- nls(formula = my_model, start = params, data = my_data)
#> Error in nlsModel(formula, mf, start, wts): singular gradient matrix at initial parameter estimates
非常感谢任何帮助。
【问题讨论】:
标签: r nonlinear-optimization nls