我遇到了一些相关问题(例如this,this,this和this),但这些问题都涉及到将数据拟合到已知曲线。有没有办法将给定数据拟合到未知曲线?我的意思是,给定一些数据,算法将给出一个拟合,即一个函数或一个函数的总和。我正在使用C编程,但我完全不知道如何使用gsl包执行此操作。我愿意使用任何可以(理想情况下)通过C管道输送的东西。但是,对于我应该看哪个方向的任何帮助都将非常感激。
编辑:这基本上是我收集的实验(物理)数据,因此数据将通过加性高斯分布式噪声修改一些趋势。一般来说趋势是非线性的,所以我猜一个线性回归拟合方法是不合适的。至于排序,数据是按时间排序的,因此曲线必须按此顺序排列。
答案 0 :(得分:9)
您可能在数值分析领域寻找 polynomial interpolation 。
在多项式插值中 - 给定一组点(x,y) - 您试图找到适合这些点的最佳多项式。一种方法是使用Newton interpolation,这很容易编程。
特定领域的数值分析和插值领域得到了广泛的研究,你可能会得到一个很好的上限到多项式的误差。
但请注意,因为您正在寻找最适合您数据的多项式,并且该函数实际上不是多项式 - 当您远离初始训练集时,错误的大小会消失。
另请注意,您的数据集是有限的,并且存在可以适合数据(精确或近似)的inifnite数量(实际上,不可枚举的无穷大) - 因此其中哪一个是最好的可能是特定的到你实际想要实现的目标。
如果您正在寻找适合您数据的模型,请注意线性回归和多项式插值位于比例的两端:多项式插值可能是对模型的过度拟合,而线性回归可能不适合它,究竟应该使用的是特定于案例的,并且因应用程序而异。
简单多项式插值示例:
假设我们有(0,1),(1,2),(3,10)
作为我们的数据。
我们使用newton方法得到的表 1 是:
0 | 1 | |
1 | 2 | (2-1)/(1-0)=1 |
3 | 9 | (10-2)/(3-1)=4 | (4-1)/(3-0)=1
现在,我们得到的多项式是以最后一个元素结尾的“对角线”:
1 + 1*(x-0) + 1*(x-0)(x-1) = 1 + x + x^2 - x = x^2 +1
(这与我们使用的数据完全吻合)
(1)以递归方式创建表:前两列是x,y值 - 每个下一列都基于前一列。一旦你得到它就很容易实现,完整的解释是在维基百科页面中进行牛顿插值。
答案 1 :(得分:4)
您可能希望使用(Fast)Fourier Transforms将数据转换为频域。
利用变换的结果(一组幅度,相位和频率),即使最扭曲的数据集也可以用以下形式的几个函数(harmonics)表示:
r * cos(f * t - p)
其中r是谐波幅度,f是频率,p是相位。
最后,未知数据曲线是所有谐波的总和。
我已经在R中完成了这个(你有一些例子),但我相信C有足够的工具来管理它。管道C和R也是可能的,但对它不太了解。 This可能会有所帮助。
这种方法非常适合大块数据,因为它具有以下复杂性:
1)用快速傅里叶变换(FTT)= O(n log n)
分解数据2)使用生成的组件= O(n)
构建函数答案 2 :(得分:4)
另一种选择是使用 linear regression ,但多维。
这里的诀窍是人为地生成额外的维度。您可以通过简单地在原始数据集上隐含一些函数来实现。一个常见的用法是生成多项以匹配数据,所以在这里,你所暗示的函数f(x) = x^i
适用于所有i < k
(其中k
是你想要的多项式的程度获得)。
例如,带有(0,2),(2,3)
的数据集k = 3
您将获得额外的2个维度,您的数据集将为:(0,2,4,8),(2,3,9,27)
。
线性回归算法将找到多项式a_0,a_1,...,a_k
的值p(x) = a_0 + a_1*x + ... + a_k * x^k
,与预测模型(p(x)的值)相比,该值最小化数据中每个点的误差。
现在,问题是 - 当你开始增加维度时 - 你正从欠拟合(1维线性回归)转变为过度拟合(当k==n
时,你实际上得到了多项式插值)。
要“选择”最佳k
值 - 您可以使用 cross-validation ,并根据您的十字架选择最小化错误的k
-validation。
请注意此过程可以完全自动化,您只需迭代检查所需范围 1 中的所有k
值,然后选择模型使用k
根据交叉验证最小化错误。
(1)范围可以是[1,n]
- 虽然它可能太耗费时间,但我会选择[1,sqrt(n)]
甚至是[1,log(n)]
- 但它只是一个预感