我已使用以下方法尝试拟合映射到特定函数的曲线,您也许可以重新设计其中的一些以满足您的需求:
首先,将您的模型函数定义为一个函数,该函数采用 x 值和一些参数集并返回关联的 y 值。
您需要确保您的函数确实是 mathematical sense 中的函数(即,对于任何 x 输入值,它们返回单个 y 值)
这是您的“模型”功能 - 例如:
# A kind of elliptic curve with two parameters n, m
def mn_elliptical(x,m,n):
return 1-((1 - (x)**(n))**(m))
对于二维模型(即输入为 x 和 y,z 有第三个输出),有多种方法可以制定模型和此处讨论的输入数据:https://scipython.com/blog/non-linear-least-squares-fitting-of-a-two-dimensional-data/ - 还有一个示例练习,看这个答案的结尾。
然后,使用scipy.optimize.curve_fit 方法,您需要为其提供一对数组,一个用于您收集的已知观测值的 x 和 y,将根据这些数组进行拟合。
xdata = [ ... all x values for all observations ... ]
ydata = [ ... all observed y values in the same order as above ... ]
from scipy.optimize import curve_fit
fitp, fite = curve_fit(mn_elliptical, xdata, ydata))
这将产生fitp 该方法拟合的最佳参数,并产生fite 输出描述执行拟合后剩余多少(最小二乘)误差。如果您的 fite 值太大,那么您的模型函数很可能不是一个好的函数。
您可以通过帮助设置要返回的参数的预期范围来帮助指导该过程,这可以显着加快速度 - 或者,如果您有一个偏斜的函数,它可以帮助您专注于正确的否则会丢失的值。链接的 scipy 文档中更深入地介绍了这些细节。
验证并接受误差量后,您可以从 fitp 检索参数并使用这些参数通过您的(现在已拟合的)模型生成 x 的附加值,并获得预测结果。
new_y = mn_elliptical(x, *fitp)
这将产生一个结果 - 使用更高级的 numpy/pandas 方法从您提供的 x 值数组生成多个结果。
为了演示二维用例,让我们想象一个粗略绘制的圆,点 A、B、C、D、E 位于以下 xy 坐标 (4,1)、(6.5,3.5)、( 4,6), (1.5,3.5), (2,2)
我们知道一个圆遵循公式(x-cx)^2+(y-cy)^2=r^2,所以可以把它写成一个可拟合的函数形式:
def circ(xy, cx, cy, r):
x,y = xy
return (((x-cx)**2) + ((y-cy)**2))-(r**2)
请注意,由于公式的性质,我已将返回值展平为始终为零(至少对于符合的 xy 值)。
我们使用此处列出的观察数据点:
xdata = np.array([4,6.5,4,1.5,2])
ydata = np.array([1,3.5,6,3.5,2])
zdata = np.array([0,0,0,0,0])
并根据linked article on 2-dimensions 中使用的方法转换该数据。
xdata = np.vstack((xdata.ravel(), ydata.ravel()))
ydata = zdata.ravel()
然后将其输入二维 circ 函数。
curve_fit(circ,xdata,ydata)
这会产生:
(array([ 4. , 3.5, -2.5]),
array([[ 0., -0., -0.],
[-0., 0., -0.],
[-0., -0., 0.]]))
其中第一部分描述了我的 fit circ 函数中的 (cx, cy, r) 参数,前两个是中心的 x,y 坐标,第三个是圆的半径。根据我在纸上的铅笔画,这几乎是钱。
第二部分描述了遇到的错误,对于这个手绘示例来说,这并不可怕。