多元异维拟合

Multivariant different dimensional fit

我正在尝试使用 scipy curve_fit 进行 3 维三次多项式拟合,但由于我对 python 曲线拟合工具的经验不多,我'我在这样做时遇到了一些麻烦。

我有一个函数的两个参数,它们是向量,一个矩阵表示每个点的值。我正在尝试对每个参数进行 3 次多项式拟合,但我遇到了一些麻烦。我正在尝试使用 curve_fit 函数,因为那是我在网上找到的,如果有更好的建议,如 polyfit,我会很乐意听取他们的意见。这是我的代码:

import numpy as np
from scipy.optimize import curve_fit

def polyfit(data,a1,a2,a3,a4,a5,a6,a7):
    return a1*np.power(data[0],3) + a2*np.power(data[0],2) + a3*data[0] \
        + a4*np.power(data[1],3) + a5*np.power(data[1],2) + a6*data[1] + a7

xtemp = np.array([10,25,35,45,55])
yexpT = np.array([1,5,10,100,500,1000,5000,7500])
dataMat = np.array([[1475,1475,1478,1528,1776,2086,4588,6146] ,
            [1575,1575,1578,1728,1976,2086,6588,7146],
            [1675,1675,1778,1928,2176,2586,7588,9146],
            [2575,2575,2578,2728,2976,3086,9588,11146],
            [3575,3575,3578,3728,4976,8086,12588,15146]]) 
ymesh,xmesh = np.meshgrid(yexpT,xtemp)

popt,pcov = curve_fit(polyfit,[xmesh,ymesh],dataMat)

如您所见,xtemp 是行数,yexpT 是列数。

我试图在以下 link 中寻求帮助,例如: 还是没用。

提前感谢任何能够提供帮助的人。

这是 least_squares 的简单解决方案:

import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
import numpy as np
from scipy.optimize import least_squares


def poly( x, y,
    c0,
    a1, a2, a3,
    b1, b2, b3
):
    "non-mixing test plynomial"
    out = c0
    out += a1 * x**1 + a2 * x**2 + a3 * x**3
    out += b1 * y**1 + b2 * y**2 + b3 * y**3
    return out



### test grid
xL = np.linspace( -2, 5, 17 )
yL = np.linspace( -0, 6, 16 )

XX, YY = np.meshgrid(  xL, yL )

### test data
ZZ = poly(
    XX, YY,
    1.1,
    2.2, -0.55, 0.09,
    -3.1, +0.75, -0.071
)


### test noise
znoise = np.random.normal( size=( len(xL) * len(yL) ), scale=0.5 )
znoise.resize( len(yL), len(xL) )
ZZ += znoise


### residual finction, i.e. the important stuff
def res( params, X, Y, Z ):
    th = poly( X, Y, *params )
    diff = Z - th
    return np.concatenate( diff )

### fit
sol = least_squares( res, x0=7*[0], args=( XX, YY, ZZ ) )
print( sol.x )

### plot it
fig = plt.figure( )
ax = fig.add_subplot( 1, 1, 1, projection="3d" )
ax.scatter( XX, YY, ZZ, color='r' )
ax.plot_surface( XX, YY, poly( XX, YY, *(sol.x) ) )

plt.show()

顺便说一句,这当然是纯线性拟合。所以根据我的另一个 post 的定义,可以这样做:

### fitting:
X = np.concatenate( XX )
Y = np.concatenate( YY )
Z = np.concatenate( ZZ )

VT = np.array( [
    np.ones( len(xL) * len(yL) ),
    X, X**2, X**3,
    Y, Y**2, Y**3
] )
V = np.transpose( VT )
eta = np.dot( VT, Z )
A = np.dot( VT, V )
sol = np.linalg.solve( A, eta )
print( sol )

### plot it
fig = plt.figure( )
ax = fig.add_subplot( 1, 1, 1, projection="3d" )
ax.scatter( XX, YY, ZZ, color='r' )
ax.plot_surface( XX, YY, poly( XX, YY, *(sol) ) )
plt.show()

我在 here

中添加了更多信息