问题是起始值。我们展示了两种方法,以及一种即使使用问题中的起始值也能收敛的替代方法。
1) plinear右手边在 Q*b 中是线性的,所以最好将 b 吸收到 Q 中,然后我们有一个线性输入的参数,这样更容易求解。同样对于 plinear 算法,线性参数不需要起始值,因此只需要指定 b 的起始值。对于 plinear,nls 公式的右侧应指定为乘以线性参数的向量。下面给出的运行 nls 的结果fm0
将是命名的系数b
,.lin
其中 Q = .lin / b。
我们已经得到了答案,fm0
但是如果我们想要一个干净的运行,b
而Q
不是b
,.lin
我们可以使用由返回的系数隐含的起始值运行问题中的原始公式,fm0
如图所示。
fm0 <- nls(Y ~ X/(1+b*X), Data, start = list(b = 0.5), alg = "plinear")
st <- with(as.list(coef(fm0)), list(b = b, Q = .lin/b))
fm <- nls(Y ~ Q*b*X/(1+b*X), Data, start = st)
fm
给予
Nonlinear regression model
model: Y ~ Q * b * X/(1 + b * X)
data: Data
b Q
0.0721 366.2778
residual sum-of-squares: 920.6
Number of iterations to convergence: 0
Achieved convergence tolerance: 9.611e-07
我们可以显示结果。点是数据,红线是拟合曲线。
plot(Data)
lines(fitted(fm) ~ X, Data, col = "red")
(情节后继续)
2) mean或者,对 Q 使用 mean(Data$Y) 的起始值似乎效果很好。
nls(Y ~ Q*b*X/(1+b*X), Data, start = list(b = 0.5, Q = mean(Data$Y)))
给予:
Nonlinear regression model
model: Y ~ Q * b * X/(1 + b * X)
data: Data
b Q
0.0721 366.2779
residual sum-of-squares: 920.6
Number of iterations to convergence: 6
Achieved convergence tolerance: 5.818e-06
这个问题已经有一个我们使用的合理的起始值,b
但是如果需要一个可以设置Y
为,Q*b
以便它们取消并X
表示(Data$X)并求解b
作为b = 1 - 1/mean(Data$X)
可能的起始值。b
虽然没有显示使用这个起始值mean(Data$Y)
作为起始值,但Q
也导致收敛。
3) optim 如果我们使用optim
算法,即使使用问题中使用的初始值也会收敛。我们形成残差平方和并最小化:
rss <- function(p) {
Q <- p[1]
b <- p[2]
with(Data, sum((Y - b*Q*X/(1+b*X))^2))
}
optim(c(1, 0.5), rss)
给予:
$par
[1] 366.27028219 0.07213613
$value
[1] 920.62
$counts
function gradient
249 NA
$convergence
[1] 0
$message
NULL