繁体   English   中英

查找匹配数据的曲线

[英]Finding a curve to match data

我正在寻找一个非线性曲线拟合程序(可能最有可能在R或Python中找到,但我对其他语言开放),这将采用x,y数据并拟合曲线。

我应该能够将我想要的表达式类型指定为字符串。

例子:

"A+B*x+C*x*x"
"(A+B*x+C*x*x)/(D*x+E*x*x)"
"sin(A+B*x)*exp(C+D*x)+E+F*x"

我得到的是至少常数(A,B,C等)的值,并希望有关比赛适合度的统计数据。

有商业程序可以做到这一点,但我希望能够找到适合现在语言库中所需表达式的常用内容。 我怀疑SciPy的优化能力可能会做到这一点,但我看不出它让我定义了一个等式。 同样,我似乎无法在R中找到我想要的东西。

我正在寻找那里,还是我需要自己动手? 我讨厌这样做,如果它在那里,我只是找不到它。


编辑:我想这样做是为了更多地控制过程,而不是从LAB Fit获得。 LAB Fit UI非常糟糕。 我也希望能够将范围分成多个部分,并且不同的曲线代表范围的不同部分。 最后,结果必须能够(速度)用线性插值击败LUT,或者我不感兴趣。

在我当前的一组问题中,我有trig函数或exp(),我需要实时执行它们每秒352,800次(并且只使用一小部分CPU)。 因此,我绘制曲线并使用数据来驱动曲线拟合器以获得更便宜的近似值。 在过去,LUT几乎总是解决方案,但现在跳过内存查找并进行近似有时会更快。

您的第一个模型在三个参数中实际上是线性的 ,并且可以适合R使用

 fit <- lm(y ~ x + I(x^2), data=X)

这将为您提供三个参数。

第二个模型也可以使用R中的nls()进行拟合,并且通常需要提供起始值等。优化中的统计问题不一定与数值问题相同 - 您无论如何都不能优化任何函数形式你选择哪种语言。

为了回答一般意义上的问题(关于R中的参数估计)而不考虑你指出的方程的细节,我认为你正在寻找nls()或optim()......'nls'是我的第一选择它为每个估计参数提供误差估计,当它失败时,我使用'optim'。 如果你有x,y变量:

out <- tryCatch(nls( y ~ A+B*x+C*x*x, data = data.frame(x,y), 
                start = c(A=0,B=1,C=1) ) ,
                error=function(e) 
                optim( c(A=0,B=1,C=1), function(p,x,y)  
                      sum((y-with(as.list(p),A + B*x + C*x^2))^2), x=x, y=y) )

获得系数,类似于

getcoef <- function(x) if(class(x)=="nls") coef(x) else x$par
getcoef(out)

如果你想要'nls'的标准错误,

summary(out)$parameters

帮助文件和r-help邮件列表帖子包含许多关于每个实现的特定最小化算法的讨论(上面每个示例案例中使用的默认值)以及它们对于手头等式的特定形式的适当性。 某些算法可以处理框约束,另一个名为constrOptim()的函数将处理一组线性约束。 本网站也可能有所帮助:

http://cran.r-project.org/web/views/Optimization.html

查看GNU Octave - 在其polyfit()和非线性约束求解器之间,应该可以构造适合您的问题的东西。

您可能不会找到具有示例中隐含的灵活性的单个例程(使用相同例程的多项式和有理函数),更不用说解析字符串以找出适合的方程式。

最小二乘多项式拟合器适用于您的第一个示例。 (这取决于你使用多项式的多项式 - 四次,立方,四次等)。 对于像第二个例子这样的理性函数,如果找不到合适的库,则可能需要“自己动手”。 另外,请记住,只要您不需要推断超出您所适合的数据集的限制,就可以使用足够高度的多项式来逼近“实际”函数。

正如其他人所指出的那样,还有其他更通用的参数估计算法也可能证明是有用的。 但这些算法并不是“即插即用”:它们通常要求您编写一些辅助例程,并提供模型参数的初始值列表。 对于不幸的初始参数估计选择,这些类型的算法可能会发散,或者陷入局部最小值或最大值。

在R中,这很容易。

内置方法称为optim()。 它将参数作为潜在参数的起始向量,然后是函数。 你必须构建自己的错误函数,但这非常简单。

然后你称之为out = optim(1,err_fn)

其中err_fn是

err_fn = function(A) {
    diff = 0;
    for(i in 1:data_length){
      x = eckses[i];
      y = data[i];
      model_y = A*x;
      diff = diff + ( y - model_y )^2
    }
    return(diff);
}

这只是假设你在eckses和数据中有一个x和y值的向量。 根据需要更改model_y行,甚至添加更多参数。

它非常适用于非线性,我将它用于四维e ^ x曲线并且它非常快。 输出数据包括拟合结束时的误差值,它是衡量其拟合程度的指标,以平方差的总和(在我的err_fn中)给出。

编辑:如果您需要将模型作为字符串接收,您可以让您的用户界面将整个模型拟合过程构​​建为R脚本并加载它以运行。 R可以从STDIN或文件中获取文本,因此创建此函数的字符串等效项并不难,并让它自动运行。

如果你对你的系数有约束,并且你知道你想要适合你的数据的特定类型的函数,并且该函数是一个混乱的,其中标准回归方法或其他曲线拟合方法将不起作用,你考虑过遗传算法?

它们不是我的第一选择,但是如果你试图找到你提到的第二个函数的系数,那么也许GA会起作用 - 特别是如果你使用非标准度量来评估最佳拟合。 例如,如果你想找到系数“(A + Bx + Cx ^ 2)/(Dx + Ex ^ 2)”,那么你的函数和数据之间的平方差之和是最小的并且存在一些约束在得到的函数的arclength上,随机算法可能是解决这个问题的好方法。

一些警告:1)随机算法不能保证最佳解决方案,但它们往往非常接近。 2)你必须要小心算法的稳定性。

更长一点,如果您正处于想要从最适合您数据的某些功能空间中找到函数的阶段(例如,您不打算对数据强加第二个模型),那么遗传编程技术也可能有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM