R 将曲线拟合到数据集时出现问题

R 将曲线拟合到数据集时出现问题,r,math,regression,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,

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

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) 
这是用指数曲线(粉红色)和四阶多项式(红色)绘制的数据。当四阶拟合时,指数曲线有相当大的误差,但是你不能使用它进行外推,当应用到类似的数据集时,它并不总是有效的

对于我正在进行的工作,我真的需要一些完全符合曲线的东西,但我还没有想出如何做到这一点。谢谢


黄土回归似乎很好地利用了这些数据

plot(y~x)

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

lines(x, pr, col = "red", lwd = 2)
绘图(y~x)

ls看起来四阶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)
库(“样条线”)

m0外推危险的客观教训

在缺乏理论模型的情况下,使用逻辑函数(
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")


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

双对数曲线图往往会显示大值的线性行为(即幂律),随后会混合成更陡的斜率。看起来你可以把这个图建模为一条直线加上一个指数,但是右边的外推是不确定的

这个模型是

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


你可以试试:
lm(log(y)~x)
如果我没有弄错的话,那不是指数曲线的对数变换吗?看看
log(y)
vs
x
,我会对任何比指数/
log(y)更复杂的模型极度怀疑~x
。关于接近投票的猜测:要求一种完全适合并可用于外推的方法确实是不可能的。感谢您以易于导入的格式提供您的数据。这非常适合,但是似乎没有一种方法可以从黄土函数中得到数学表示,你需要数学表示有什么具体的原因吗?除非你对生成这些数据的过程有一个具体的想法,否则我不太确定这会增加什么。在任何情况下都可以使用预测函数进行插值。这条曲线是一个更大问题的一部分。我需要这个表示来解决这个问题。因为它是数据中的关键关系之一。谢谢。使用黄土的好处是它是非参数的。不是说这是世界问题的解决方案,但如果你没有数据背后的理论模型,那么这可能是一种更安全的方法,具有不依赖特定函数拟合数据的优势。但是,您仍然可以进行插值/外推,如果您确实需要一个方程,那么它不是一个好的解决方案(但请参阅@jlhoward answer,它很好地说明了为什么假设一个特定的方程而没有理由这样做是不好的)。
log(y) = a.log(x) + b - c.d^log(x)
y = A.x^B.exp(-C.x^D)