numpy拟合系数到多项式的线性组合

时间:2018-01-11 13:41:33

标签: python numpy math linear-algebra polynomials

我有想要与多项式拟合的数据。我有200,000个数据点,所以我想要一个有效的算法。我想使用numpy.polynomial包,以便我可以尝试不同的族和多项式次数。有没有什么方法可以将其表示为Ax = b等方程组?有没有比使用scipy.minimize更好的解决方法?

import numpy as np
from scipy.optimize import minimize as mini

x1 = np.random.random(2000)
x2 = np.random.random(2000)
y = 20 * np.sin(x1) + x2 - np.sin (30 * x1 - x2 / 10)
def fitness(x, degree=5):

    poly1 = np.polynomial.polynomial.polyval(x1, x[:degree])
    poly2 = np.polynomial.polynomial.polyval(x2, x[degree:])
    return np.sum((y - (poly1 + poly2)) ** 2 )

# It seems like I should be able to solve this as a system of equations
# x = np.linalg.solve(np.concatenate([x1, x2]), y)

# minimize the sum of the squared residuals to find the optimal polynomial coefficients
x = mini(fitness, np.ones(10))
print fitness(x.x)

1 个答案:

答案 0 :(得分:1)

你的直觉是正确的。您可以将此解析为 Ax = b 形式的方程组。

然而:

  • 系统过度定义,您希望获得最小二乘解决方案,因此您需要使用np.linalg.lstsq代替np.linalg.solve

  • 您不能使用polyval,因为您需要分离自变量的系数和幂。

这是如何构建方程组并解决它:

A = np.stack([x1**0, x1**1, x1**2, x1**3, x1**4, x2**0, x2**1, x2**2, x2**3, x2**4]).T             
xx = np.linalg.lstsq(A, y)[0]
print(fitness(xx))  # test the result with original fitness function

当然,你可以概括一下学位:

A = np.stack([x1**p for p in range(degree)] + [x2**p for p in range(degree)]).T

使用示例数据,最小二乘解决方案的运行速度比minimize解决方案快得多(800μs比我的笔记本电脑上的35ms)。但是,A可能变得非常大,因此如果内存有问题minimize可能仍然是一个选项。

<强>更新

在没有任何关于多项式函数内部的知识的情况下,事情变得棘手,但 可能将术语和系数分开。这是从像A这样的函数构造系统矩阵polyval的一种有点丑陋的方法:

def construct_A(valfunc, degree):
    columns1 = []
    columns2 = []
    for p in range(degree):
        c = np.zeros(degree)
        c[p] = 1
        columns1.append(valfunc(x1, c))
        columns2.append(valfunc(x2, c))
    return np.stack(columns1 + columns2).T

A = construct_A(np.polynomial.polynomial.polyval, 5)           
xx = np.linalg.lstsq(A, y)[0]
print(fitness(xx))  # test the result with original fitness function