Il s'agit de ma première tentative d'ajustement d'un modèle non linéaire dans R, alors soyez indulgent avec moi.
Problème
J'essaie de comprendre pourquoi nls()
me donne cette erreur :
Error in nlsModel(formula, mf, start, wts): singular gradient matrix at initial parameter estimates
Hypothèses
D'après ce que j'ai lu dans d'autres questions ici à SO, cela pourrait être soit parce que :
- mon modèle est discontinu, ou
- mon modèle est surdéterminé, ou
- mauvais choix des valeurs des paramètres de départ
J'appelle donc à l'aide pour savoir comment surmonter cette erreur. Puis-je changer le modèle et continuer à utiliser nls()
ou dois-je utiliser nls.lm
de la minpack.lm
paquet, comme je l'ai lu ailleurs ?
Mon approche
Voici quelques détails sur le modèle :
- le modèle est une fonction discontinue, une sorte de escalier type de fonction (voir le graphique ci-dessous)
- en général, le nombre de étapes dans le modèle peuvent être variables, mais elles sont fixes pour un événement d'ajustement spécifique.
MWE qui montre le problème
Brève explication du code MWE
-
step_fn(x, min = 0, max = 1)
: fonction qui renvoie1
dans l'intervalle (min
,max
] et0
autrement ; désolé pour le nom, je réalise maintenant que ce n'est pas vraiment une fonction d'étape...interval_fn()
serait plus approprié, je suppose. -
staircase(x, dx, dy)
: une somme destep_fn()
fonctions.dx
est un vecteur de largeurs pour les étapes c'est-à-diremax - min
ydy
est l'augmentation dey
pour chaque étape . -
staircase_formula(n = 1L)
: génère unformula
qui représente le modèle modélisé par la fonctionstaircase()
(à utiliser avec lenls()
fonction). - veuillez noter que j'utilise le
purrr
yglue
dans l'exemple ci-dessous.
Code
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
Toute aide est la bienvenue.