尝试使用 scipy.curve_fit 将数据拟合到余切函数

Trying to fit data to cotangens function using scipy.curve_fit

我的数据与 arccos(x) 的数据非常相似,所以我想我会成功的。使用代码:

from scipy.optimize import curve_fit
        
x0 = [240, 320] 
y0 = [100, 99, 90, 60, 30, 10, 1, 0, 0] 

x = np.linspace(x0[0], x0[1], int((x0[1]-x0[0])/10+1))

def fun(x, a, b, c):
    return np.pi/2 - c*np.arctan(x*a + b)
        
p, c = curve_fit(f=fun, xdata=x, ydata=y0)
plt.plot(x, fun(x, *p))

我得到的几乎是直线 - 不是 arccot 形状,y 域在 3.6 和 4.6 之间,不在数据范围 (0, 100) 内。 我想我遗漏了什么,但设置 bounds 没有帮助。也许应该填充函数中的一些附加参数或者我自己的参数是错误的?请给我一些提示。

编辑

发现错误:

def fun(x, a, b, c, d):
    return (np.pi/2 - np.arctan(x*a + c)) * b + d

该函数已分离并添加了新参数。

顺便说一句,我发现那些适合的数据点使得 arccot 的行为不像这种类型的典型函数,因为新的 y 值是

array([102.37654247,  97.634854  ,  87.58354894,  62.42799136,
        27.36151993,  10.72835311,   3.75400887,   0.15012275,
        -2.0169414 ])

所以有一些值超过 100 和低于 0,这在我设置的域中不好。也许有一些方法可以通过使用其他参数来拟合域,或者我只是过度拟合?

编辑 2

找到最符合值的值

x0 = np.array([200, 250, 260, 275, 290, 300, 350])
y0 = np.array([100, 97, 90, 50, 10, 3, 0])

略有变化,但 arccot 非常坚硬且对对称性敏感,因此需要做出一些妥协。

正在检查由 x0 设置的域外的一些值,仍然存在错误:

fun(220, *p)
Out[448]: 99.71484816434646

fun(210, *p)
Out[449]: 100.25808335333575

不过要满足一些如果。

答案是:

def fun(x, a, b, c, d):
    return (np.pi/2 - np.arctan(x*a + c)) * b + d

函数构建错误。使用只有一个形状变化条目的 4 个参数过度拟合此类函数的问题导致我从未将它拟合到所有点,即使它们似乎在“目标”上。可以删除 cd 并获得更好的拟合。或者只是将函数更改为多项式。