简单的多维曲线拟合

时间:2009-02-09 18:01:36

标签: statistics regression best-fit-curve

我有一堆数据,通常是表格 a,b,c,...,y

其中y = f(a,b,c ...)

大多数是三个和四个变量,并且有10k到10M的记录。我的一般假设是它们本质上是代数的,例如:

y = P1 a ^ E1 + P2 b ^ E2 + P3 c ^ E3

不幸的是,我上次的统计分析课是在20年前。获得f近似值的最简单方法是什么?开源工具具有非常小的学习曲线(即我可以在一小时左右得到适当的近似值)是理想的。谢谢!

7 个答案:

答案 0 :(得分:12)

如果它有用,这里有一个Numpy / Scipy(Python)模板来做你想要的:

from numpy import array
from scipy.optimize import leastsq

def __residual(params, y, a, b, c):
    p0, e0, p1, e1, p2, e2 = params
    return p0 * a ** e0 + p1 * b ** e1 + p2 * c ** e2 - y

# load a, b, c
# guess initial values for p0, e0, p1, e1, p2, e2
p_opt = leastsq(__residual,  array([p0, e0, p1, e1, p2, e2]), args=(y, a, b, c))
print 'y = %f a^%f + %f b^%f %f c^%f' % map(float, p_opt)

如果你真的想了解发生了什么,你将不得不花时间来扩展某些工具或编程环境的学习曲线 - 我真的不认为有任何解决办法。人们通常不会专门编写专门的工具来执行3期权力回归等事情。

答案 1 :(得分:3)

有一个工具可以在zunzun.com处拟合1D和2D曲线,但我认为它不会超出两个变量。同样,Matlab不支持超过两个维度(据我所知)并且它当然不是免费的。

否则,您可以在Numerical Recipes中找到部分解决方案。

但正如其他海报所表明的那样,你可能至少需要一个关于你的功能模型的基本概念(希望它是线性的或者可以线性化的,在这种情况下你将拥有更多的解决方案)处置)

答案 2 :(得分:2)

数据拟合的基础包括假设解的一般形式,猜测常量的一些初始值,然后迭代以最小化猜测解的误差以找到特定解,通常在最小二乘意义上。 / p>

查看ROctave了解开源工具。它们都能够进行最小二乘分析,其中几个教程只是谷歌搜索。

编辑:用于估算二阶多项式系数的八度代码

x = 0:0.1:10;
y = 5.*x.^2 + 4.*x + 3;

% Add noise to y data
y = y + randn(size(y))*0.1;

% Estimate coefficients of polynomial
p = polyfit(x,y,2)

在我的机器上,我得到:

ans =

   5.0886   3.9050   2.9577

答案 3 :(得分:1)

你知道你想要限制多项式的能力吗?

如果没有限制,那么通过将N点与具有N个系数的多项式匹配,可以始终获得N个点的精确匹配。要做到这一点,你可以在你的方程中插入N个不同的点,产生N个方程和N个未知数(系数),然后你可以使用简单的高中代数或矩阵来求解未知数。

答案 4 :(得分:1)

我花了一个多星期的时间试图做基本上相同的事情。我尝试了一大堆优化的东西来微调系数,但基本上没有成功,然后我发现有一个封闭形式的解决方案,而且效果很好。

免责声明:我试图以固定的最大数量级拟合数据。如果您的 E1、E2 等值没有限制,那么这对您不起作用。

既然我已经花时间学习了这些东西,我实际上看到如果我理解了某些答案会给出很好的提示。距我上一次统计和线性代数课也有一段时间了。

所以如果还有其他人缺乏线性代数知识,这就是我所做的。

即使这不是您要拟合的线性函数,但事实证明这仍然是一个线性回归问题。维基百科有一篇关于线性回归的非常好的文章。我建议慢慢阅读:https://en.wikipedia.org/wiki/Linear_regression#:~:text=In%20statistics%2C%20linear%20regression%20is,as%20dependent%20and%20independent%20variables)。它还链接了很多其他很好的相关文章。

如果您不知道如何使用矩阵解决简单(单变量)线性回归问题,请花点时间学习如何去做。

一旦您学会了如何进行简单的线性回归,就可以尝试一些多变量线性回归。基本上,要进行多变量线性回归,您需要创建一个 X 矩阵,其中每个输入数据项都有一行,每行包含该数据条目的所有变量值(在使用的最后一列中加上 1)对于多项式末尾的常数值(称为截距))。然后创建一个 Y 矩阵,它是一个单列,每个数据项都有一行。然后你求解 B = (XTX)-1XTY。 B 然后成为多项式的所有系数。

