使用numpy polyfit在python中使用polyfit和多个变量将数据拟合到曲线

有没有办法计算两个变量中多项式模型的参数.它们是独立的,因此:

z = a + bx + cx^2 + dy + ey^2

我被告知你可以使用numpy.polyfit,但它只能支持两个变量而不是我需要的三个变量.我的数据当前存储在三个numpy数组中,这样数组中每个数据的索引与其他变量中该索引处的数据相关联.即

Y = [1 2 3 4 5]
X = [3 5 7 9 11]
Z = [2 4 6 2 6]

1与3和2相关; 2与5和4相关,依此类推.
我该如何处理这个问题?

最佳答案 polyfit假设一个变量.但是,您想要做的是求解一般的线性方程组.

用线性代数表达问题

你有一个等式:

z = a + bx + cx^2 + dy + ey^2

并且观察到x,y和z的5个点.这给了我们5个方程式:

z1 = a + bx1 + cx1^2 + dy1 + ey1^2
z2 = a + bx2 + cx2^2 + dy2 + ey2^2
z3 = a + bx3 + cx3^2 + dy3 + ey3^2
z4 = a + bx4 + cx4^2 + dy4 + ey4^2
z5 = a + bx5 + cx5^2 + dy5 + ey5^2

最容易将其视为线性代数问题.我们可以将方程组重写为矩阵乘法:

|z1|   |1  x1  x1^2  y1  y1^2|   |a|
|z2|   |1  x2  x2^2  y2  y2^2|   |b|
|z3| = |1  x3  x3^2  y3  y3^2| x |c|
|z4|   |1  x4  x4^2  y4  y4^2|   |d|
|z5|   |1  x5  x5^2  y5  y5^2|   |e|

我们知道x1..5,y1..5和z1..5,但a,b,c,d,e是未知数.我们分别称这些矩阵为B,A和x:

B = A x

我们想要求解x,它是我们的a,b,c,d,e参数的矩阵.

奇异矩阵

但是,我们有一个皱纹.您为x,y和z给出的确切数字会产生A的奇异矩阵.换句话说,行不是独立的.我们有效地将两次相同的等式放入.事实上,在这个确切的情况下,我们只有3个方程式.另外两个只是前三个的组合.

没有办法用您提供的X,Y,Z数据求解方程组.

考虑到这一点,让我们改变问题,使用5个随机的x,y,z点.

准确的解决方案

在这个特定的情况下,我们有5个未知数和5个方程.因此,我们可以准确地解决这个问题(例如使用np.linalg.solve).这被称为“甚至确定的问题”.

import numpy as np
np.random.seed(1)

# Each array with have 5 random points
x, y, z = np.random.random((3, 5))

# A is going to look like:
#  |1  x1  x1^2  y1  y1^2|
#  |1  x2  x2^2  y2  y2^2|
#  |1  x3  x3^2  y3  y3^2|
#  |1  x4  x4^2  y4  y4^2|
#  |1  x5  x5^2  y5  y5^2|
A = np.column_stack([np.ones(len(x)), x, x**2, y, y**2])

# And "B" will just be our "z" array
B = z

# Now we can solve the system of equations Ax = B
a, b, c, d, e = np.linalg.solve(A, B)

超过5次观察

但是,假设我们有10次观察或100次.在这种情况下,我们有一个过分确定的问题.我们无法准确地解决它,而是需要使用最小二乘拟合.

在这种情况下,你仍然用矩阵乘法来表达事物并解决Ax = B.但是,A不是方阵.因此,我们需要使用不同的工具来解决问题.对于numpy,它是np.linalg.lstsq而不是np.linalg.solve:

我很快就会详细说明(可能会有点),但目前:

import numpy as np
np.random.seed(1)

# Each array with have 20 random points this time
x, y, z = np.random.random((3, 20))

# We're solving Ax = B
A = np.column_stack([np.ones(len(x)), x, x**2, y, y**2])
B = z

# Solve the system of equations.
result, _, _, _ = np.linalg.lstsq(A, B)
a, b, c, d, e = result

删除条款

如果你想从等式中删除bx和dy项,你可以将它们从A中删除:

import numpy as np
np.random.seed(1)

x, y, z = np.random.random((3, 20))

# Note that we've remove the `x` and `y` terms.
# We're solving `z = a + cx^2 + ey^2`
A = np.column_stack([np.ones(len(x)), x**2, y**2])
B = z

# Solve the system of equations.
result, _, _, _ = np.linalg.lstsq(A, B)
a, c, e = result
点赞