Ниже мы покажем 2 подхода к этому.Если вы хотите сделать это автоматически, вы можете попробовать выполнить прямую подгонку, а если это не удастся, то попробовать (2), а если это не удастся, попробовать (1).Если все они терпят неудачу, тогда данные могут не соответствовать модели и не должны соответствовать ей.
Еще одна возможность, которая может избежать итеративных попыток использования различных методов, если все данные достаточно похожи, состоит в том, чтобы соответствовать всемсначала данные, а затем подгонять каждый набор данных, используя начальные значения из этого.Об этом см. (3).
1) Если вы сначала добавите больше точек, выполнив подбор сплайна, то он сходится:
sp <- with(bad_data, spline(x, y))
fit2sp <- nls(y ~ SSasymp(x, Asym, R0, lrc), data = sp)
fit2sp
, давая:
Nonlinear regression model
model: y ~ SSasymp(x, Asym, R0, lrc)
data: sp
Asym R0 lrc
5.0101 22.1915 -0.2958
residual sum-of-squares: 5.365
Number of iterations to convergence: 0
Achieved convergence tolerance: 1.442e-06
2) Другой подход, если данные похожи, состоит в использовании начальных значений из предыдущего успешного подбора.
fit1 <- nls(y ~ SSasymp(x, Asym, R0, lrc), data = good_data)
fit2 <- nls(y ~ SSasymp(x, Asym, R0, lrc), data = bad_data, start = coef(fit1))
fit2
, дающий:
Nonlinear regression model
model: y ~ SSasymp(x, Asym, R0, lrc)
data: bad_data
Asym R0 lrc
4.9379 15.5472 -0.7369
residual sum-of-squares: 2.245
Number of iterations to convergence: 10
Achieved convergence tolerance: 7.456e-06
Ниже мы приведем оба решения:
plot(y ~ x, bad_data)
points(y ~ x, sp, pch = 20)
lines(fitted(fit2sp) ~ x, sp, col = "red")
lines(fitted(fit2) ~ x, bad_data, col = "blue", lty = 2)
legend("topright", c("data", "spline", "fit2sp", "fit2"),
pch = c(1, 20, NA, NA), lty = c(NA, NA, 1, 2),
col = c("black", "black", "red", "blue"))
3) Другой подход, который может работать, если вседанные достаточно похожи, чтобы соответствовать всем данным, а затем отдельные наборы данных, используя начальные значения из всех данных.
all_data <- rbind(good_data, bad_data)
fitall <- nls(y ~ SSasymp(x, Asym, R0, lrc), data = all_data)
fit1a <- nls(y ~ SSasymp(x, Asym, R0, lrc), data = good_data, start = coef(fitall))
fit2a <- nls(y ~ SSasymp(x, Asym, R0, lrc), data = bad_data, start = coef(fitall))