我想对我的数据拟合一个有理函数:
数据:
#[doc(hidden)]
pub mod channel;
我要拟合的模型如下:
给出一组有序对(ti,yi),其中通常在每个t值处都有重复的测量,有理函数的参数可以通过非线性最小二乘估计来拟合,例如使用R中的nls方法。我们有四个参数,我们可以通过计算一阶导数来计算t的最大值。[1] 2.000000 3.000000 2.333333 1.750000 2.000000 1.833333 2.416667 1.916667 [9] 1.750000 2.166667 2.116667 1.916667 1.944444 1.611111 1.722222 1.777778 [17] 1.877778 1.944444 1.958333 1.833333 2.041667 2.020833 1.908333 1.916667 [25] 1.733333 1.833333 1.800000 1.933333 1.893333 1.866667 1.888889 1.805556 [33] 1.833333 1.847222 1.822222 1.805556 1.833333 1.904762 1.880952 1.833333 [41] 1.804762 1.809524 1.708333 1.708333 1.750000 1.708333 1.683333 1.687500 [49] 1.611111 1.666667 1.648148 1.611111 1.611111 1.611111 1.650000 1.600000 [57] 1.650000 1.625000 1.630000 1.616667 1.469697 1.560606 1.590909 1.651515 [65] 1.651515 1.651515 1.513889 1.555556 1.625000 1.638889 1.647222 1.652778 [73] 1.679487 1.717949 1.705128 1.698718.
我知道我首先必须为nls提供a,b,c ...的起始列表,但我真的不知道如何设置参数。由于我不是专家,因此在此http://www.css.cornell.edu/faculty/dgr2/teach/R/R_rat.pdf文档中找到了有用的指南。但在某些时候它说:
尽管我不报告其他数据,但我还有另一列代表时间(从1:76表示年份的整数)。
有人可以帮助我吗?
最佳
E。
答案 0 :(得分:3)
问题中未完全指定模型,但假设下面的代码中的模型以及下面的注释2中可重复显示的数据,如果我们将c = d = 0设置为线性模型,则可以使用以下公式中的系数线性模型适合作为初始值:
fm1 <- lm(y ~ t)
st2 <- list(a = coef(fm1)[[1]], b = coef(fm1)[[2]], c = 0, d = 0)
fm2 <- nls(y ~ Model(t, a, b, c, d), start = st2)
给予:
> fm2
Nonlinear regression model
model: y ~ Model(t, a, b, c, d)
data: parent.frame()
a b c d
2.5097712 0.6038808 0.3205409 0.0008663
residual sum-of-squares: 1.684
Number of iterations to convergence: 16
Achieved convergence tolerance: 8.029e-06
以图形方式查看适合度:
# model is shown in red. See Note 1 for fm4 (blue) and fm5 (green) models.
plot(y ~ t)
lines(fitted(fm2) ~ t, col = "red")
lines(fitted(fm4) ~ t, col = "blue")
lines(fitted(fm5) ~ t, col = "green")
legend("topright", c("fm2", "fm4", "fm5"), col = c("red", "blue", "green"), lty = 1)
以下是一个几乎适合的不同模型,但仅使用3个参数。参见上方图表中的蓝线。
fm3 <- lm(log(y) ~ log(t))
st4 <- list(a = coef(fm3)[[1]], b = 0, c = coef(fm3)[[2]])
fm4 <- nls(y ~ exp(a + b/t + c*log(t)), start = st4)
> fm4
Nonlinear regression model
model: y ~ exp(a + b/t + c * log(t))
data: parent.frame()
a b c
0.9845 -0.1767 -0.1157
residual sum-of-squares: 1.685
Number of iterations to convergence: 4
Achieved convergence tolerance: 2.625e-06
这个模型也不错。它仅使用两个参数,它们是线性的,并且其残差平方和为1.728837,而fm2模型为1.684,fm4模型为1.685。参见上方图表中的绿线。
fm5 <- lm(y ~ log(t))
> fm5
Call:
lm(formula = y ~ log(t))
Coefficients:
(Intercept) log(t)
2.4029 -0.1793
> deviance(fm5)
[1] 1.728837
y <- c(2, 3, 2.333333, 1.75, 2, 1.833333, 2.416667, 1.916667, 1.75,
2.166667, 2.116667, 1.916667, 1.944444, 1.611111, 1.722222, 1.777778,
1.877778, 1.944444, 1.958333, 1.833333, 2.041667, 2.020833, 1.908333,
1.916667, 1.733333, 1.833333, 1.8, 1.933333, 1.893333, 1.866667,
1.888889, 1.805556, 1.833333, 1.847222, 1.822222, 1.805556, 1.833333,
1.904762, 1.880952, 1.833333, 1.804762, 1.809524, 1.708333, 1.708333,
1.75, 1.708333, 1.683333, 1.6875, 1.611111, 1.666667, 1.648148,
1.611111, 1.611111, 1.611111, 1.65, 1.6, 1.65, 1.625, 1.63, 1.616667,
1.469697, 1.560606, 1.590909, 1.651515, 1.651515, 1.651515, 1.513889,
1.555556, 1.625, 1.638889, 1.647222, 1.652778, 1.679487, 1.717949,
1.705128, 1.698718)
t <- seq_along(y)
答案 1 :(得分:0)
我相信您可以做类似的事情
nls(y ~ (a1 + b1*times) / (1 + c1*times + d1*times^2))
其中y
是您上面提供的数据,times=1:76
是您提供的数据。我在参数中添加了1
,因为nls
不能将c
识别为参数,而可以识别为功能c()
。
但是,当我运行此命令时,出现错误singular gradient
,并建议将起始值初始化为1
以外的其他值(默认值)。您可以使用参数start = list("a1"=0.1, "b1"=0.1, "c1"=0.1, "d1"=0.1)
指定起始值,但这似乎无济于事。也许您对初始值应该是一个更好的主意?