我试图将多个模型拟合到相同的数据,在本例中,它是双指数方法。我尝试过观察参数,并使用强力方法(见下文。
在这种情况下,手动设置参数(黑线)似乎比暴力方法(红线)更好。我不太明白为什么会这样,因为暴力法起始值中设置的参数空间包括为手动方法设置的参数。
有人可以解释为什么暴力方法不能收敛于相同的参数,或者至少有更好的拟合吗?
此外,我能否就最适合数据的建议提供建议。我尝试过 lnorm、power、exp 和 double exp。
谢谢!
# loading packages
library(nls2)
library(tidyverse)
# example dataset
df = data.frame(
time = c(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 16, 18, 21, 23, 32, 33),
proportion = c(
1.00000000, 0.89583333, 0.77083333, 0.58333333, 0.54166667,
0.43750000, 0.35416667, 0.31250000, 0.25000000, 0.22916667,
0.16666667, 0.14583333, 0.12500000, 0.10416667, 0.08333333,
0.06250000, 0.04166667, 0.02083333, 0.00000000
)
)
# Fitting model using manual approach
manual_fit <- nls2::nls2(proportion ~ a * exp(b * time) + c * exp(d * time),
data = df,
start = list(a = 1, b = -0.1, c = 1, d = -0.5))
# setting starting parameter space for brute approach
start_values <- list(a = seq(-.5, 1.5, length.out = 10),
b = seq(-.5, 2, length.out = 10),
c = seq(-.5, 2, length.out = 10),
d = seq(-1, 2, length.out = 10))
# fitting model using brute approach
brute_fit <- nls2::nls2(proportion ~ a * exp(b * time) + c * exp(d * time),
data = df,
start = expand.grid(start_values),
control = nls.control(maxiter = 2000), algorithm = "brute-force")
# plotting to see both fits
ggplot(df) +
geom_point(aes(x = time, y = proportion), size = 3.5) +
geom_line(aes(x = time, y = predict(manual_fit)), linewidth = 1) +
geom_line(aes(x = time, y = predict(brute_fit)), linewidth = 1, colour = "red") +
ylab("Proportion > Time") +
xlab("Time (days)")
创建于 2024-07-01,使用 reprex v2.1.0
暴力算法中没有收敛的概念。 它所做的就是评估每个点的目标,然后选择最好的。它通常用于获取起始值,然后将其输入 nls。 请注意,如果给定 2 行数据框,它将为您创建网格,如下所示。
library(nls2)
fo <- proportion ~ a * exp(b * time) + c * exp(d * time)
st <- data.frame(a = c(-0.5, 1.5), b = c(-0.5, 2), c = c(-0.5, 2), d = c(-1, 2))
fm0 <- nls2(fo, df, start = st, alg = "brute", control = list(maxiter = 10^4))
fm <- nls(fo, df, start = coef(fm0))
fm
## Nonlinear regression model
## model: proportion ~ a * exp(b * time) + c * exp(d * time)
## data: df
## a b c d
## 1.00025 -0.18194 0.03566 -0.02066
## residual sum-of-squares: 0.008595
##
## Number of iterations to convergence: 10
## Achieved convergence tolerance: 6.554e-06
相反,您可以尝试线性算法,该算法可用于避免线性输入参数的起始值。 这里我们使用 p线性随机与 nls2,然后使用 p线性与 nls。
set.seed(123)
fo.p <- proportion ~ cbind(a = exp(b * time), c = exp(d * time))
fm0.p <- nls2(fo.p, df, start = st[c("b", "d")], alg = "plinear-random",
control = list(maxiter = 10^2))
fm.p <- nls(fo.p, df, start = coef(fm0.p)[c("b", "d")], alg = "plinear")
fm.p
## Nonlinear regression model
## model: proportion ~ cbind(a = exp(b * time), c = exp(d * time))
## data: df
## b d .lin.a .lin.c
## -0.02066 -0.18194 0.03566 1.00025
## residual sum-of-squares: 0.008595
##
## Number of iterations to convergence: 17
## Achieved convergence tolerance: 5.783e-06