10

我遇到了一些相关的问题(例如thisthisthisthis),但它们都涉及将数据拟合到已知曲线。有没有办法将给定的数据拟合到未知曲线?我的意思是,给定一些数据,算法会给我一个拟合,它是一个函数或函数的总和。我正在用 C 编程,但我完全不知道如何使用gsl包来做到这一点。我愿意使用任何可以(理想情况下)通过 C 管道传输的东西。但是对于我应该寻找的方向的任何帮助将不胜感激。

编辑:这基本上是我收集的实验(物理)数据,所以数据会有一些被加性高斯分布噪声修改的趋势。一般来说,趋势是非线性的,所以我猜线性回归拟合方法是不合适的。至于排序,数据是按时间排序的,因此曲线必须按该顺序拟合。

4

3 回答 3

9

您可能正在寻找数值分析领域的多项式插值。

在多项式插值中 - 给定一组点 (x,y) - 您试图找到适合这些点的最佳多项式。一种方法是使用牛顿插值法,这很容易编程。

数值分析和具体插值领域得到了广泛的研究,您可能可以获得多项式误差的一些不错的上限。

但是请注意,因为您正在寻找最适合您的数据的多项式,并且该函数并不是真正的多项式 - 当远离您的初始训练集时,错误的规模会爆炸。


另请注意,您的数据集是有限的,并且有无限数量(实际上是不可枚举的无穷大)可以拟合数据(精确或近似)的函数 - 所以其中哪一个是最好的可能特定于您实际上是在努力实现。

如果您正在寻找一个模型来拟合您的数据,请注意线性回归和多项式插值处于尺度的相反两端:多项式插值可能对模型过度拟合,而线性回归可能对其拟合不足,究竟应该怎么做be used 是针对具体情况的,并且因应用程序而异。


简单的多项式插值示例

假设我们有(0,1),(1,2),(3,10)我们的数据。

我们使用牛顿法得到的表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) 表是递归创建的:前 2 列是 x,y 值 - 下一列基于前一列。一旦你得到它就很容易实现,完整的解释在牛顿插值的维基百科页面中。

于 2013-01-01T14:03:59.220 回答
4

您可能希望使用(快速傅立叶变换将数据转换为频域。

通过变换的结果(一组幅度、相位和频率),即使是最扭曲的数据集也可以用以下形式的几个函数(谐波)表示:

r * cos(f * t - p)

其中 r 是谐波幅度,f 是频率和 p 相位。

最后,未知数据曲线是所有谐波的总和。

我在R中做过这个(你有一些例子),但我相信 C 有足够的工具来管理它。也可以对 C 和 R 进行管道传输,但对其了解不多。可能会有所帮助。

这种方法对于大块数据非常有用,因为它具有以下复杂性:

1) 使用快速傅里叶变换 (FTT) = O(n log n) 分解数据

2) 使用结果组件 = O(n) 构建函数

于 2013-01-01T14:19:05.207 回答
4

另一种选择是使用线性回归,但是是多维的

这里的技巧是人为地生成额外的维度。您可以通过简单地在原始数据集上隐含一些函数来做到这一点。一个常见的用法是生成多项式以匹配数据,因此在这里您暗示的功能f(x) = x^i适用于所有人i < kk您想要获得的多项式的度数在哪里)。

例如,(0,2),(2,3)k = 3你的数据集将获得额外的 2 个维度,你的数据集将是:(0,2,4,8),(2,3,9,27).

与预测模型(p(x) 的值)相比,线性回归算法将找到使数据中每个点的误差最小化a_0,a_1,...,a_k的多项式值。p(x) = a_0 + a_1*x + ... + a_k * x^k

现在,问题是——当你开始增加维度时——你正在从欠拟合(一维线性回归)转向过拟合(当k==n你有效地得到多项式插值时)。

要“选择”什么是最佳k值 - 您可以使用cross-validation,并k根据您的交叉验证选择最小化错误的值。

请注意,此过程可以完全自动化,您只需要迭代检查k所需范围1中的所有值,并k根据交叉验证选择误差最小的模型。


(1) 范围可能是 [1,n]——虽然它可能会太费时,但我会去[1,sqrt(n)]甚至[1,log(n)]——但这只是一种预感。

于 2013-01-01T15:24:24.447 回答