当初始曲线看起来如此接近点时,为什么 R 函数 "nls" 无法收敛?
Why can't the R function "nls" reach convergence when the initial curve looks so close to the points?
我想用第一个猜测由线表示的函数拟合以下各点:
但我收到以下错误消息:
Error in nls(y ~ A * (1 + erf(E * B * (x - C)/sqrt(2))) * dnorm(B * (x - : gradiente singular
Traceback:
1. nls(y ~ A * (1 + erf(E * B * (x - C)/sqrt(2))) * dnorm(B * (x -
. C)) + D, data = fdata, start = list(A = A0, B = B0, C = C0,
. D = D0, E = E0))
这是我的代码:
erf <- function(x) 2 * pnorm(x * sqrt(2)) - 1
x = c(0.275, 0.325, 0.375, 0.425, 0.475, 0.525, 0.575, 0.625, 0.675, 0.725, 0.775, 0.825, 0.875, 0.925, 0.975)
y = c(33, 69, 48, 57, 51, 46, 36, 42, 26, 22, 22, 18, 16, 9, 5)
plot(x, y, xlim=c(0,1))
fdata = data.frame(x = x, y = y)
# Initial parameter values:
A0 = 1.3*max(y); B0 = 3.8*max(x); C0 = 1.0*x[which.max(y)]; D0 = 0.0; E0 = 4.0
# Plot curve with initial parameter values:
xfit0 = seq(from=0.0, to=1.0, length.out=100)
yfit0 = A0*(1+erf(E0*B0*(xfit0-C0)/sqrt(2)))*dnorm(B0*(xfit0-C0))+D0
lines(xfit0, yfit0, lwd=3)
# Do the fit:
fit <- nls(y~A*(1+erf(E*B*(x-C)/sqrt(2)))*dnorm(B*(x-C))+D, data = fdata, start = list(A = A0, B = B0, C = C0, D = D0, E = E0))
lines(fdata$x, predict(fit), col="red", lwd=2)
为什么 nls
即使对于如此接近的初始猜测也不能收敛?
没有足够的点来获得合适的拟合,尤其是在图表的某些区域。使用样条插值添加一些点,然后进行拟合。为此,请将问题中的最后两行代码替换为:
fdata.s <- spline(fdata)
fit <- nls(y~A*(1+erf(E*B*(x-C)/sqrt(2)))*dnorm(B*(x-C))+D, data = fdata.s,
start = list(A = A0, B = B0, C = C0, D = D0, E = E0))
lines(fdata.s$x, fitted(fit), col="red", lwd=2)
我想用第一个猜测由线表示的函数拟合以下各点:
但我收到以下错误消息:
Error in nls(y ~ A * (1 + erf(E * B * (x - C)/sqrt(2))) * dnorm(B * (x - : gradiente singular
Traceback:
1. nls(y ~ A * (1 + erf(E * B * (x - C)/sqrt(2))) * dnorm(B * (x -
. C)) + D, data = fdata, start = list(A = A0, B = B0, C = C0,
. D = D0, E = E0))
这是我的代码:
erf <- function(x) 2 * pnorm(x * sqrt(2)) - 1
x = c(0.275, 0.325, 0.375, 0.425, 0.475, 0.525, 0.575, 0.625, 0.675, 0.725, 0.775, 0.825, 0.875, 0.925, 0.975)
y = c(33, 69, 48, 57, 51, 46, 36, 42, 26, 22, 22, 18, 16, 9, 5)
plot(x, y, xlim=c(0,1))
fdata = data.frame(x = x, y = y)
# Initial parameter values:
A0 = 1.3*max(y); B0 = 3.8*max(x); C0 = 1.0*x[which.max(y)]; D0 = 0.0; E0 = 4.0
# Plot curve with initial parameter values:
xfit0 = seq(from=0.0, to=1.0, length.out=100)
yfit0 = A0*(1+erf(E0*B0*(xfit0-C0)/sqrt(2)))*dnorm(B0*(xfit0-C0))+D0
lines(xfit0, yfit0, lwd=3)
# Do the fit:
fit <- nls(y~A*(1+erf(E*B*(x-C)/sqrt(2)))*dnorm(B*(x-C))+D, data = fdata, start = list(A = A0, B = B0, C = C0, D = D0, E = E0))
lines(fdata$x, predict(fit), col="red", lwd=2)
为什么 nls
即使对于如此接近的初始猜测也不能收敛?
没有足够的点来获得合适的拟合,尤其是在图表的某些区域。使用样条插值添加一些点,然后进行拟合。为此,请将问题中的最后两行代码替换为:
fdata.s <- spline(fdata)
fit <- nls(y~A*(1+erf(E*B*(x-C)/sqrt(2)))*dnorm(B*(x-C))+D, data = fdata.s,
start = list(A = A0, B = B0, C = C0, D = D0, E = E0))
lines(fdata.s$x, fitted(fit), col="red", lwd=2)