如何在Python中应用二维曲线拟合



我正在尝试应用一条2D曲线来拟合下面给出的数据(任意)集:

# Data
T   Z   X 1 X 2 X 3 X 4 X 5
100.000 1.000   1.000   1.478   1.304   1.162   0.805
200.000 1.500   2.000   2.314   2.168   2.086   1.801
300.000 2.250   3.000   3.246   3.114   3.058   2.798
400.000 3.375   4.000   4.211   4.087   4.044   3.780
500.000 5.063   5.000   5.189   5.070   5.035   4.780

最终目的是发展形式Z=f(X,T)的相关性。

首先,它是使用二次表达式Z=a*x^2+b*x+c沿着T的常数值进行曲线拟合,即沿着每行,这给出了每个T的拟合参数,如下所示(作为示例):

T   a   b   c
100.00  1.00    2.10    10.02
200.00  4.00    6.20    10.06
300.00  9.00    12.30   10.12
400.00  16.00   20.40   10.20
500.00  25.00   30.50   10.31

现在我想沿着T拟合每个拟合参数,这样我就得到了形式为a=p*T^2+q*T+r,b=s*T^2+T*T+u等的方程

from __future__ import division
from scipy import optimize
import matplotlib.pyplot as plt
import numpy as np
data = open('data.dat', "r")
line = data.readline()
while line.startswith('#'):
    line = data.readline()
data_header = line.split("t")
data_header[-1] = data_header[-1].strip()

_data_ = np.genfromtxt('data.dat', skiprows=2, delimiter='t', names = data_header, dtype = None, unpack = True).transpose()
data = np.array(_data_.tolist())
m = data.shape[0]
n = data.shape[1] - 2
print m, n
y_data = np.empty(shape=(m, n))
for i in range(0, m):
    for j in range(0, n):
        y_data[i, j] = (data[i, j+2])
x = _data_['X']
z = _data_['Z']
def quadratic_fit(x, a, b, c):
    return a * x ** 2 + b * x + c
fit_a = np.empty(shape = (m, 1))
fit_b = np.empty(shape = (m, 1))
fit_c = np.empty(shape = (m, 1))
z_fit = np.empty(shape=(m, len(z)))
for j in range(m):
    x_fit = y_data[j, :]
    y_fit = z
    fit_a[j], fit_b[j], fit_c[j] = optimize.curve_fit(quadratic_fit, x_fit, y_fit)[0]
fit_a_fit_a, fit_a_fit_b, fit_a_fit_c, = optimize.curve_fit(quadratic_fit, x, fit_a)[0]
fit_b_fit_a, fit_b_fit_b, fit_b_fit_c, = optimize.curve_fit(quadratic_fit, x, fit_b)[0]
fit_c_fit_a, fit_c_fit_b, fit_c_fit_c, = optimize.curve_fit(quadratic_fit, x, fit_c)[0]
fit_a = fit_a_fit_a * x ** 2 + fit_a_fit_b * x + fit_a_fit_c
fit_b = fit_b_fit_a * x ** 2 + fit_b_fit_b * x + fit_b_fit_c
fit_c = fit_c_fit_a * x ** 2 + fit_c_fit_b * x + fit_c_fit_c
for j in range(m):              
    z_fit[j, :] = (fit_a[j] * x_fit ** 2) + (fit_b[j] * x_fit) + fit_c[j] 

但它给了我以下错误:

ValueError: object too deep for desired array
Traceback (most recent call last):
    fit_a_fit_a, fit_a_fit_b, fit_a_fit_c, = optimize.curve_fit(quadratic_fit, x, fit_a)[0]
  File "scipy/optimize/minpack.py", line 533, in curve_fit
    res = leastsq(func, p0, args=args, full_output=1, **kw)
  File "scipy/optimize/minpack.py", line 378, in leastsq
    gtol, maxfev, epsfcn, factor, diag)
minpack.error: Result from function call is not a proper array of floats.

在Python中如何做到这一点?

我只是玩了一会儿,我认为你的问题是

fit_a = np.empty(shape = (m, 1))
fit_b = np.empty(shape = (m, 1))
fit_c = np.empty(shape = (m, 1))

应该是

fit_a = np.empty(shape = (m, ))
fit_b = np.empty(shape = (m, ))
fit_c = np.empty(shape = (m, ))

看起来形状(m,1)确实应该是正确的,但它并没有像形状(m)那样被处理,形状只是一个一维数组。试试看是否有效。

也就是说,我不确定拟合参数是否是解决这个问题的正确方法,至少就我所知…

我可以借此机会无耻地插入我自己的配件包symfit吗?

我开发它正是为了让像你这样的合身问题变得更容易。如果没有针对您的问题运行它,这就是我使用symfit:解决问题的方法

from symfit import parameters, variables, Fit
Z, X, T = variables('Z, X, T')
p, q, r, s, t, u  = parameters('p, q, r, s, t, u')
a = p * T**2 + q * T + r
b = s * T**2 + t * T + u
c = ...
model = {Z: a * X ** 2 + b * X + c}
fit = Fit(model, X=_data_['X'], T=_data_['T'], Z=_data_['Z'])
fit_result = fit.execute()
print(fit_result)

有关更多信息,请查看文档:)。

最新更新