【问题标题】:Non-linear fit in Python 2.7 doesn't give any good resultPython 2.7 中的非线性拟合没有给出任何好的结果
【发布时间】:2016-05-25 15:09:25
【问题描述】:

这是我的问题:我有适合模型的实验数据。为此,我使用了 scipy 的 curve_fit。该脚本没有任何错误或警告,但没有给出令人满意的结果(它给了我一个准线而不是两个洛伦兹形图)。

但最奇怪的是,当我给拟合函数一个猜测数组时,除了第三个参数之外,没有一个猜测的参数被修改(尽管它远离预期值)。但是我注意猜测参数的顺序。

我给你合适的代码部分。

X = 927.
Z = 88.
M = 5.e-15
O1 = 92975.
O2 = 93570.
bm = np.arctan2(Z,X)
P0 = 0.
T = np.pi/2.
TM = np.pi/3.
G = 20.

File ="Data.txt"
open(File,  "rb")
dat = np.loadtxt(File)

O = dat[:,1]

D = np.sqrt(1./20. *10**(dat[:,7]/10.)*1/((X**2+Z**2)*10**(6)))

def model(W,o1,o2,p0,t,tm,g):

    DB = np.abs((1./M)*(np.cos(bm-tm)*(p0*np.cos(t-tm)/(o1**2-W**2-1.j*g*W))+np.sin(bm-tm)*(p0*np.sin(t-tm)/((o2**2-W**2-1.j*g*W)))))

    return DB

guess = np.array([O1,O2,P0,T,TM,G])
fit , pcov = curve_fit(model, O , D , guess)

我在整整一个月的时间里搜索了一项研究以发现任何错误,但仍然注意到。函数是否可能对curve_fit复杂?

提前感谢您的帮助。如果您需要更多信息或数据,请不要犹豫

这是O v D 的情节。红点是实验,蓝线是返回拟合参数的函数(没有修改,所以是猜测值)

D = model(O)

【问题讨论】:

  • 你的模型函数中是否可能不依赖o2
  • 你能给我们看一张O vs D的图吗?
  • 您最初的猜测可能不是一个好的猜测,因为model 对所有W 的计算结果为零
  • 检查pcov的值。如果包含naninf,则拟合不成功。
  • 你好@gboffi :不,对o2 的依赖很重要,这是给出我haded 图中两个峰之一的位置的参数。 @WarrenWeckesser:是的, pcov 等于 inf 所以拟合不起作用。我想我会试试 M Newville 的建议,看看 lmfit 给了我什么

标签: python scipy curve-fitting


【解决方案1】:

很难判断混合常量和很长的公式会发生什么。但有几点需要考虑:

  1. 如果变量的初始值没有变化,则应注意缩放。您的 (X**2+Z**2)*10**(6) 将在 ~1e16 左右,这可能会导致难以进行良好的数值导数。您可能需要修改发送到 leastsq()epsfcn 的值。

  2. 看起来您的模型函数计算了一个复数数组。我相信 curve_fit() 只能处理严格的真实值。

您可能会发现lmfit 模块很有用。

【讨论】:

  • 您好首先,感谢您抽出宝贵时间,并为所有变量感到抱歉,我真的试图让它简单易懂。我真的不认为这是复数数组的问题,因为函数返回这个数组的模数,所以它是真实的。但是,我会检查这一点。但我没有考虑我的价值观的规模。我还不知道epsfcn 是什么,我会看看这个和lmfit 模块。
【解决方案2】:

各位,谢谢你们,我终于找到了解决办法!

我没有使用curve_fit,而是尝试在this tutorial 之后直接使用leastsq,以查看会发生什么。它的效果比预期的要好,因为拟合确实成功并为我提供了正确的峰值位置和振幅。我给你正确的代码,因为它对我有用。

X = 927.0
Z = 88.
M = 5.e-15
O1 = 92975.
O2 = 93570.
bm = np.arctan2(Z,X)
P0=1.e-12
T=np.pi/2.
TM=np.pi/3.
G=20.

File ="Data.csv"
open(File,  "rb")
dat = np.loadtxt(File)

O = dat[:,1]

D = np.sqrt(1/1000. *10**(dat[:,7]/10.)*50.*1/((X**2+Z**2)*10**(6)))

def resid(p, y, W) :
    o1,o2,p0,t,tm,g = p
    err=y-(np.abs((1./M)*(np.cos(bm-tm)*(p0*np.cos(t-tm)/(o1**2-W**2-1.j*g*W))+np.sin(bm-tm)*(p0*np.sin(t-tm)/((o2**2-W**2-1.j*g*W))))))
    return err

def peval(W,p) :
    return np.abs((1./M)*(np.cos(bm-p[4])*(p[2]*np.cos(p[3]-p[4])/(p[0]**2-W**2-1.j*p[5]*W))+np.sin(bm-p[4])*(p[2]*np.sin(p[3]-p[4])/((p[1]**2-W**2-1.j*p[5]*W)))))


guess = np.array([O1,O2,P0,T,TM,G])
plsq = leastsq(resid,guess,args=(D,O))
print plsq[0]

plt.yscale('log')

再次感谢您的关注

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-30
    • 2020-11-22
    • 1970-01-01
    • 2021-02-25
    • 2014-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多