【问题标题】:Scipy curve_fit confusion using bounds and initial parameters on simple data在简单数据上使用边界和初始参数的 Scipy curve_fit 混淆
【发布时间】:2020-03-13 12:34:32
【问题描述】:

虽然我非常适合其他数据集,但出于某种原因,以下代码不适用于相对简单的一组点。我已经尝试了衰减指数和幂,以及初始参数和界限。我相信这暴露了我更深的误解;我很感激任何建议。

    snr = [1e10, 5, 1, .5, .1, .05]
    tau = [1, 8, 10, 14, 35, 80]

    fig1, ax1 = plt.subplots()

    def fit(x, a, b, c): #c: asymptote
        #return a * np.exp(b * x) + 1.
        return np.power(x,a)*b + c

    xlist = np.arange(0,len(snr),1)
    p0 = [-1., 1., 1.]
    params = curve_fit(fit, xlist, tau, p0)#, bounds=([-np.inf, 0., 0.], [0., np.inf, np.inf]))

    a, b, c = params[0]
    print(a,b,c)
    ax1.plot(xlist, fit(xlist, a, b, c), c='b', label='Fit')

    #ax1.plot(snr, tau, zorder=-1, c='k', alpha=.25)
    ax1.scatter(snr, tau)
    ax1.set_xscale('log')        
    #ax1.set_xlim(.02, 15)
    plt.show()

更新 1: 参考图,遵循 Eric M 的代码: 将在下面的帖子中发表评论。


修复更新 1: xlist = np.arange(0.01,10000,1)/1000+0.01

【问题讨论】:

  • 您确定要适合xlist吗?您的代码使您看起来想要适合 snrtau。然后在xlist 上绘制拟合。在这种情况下,您需要将拟合线更改为 curve_fit(fit, snr, tau, p0)

标签: python scipy curve-fitting


【解决方案1】:

这对我有用。有几个问题。包括我的评论。您的 xlist 中还有一个“除以零”错误,所以我通过将 0.01 添加到 xlist 并增加点的密度以使曲线变圆来避免这种情况。

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

snr = [1e10, 5, 1, .5, .1, .05]
tau = [1, 8, 10, 14, 35, 80]

fig1, ax1 = plt.subplots()

def fit(x, a, b, c):
    return np.power(x, a)*b + c

xlist = np.arange(0.01,10000,1)/1000+0.01
xlist = np.append(xlist, 1e10)
p0 = [-10, 10., 1.]
params = curve_fit(fit, snr, tau, p0)

print('Fitting parameters: {}'.format(params[0]))
ax1.plot(xlist, fit(xlist, *params[0]), c='b', label='Fit')
ax1.scatter(snr, tau)
ax1.set_xscale('log')        
plt.show()

【讨论】:

  • 感谢您的建议,我完全忽略了 xlist 错位。您的身材看起来不错,但是完全使用您的代码(复制和粘贴),我得到了不同的输出(请参阅我的原始帖子)。你的参数是什么?也许我需要设置界限
  • 没关系,我做出了改变:xlist = np.arange(0.01,10000,1)/1000+0.01;如果您更新代码,我会接受。再次感谢您!
  • 已更新。很高兴我们能弄清楚。
【解决方案2】:
import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit


def fit(x, a, b, c):
    return np.power(x, a)*b + c


x = [1e10, 5, 1, .5, .1, .05]
y = [1, 8, 10, 14, 35, 80]

popt, pcov=curve_fit(fit,x,y, bounds=([-np.inf, 0., 0.], [0., np.inf, np.inf]))
x_curve = np.append(np.linspace(0.01, 10, 1000), 1e11)

# plot
fig, ax = plt.subplots()
ax.set_ylim(-25,100)
ax.set_xscale("log")
ax.scatter(x, y)
plt.plot(x_curve, np.power(x_curve, popt[0])*popt[1] + popt[2], color = 'green')
plt.show()

输出:

【讨论】:

  • 非常感谢。 Eric M 的评论更贴切,但我在复制时也遇到了麻烦。然而,我可以重现这个情节。会及时更新
猜你喜欢
  • 2018-02-03
  • 2013-07-30
  • 2017-04-08
  • 2014-07-12
  • 1970-01-01
  • 2017-10-29
  • 1970-01-01
  • 2021-07-22
  • 2016-03-12
相关资源
最近更新 更多