2度多变量曲线拟合

时间:2018-11-17 22:52:31

标签: python numpy scikit-learn scipy

我正在我的研究生项目中工作,在那里我有一个像这样的方程式-

fos=f(x,y)= a1+a2*x+a3*x^2+a4*y+a5*y^2

我的值为fos[]array[[x],[y]]
我需要知道使用numpy或scipy / scikit获取那些系数值的方法。我尝试在scikit中使用PolynomialFeature,但无法找到一种合适的方法来输入给定的方程式并根据这些数据计算值。

2 个答案:

答案 0 :(得分:1)

这是您问题的答案。基本上,使用numpy拟合这样的函数非常简单。我已经在下面严重地注释了代码。您可以看到,在前4个代码行中(不包括注释行和空行),我只是使要拟合的数据集通过使用X和Y拟合Z。这里Z = fos = f(x,y)。

加载数据集后,拟合数据集的第一条重要行将是XY = ...。此后,只有一行可以找到系数,然后剩下的仅是打印出来。

import numpy as np

# in these 4 lines I just create a some data
# You have your own so you can ignore them
# we have x and y and the z. z is f(x,y)

X, Y = np.meshgrid(np.linspace(0, 1, 20), np.linspace(0, 1, 20), copy=False)
X = X.flatten()
Y = Y.flatten()
Z = (X**2 + Y**2 + np.random.rand(*X.shape)*0.01).flatten()

# we want to make the function something like a1+a2*x+a3*x^2+a4*y+a5*y^2
# we will first make an array of our known variables
# we want a array of 1, x, x**2, y, y**2
# after we have this we can fit it linearly to get the coefficients a_n

XY = np.array([np.ones(X.shape), X, Y, X**2, Y, Y**2]).T

# here is where we actually fit the coefficients
coeff,_,_,_ = np.linalg.lstsq(XY, Z)

for i in range(len(coeff)):
    print('a{} = {}'.format(i, coeff[i]))

答案 1 :(得分:0)

紧随this code之后,我得到了以下内容:

from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
import numpy as np

def f(x, a1, a2, a3, a4, a5):
    return a1+a2*x[0]+a3*x[0]**2+a4*x[1]+a5*x[1]**2

limits = [-10, 10, -10, 10]  # [x1_min, x1_max, x2_min, x2_max]
side_x = np.linspace(limits[0], limits[1], 100)
side_y = np.linspace(limits[2], limits[3], 100)
X1, X2 = np.meshgrid(side_x, side_y)
size = X1.shape
X1_1d = X1.reshape((1, np.prod(size)))
X2_1d = X2.reshape((1, np.prod(size)))


xdata = np.vstack((X1_1d, X2_1d))

#Here I create some sample data
original = (1,2,3,4,5)
z = f(xdata, *original)
Z = z.reshape(size)
z_noise = z + .2*np.random.randn(len(z))
Z_noise = z_noise.reshape(size)

#For z_noise you have to plug in your data here
popt, pcov = curve_fit(f, xdata, z_noise)
print("fitted: {}".format(popt))
z_fit = f(xdata, *popt)
Z_fit = z_fit.reshape(size)

#Plotting
plt.subplot(1, 2, 1)
plt.title("Sample data")
plt.pcolormesh(X1, X2, Z_noise)
plt.axis(limits)
plt.colorbar()
plt.subplot(1, 2, 2)
plt.title("Fitted Function")
plt.pcolormesh(X1, X2, Z_fit)
plt.axis(limits)
plt.colorbar()

plt.show()

首先,我以发布函数的方式定义函数(假设^表示**)。然后,我为x和y轴设置了限制(您将不得不用自己的限制替换它们)。

现在要使拟合工作正常,我们必须将x / y数据放入一个向量中,这是直到第一个注释执行之前代码块的内容。在评论之后,我创建了示例数据,因为您拥有自己的数据,所以不需要它们。样本数据命名为z_noise(小z!),您必须将其重塑为一维矢量。毕竟,我可以调用curve_fit以获得最匹配z_noise的参数。

我让创建示例数据的部分进入其中,以便可以轻松地对其进行反复测试:大部分代码来自here