对于多变量多项式回归,它的想法是相同的,刚才你有一个巨大的多变量线性回归,其中每个回归量(你正在做回归的变量)是你的巨大多项式表达式的系数。

因此,如果您的输入数据如下所示:

<头>
输入 输出
a1, b1, y1
a2, b2, y2
... ...
aN, bN, yN

并且您想要拟合形式为 y = c1a^2b^2 + c2a^2b + c3a 的二阶多项式^2 + c4ab^2 + c5ab + c6a + c7b^2 + c8b + c9 ,那么您的 X 矩阵将如下所示:

<头>
a1^2*b1^2 a1^2*b1 a1^2 a1*b1^2 a1*b1 a1 b1^2 b1 1
a2^2*b2^2 a2^2*b2 a2^2 a2*b1^2 a2*b2 a2 b2^2 b2 1
... ... ... ... ... ... ... ... ...
aN^2*bN^2 aN^2*bN aN^2 aN*bN^2 aN*bN 一个N bN^2 bN 1

你的 Y 矩阵很简单:

<头>
y1
y2
...
yN

然后你做 B = (XTX)-1XTY 然后 B 等于

<头>
c1
c2
c3
c4
c5
c6
c7
c8
c9

请注意,系数的总数将为 (o + 1)V,其中 o 是多项式的阶数,V 是变量的数量,因此它增长得非常快。

如果您使用的是好的矩阵代码,那么我相信运行时复杂度将是 O(((o+1)V)3 + ((o + 1 )V)2N),其中 V 是变量的数量,o 是多项式的阶数,N 是您拥有的数据输入的数量。最初这听起来很糟糕,但在大多数情况下,o 和 V 可能不会很高,所以这只是关于 N 的线性。

请注意,如果您正在编写自己的矩阵代码,那么确保您的反演代码使用类似 LU decomposition 的内容非常重要。如果你使用简单的反演方法(就像我一开始那样)那么 ((o+1)V)3 变成 ((o+1)V )!,这更糟糕。在我做出改变之前,我预测我的 5 阶 3 变量多项式大约需要 400 谷歌千年才能完成。使用LU分解后,大约需要7秒。

另一个免责声明

这种方法要求 (XTX) 不是奇异矩阵(换句话说,它可以反转)。我的线性代数有点粗糙,所以我不知道会发生这种情况的所有情况,但我知道它发生在输入变量之间存在完美的多重共线性时。这意味着一个变量只是另一个因子乘以一个常数(例如,一个输入是完成一个项目的小时数,另一个是完成一个项目的美元,但美元只是基于小时费率乘以小时数).

好消息是,当存在完美的多重共线性时,您就会知道。当您对矩阵求逆时,您最终会得到除以零或其他结果。

更大的问题是当你有不完美的多重共线性时。那时你有两个密切相关但不完全相关的变量(例如温度和高度,或速度和马赫数)。在这些情况下,这种方法在理论上仍然有效,但它变得非常敏感,以至于小的浮点错误可能导致结果偏离。

然而,根据我的观察,结果要么真的好,要么很差,所以你可以为你的均方误差设置一些阈值,如果超过这个阈值,然后说“无法计算多项式”。

>

答案 5 :(得分:0)

如果你猜测f的形式,[*]你需要一个最小化器来找到最佳参数。 The tools Scottie T suggests会像ROOT和其他许多人一样工作。

如果你不知道f可能会采取什么形式,你确实会陷入深深的麻烦。


[*]也就是说,你知道

f = f(x,y,z,w,...; p1,p2,p3 ......)

其中p是参数,坐标为xy ......

答案 6 :(得分:0)

简答:这不是那么简单。考虑数据子集的非参数方法。

您需要决定两个主要问题(1)您是否真正关心函数的参数,即您的P1,E1,......,或者您只需估算平均函数就可以了(2) )你真的需要估算所有数据的功能吗?

我要提到的第一件事是你的指定函数是非线性的(在要估计的参数中),所以普通的最小二乘法不起作用。让我们假装你指定了一个线性函数。你仍然有10M值的问题。线性回归可以使用QR分解以有效的方式执行,但您仍然使用O(p * n ^ 2)算法,其中p是您尝试估计的参数数量。如果你想估计非线性平均函数,它会变得更糟。

您能够在如此大的数据集中估算任何内容的唯一方法是使用子集来执行估算。基本上,您随机选择一个子集并使用它来估计函数。

如果您不关心参数值,并且只想估算平均函数,那么使用非参数估计技术可能会更好。

希望这有帮助。

雷夫