see < a href =" https://youcans.blog.csdn.net/article/details/119332590" target="_blank"> Python's mathematical modeling lesson -23. Data fitting full set
fit() uses the nonlinear least square method to fit the customized fitting function to the observed data. It can be used not only for the fitting of straight line, quadratic curve, cubic curve, but also for the fitting of any form of custom function. It is very convenient to use. curve_fit() allows custom function fitting of one or more variables.
curve_fit() defines a fitting function fitfunc7(X, p0, p1,p2, p3). The name of the function can be defined arbitrarily, but the parameters of the fitting function must be(x,p1,p2,...). The order of, cannot change the order. p1, p2... It's a scalar. You can't write it as an array.
# mathmodel25_v1.py
# Demo25 of mathematical modeling algorithm
# Demo of curve fitting with Scipy
# Copyright 2021 YouCans, XUPT
# Crated:2021-08-03
# 7. 自定义函数曲线拟合:多变量
import numpy as np
import matplotlib.pyplot as plt # 导入 Matplotlib 工具包
from scipy.optimize import curve_fit # 导入 scipy 中的曲线拟合工具
def fitfunc7(X, p0, p1, p2, p3): # 定义多变量拟合函数, X 是向量
# p0, p1, p2, p3 = p # 拟合函数的参数
y = p0 + p1*X[0,:] + p2*X[1,:] + p3*np.sin(X[0,:]+X[1,:]+X[0,:]**2+X[1,:]**2)
return y
# 创建给定数据点集 (x,yObs)
p = [1.0, 0.5, -0.5, 5.0] # 自定义函数的参数
p0, p1, p2, p3 = p # y = p0 + p1*x1 + p2*x2 + p3*np.sin(x1+x2+x1^2+x2^2)
np.random.seed(1)
x1 = 2.0 * np.random.rand(8) # 生成随机数组,长度为 8
x2 = 3.0 * np.random.rand(5) # 生成随机数组,取值范围 (0,3.0)
xmesh1, xmesh2 = np.meshgrid(x1, x2) # 生成网格点的坐标 xx,yy (二维数组)
xx1= xmesh1.reshape(xmesh1.shape[0]*xmesh1.shape[1], ) # 将网格点展平为一维数组
xx2= xmesh2.reshape(xmesh2.shape[0]*xmesh2.shape[1], ) # 将网格点展平为一维数组
X = np.vstack((xx1,xx2)) # 生成多变量数组,行数为变量个数
y = fitfunc7(X, p0, p1, p2, p3) # 理论计算值 y=f(X,p)
yObs = y + 0.2*np.random.randn(y.shape[-1]) # 生成带有噪声的观测数据
print(x1.shape,x2.shape,xmesh1.shape,xx1.shape,X.shape)
# 用 scipy.optimize.curve_fit() 进行自定义函数拟合(多变量)
pFit, pcov = curve_fit(fitfunc7, X, yObs) # 非线性最小二乘法曲线拟合
print("Data fitting of multivariable custom function")
print("y = p0 + p1*x1 + p2*x2 + p3*np.sin(x1+x2+x1^2+x2^2)")
for i in range(4):
print("p[{:d}] = {:.4f}\tp[{:d}]_fit = {:.4f}".format(i, p[i], i, pFit[i]))
# 由拟合函数 fitfunc 计算拟合曲线在数据点的函数值
yFit = fitfunc7(X, pFit[0], pFit[1], pFit[2], pFit[3])