麻烦拟合曲线到数据集

时间:2015-09-15 21:07:35

标签: r math regression

在过去的两天里,我一直试图将曲线拟合到以下数据集中。正如您所看到的(从图像中)数据本身形成了近乎完美的曲线,但我还没有找到一种方法来数学表示插值和外推的数据。

y = c(0.2966, 0.2793, 0.2147, 0.1523, 0.1177, 0.1026, 0.0934, 0.0767, 
 0.0729, 0.0693, 0.0658, 0.0624, 0.0561, 0.0502, 0.0424, 0.04, 0.0356, 
 0.0335, 0.0316, 0.0279, 0.0231, 0.0217, 0.0203, 0.019, 0.02, 0.016, 
 0.0151, 0.0134, 0.0127, 0.0119, 0.0113, 0.0106, 0.01, 0.0094, 0.0089,
  0.0084, 0.0074, 0.007, 0.0062, 0.0059, 0.0053, 0.0048, 0.0043, 
  0.0041, 0.0037, 0.0033, 0.0032, 0.003, 0.0029, 0.0025, 0.0024, 
  0.0023, 0.0021, 0.002, 0.0016, 0.0016, 0.0014, 0.0012, 0.001, 
  0.0007, 0.0006, 0.0004, 0.0003)

x = c(0.77894, 0.79452, 0.85683, 0.92694, 0.97367, 0.99704, 1.01262, 
   1.04378, 1.05157, 1.05936, 1.06714, 1.07493, 1.09051, 1.10609, 
    1.12946, 1.13725, 1.15283, 1.16062, 1.16841, 1.18399, 1.20735, 
    1.21514, 1.22293, 1.23072, 1.2463, 1.25409, 1.26188, 1.27746, 
    1.28525, 1.29304, 1.30083, 1.30862, 1.3164, 1.32419, 1.33198, 
    1.33977, 1.35535, 1.36314, 1.37872, 1.38651, 1.40209, 1.41767, 
    1.43325, 1.44103, 1.45661, 1.47219, 1.47998, 1.48777, 1.49556, 
    1.51893, 1.52672, 1.53451, 1.55009, 1.55788, 1.58903, 1.59682, 
    1.6124, 1.63577, 1.67472, 1.75261, 1.79156, 1.86945, 1.92398) 

这里是用指数曲线(粉红色)和四阶多项式(红色)绘制的数据。指数曲线有相当多的误差,而第四阶适合,但你无法使用它进行外推,当应用于类似的数据集时,它并不总是有效。

对于我正在做的事情,我真的需要一些非常适合曲线的东西我还没弄明白怎么做。感谢。

enter image description here

4 个答案:

答案 0 :(得分:4)

外推危险中的对象课程。

在没有理论模型的情况下,使用逻辑函数(f1(...))或缩放的对数正态密度函数(f2(...))可以很好地拟合数据。可能还有其他功能也适合。

df <- data.frame(x,y)
library(minpack.lm)   # for nlsLM(...)

f1 <- function(x,a,b,c,d) a*exp(-(b*x))/(1+c*exp(-d*x))
fit.1 <- nlsLM(y~f1(x,a,b,c,d), df, 
               start=c(a=1, b=1, c=100, d=0), control=list(maxiter=500))
f2 <- function(x,a,m,s) a*dlnorm(x, meanlog=m, sdlog=s)
fit.2 <- nlsLM(y~f2(x,a,m,s), df, 
               start=c(a=1, m=0, s=1), control=list(maxiter=500))

plot(y~x,df)
curve(predict(fit.1,data.frame(x)),add=TRUE, col="blue")
curve(predict(fit.2,data.frame(x)),add=TRUE, col="red")

但是看看你推断会发生什么。

plot(y~x, df, xlim=c(0.5,2), ylim=c(0,.6))
curve(predict(fit.1,data.frame(x)),add=TRUE, col="blue")
curve(predict(fit.2,data.frame(x)),add=TRUE, col="red")

事实证明,实际上对数正态密度函数稍微更合适,因为残差更接近正常,尽管在两种情况下残差都有强烈的模式。关键在于,仅通过查看数据和拟合曲线,您可以接受任一函数,但它们将在外推上给出非常不同的结果,实际上两者都不是很合适。你真的需要一个理论模型。

答案 1 :(得分:2)

LOESS回归似乎与这些数据相得益彰。

plot(y~x)

ls <- loess(y~x, span = 0.5)
pr <- predict(ls, x)

lines(x, pr, col = "red", lwd = 2)

LOESS regression

答案 2 :(得分:1)

看起来四阶B样条很好:

library("splines")
m0 <- lm(y~bs(x,degree=4)) ## default: 5 df
m1 <- lm(y~bs(x,degree=4,df=6))
e1 <- glm(y~x,family=gaussian(link="log"))

par(las=1,bty="l")
plot(x,y,log="y")
lines(x,predict(m0))
lines(x,predict(m1),col=2)
lines(x,predict(e1,type="response"),col=4)

enter image description here

答案 3 :(得分:0)

bilogarithmic plot倾向于显示大值的线性行为(即幂律),后者混合到更陡峭的斜率。您似乎可以将此图形建模为直线加指数,但右侧的推断是不确定的。

enter image description here

此模型

log(y) = a.log(x) + b - c.d^log(x)

y = A.x^B.exp(-C.x^D)