问题在于起始值。我们展示了两种方法以及一种替代方案,即使使用问题中的起始值也会收敛。
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")
(图表后继续)![屏幕截图](https://istack.dev59.com/J7XQB.webp)
2) 平均值 或者,对于 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
设为 mean(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
start = list(Q = 300, b = 1)
。 - Marat Talipov