R:用nls拟合4参数曲棍球杆曲线时遇到问题
我的数据集:R:用nls拟合4参数曲棍球杆曲线时遇到问题,r,curve-fitting,nls,R,Curve Fitting,Nls,我的数据集: mydata<-structure(list(t = c(0.208333333, 0.208333333, 0.208333333, 0.208333333, 1, 1, 1, 1, 2, 2, 2, 2, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 0.208333333, 0.208333333, 0.208333333, 0.208333333, 1, 1, 1, 1, 2, 2, 2, 2), parent
mydata<-structure(list(t = c(0.208333333, 0.208333333, 0.208333333, 0.208333333,
1, 1, 1, 1, 2, 2, 2, 2, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16,
16, 16, 0.208333333, 0.208333333, 0.208333333, 0.208333333, 1,
1, 1, 1, 2, 2, 2, 2), parent = c(1.2, 1.4, 0.53, 1.2, 1, 0.72,
0.93, 1.1, 0.88, 0.38, 0.45, 0.27, 0.057, 0.031, 0.025, 0.051,
0.027, 0.015, 0.034, 0.019, 0.017, 0.025, 0.024, 0.023, 0.29,
0.22, 0.34, 0.19, 0.12, 0.092, 0.41, 0.28, 0.064, 0.05, 0.058,
0.043)), .Names = c("t", "Ct"), row.names = c(325L, 326L,
327L, 328L, 341L, 342L, 343L, 344L, 357L, 358L, 359L, 360L, 373L,
374L, 375L, 376L, 389L, 390L, 391L, 392L, 401L, 402L, 403L, 404L,
805L, 806L, 807L, 808L, 821L, 822L, 823L, 824L, 837L, 838L, 839L,
840L), class = "data.frame")
我尝试了端口
和标准nls方法。我尝试了模型的线性化(如图所示)和正常状态,但两者似乎都不起作用
编辑:根据Carl的建议,我尝试将模型拟合到一个数据集,在该数据集中,我首先平均了每个t值的Ct值,但仍然得到了错误
编辑:稍微更改了模型,使
k2
值为正值而不是负值。负值在动力学上没有意义。我还没有完全解决nls()
问题,但我有一些建议
首先,我建议稍微修改一下曲棍球杆的功能,使其在断点处保持连续:
hockeystick<-function (t, C0, k1, k2, tb)
{
Ct <- ifelse(t <= tb, C0 -k1 * t, C0 -k1*t -k2*(t-tb))
}
我在这里把k2设为负值,所以第二阶段的下降斜率小于第一阶段
start.hockey <- c(C0=0,k1=0.8,k2=-0.7, tb=3)
nls(log(Ct)~hockeystick(t,C0,k1,k2,tb),
start=start.hockey,data=mydata)
绘图预测:
pframe <- data.frame(t=seq(0,15,length=51))
pframe$pred <- predict(m1,newdata=pframe)
with(pframe,lines(t,pred,col=2))
pframe尝试绘制hockeystick(mydata$t、C0、k1、k2、tb)
vsmydata$t
。这不是曲棍球棒。此外,重复的t
值几乎肯定会导致回归失败。因此,一般来说,我最好将回归拟合为每个t值的平均值?曲棍球杆是线性化的,因此y轴是对数单位。tb是曲棍球杆模型的“弯曲点”,即曲线改变其“下降率”的点。感谢全面的回答。是的,您从tb
修改为t-tb
是一个很大的改进。今晚晚些时候到家时,我会检查你的其余答案。你能解释一下为什么要将dnorm
函数包装在hockeystick()
周围进行估算吗?此外,对于这种特殊化合物,我可能需要获得t
的2-10范围内的数据。此外,在拟合过程中,tb
参数似乎根本没有改变。我在hockey.start中使用的任何值都保留在最终参数集中。虽然我通常可以从数据中做出有根据的猜测,但我无法将其粘贴在纸上。测试集的tb
参数确实发生了变化(请参见上面的编辑)。如果您使用的是合理的起始值,我不知道为什么优化器会卡住。我使用的是dnorm()
,因为mle2
不做最小二乘,它做一般的最大似然估计,而dnorm()
是将其等效为最小二乘拟合的一种方法。使用lm
对指定断点拟合分段线性模型,然后进行一维非线性优化(optimize
)以选择断点将更高效、更稳健。或者使用strucchange
软件包。
hockeystick<-function (t, C0, k1, k2, tb)
{
Ct <- ifelse(t <= tb, C0 -k1 * t, C0 -k1*t -k2*(t-tb))
}
par(las=1,bty="l") ## cosmetic
plot(log(Ct)~t,data=mydata)
curve(hockeystick(x,C0=0,k1=0.8,k2=-0.7, tb=3),add=TRUE)
start.hockey <- c(C0=0,k1=0.8,k2=-0.7, tb=3)
nls(log(Ct)~hockeystick(t,C0,k1,k2,tb),
start=start.hockey,data=mydata)
library(bbmle)
m1 <- mle2(log(Ct)~dnorm(hockeystick(t,C0,k1,k2,tb),
sd=exp(logsd)),
start=c(as.list(start.hockey),list(logsd=0)),
data=mydata)
coef(summary(m1))
## Estimate Std. Error z value Pr(z)
## C0 -0.4170749 0.2892128 -1.442104 1.492731e-01
## k1 0.6720120 0.2236111 3.005271 2.653439e-03
## k2 -0.5285974 0.2400605 -2.201934 2.766994e-02
## tb 2.0007688 0.1714292 11.671108 1.790751e-31
## logsd -0.2218745 0.1178580 -1.882558 5.976033e-02
pframe <- data.frame(t=seq(0,15,length=51))
pframe$pred <- predict(m1,newdata=pframe)
with(pframe,lines(t,pred,col=2))