使用曲线拟合的Python数据拟合

使用曲线拟合的Python数据拟合,python,data-analysis,Python,Data Analysis,(此任务使用jupyter笔记本系统) 这不是 拟合希格斯质量-给定下面的fitter(xvalues,data,init)函数,编写一个函数fitfunc(…),描述用于拟合数据的组合背景和信号模型。创建两张图片: (a) 使用交叉标记(“+”符号)和最佳拟合曲线在第一个绘图上绘制数据,然后 (b) 在第二个图上绘制带有交叉标记的残差,残差定义为最佳拟合模型和纯背景模型之间的差异,见下文 拟合函数由3个参数的背景模型组成 我修改了你的代码来运行,所以你的init数组在这里为我做了更改 """.

(此任务使用jupyter笔记本系统)

这不是

拟合希格斯质量-给定下面的fitter(xvalues,data,init)函数,编写一个函数fitfunc(…),描述用于拟合数据的组合背景和信号模型。创建两张图片:

(a) 使用交叉标记(“+”符号)和最佳拟合曲线在第一个绘图上绘制数据,然后

(b) 在第二个图上绘制带有交叉标记的残差,残差定义为最佳拟合模型和纯背景模型之间的差异,见下文

拟合函数由3个参数的背景模型组成


我修改了你的代码来运行,所以你的init数组在这里为我做了更改

"""."""
# YOUR CODE HERE
import math
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit


def fitfunc(m, mu, sigma, R, A, b1, b2):
    """."""
    tb1 = b1 * (m - 105.5)
    tb2 = b2 * ((m-105.5)**2)
    b = A * np.exp(tb1 + tb2)
    ts1 = R / (sigma * np.sqrt(2 * np.pi))
    ts2 = -(((m - mu)**2) / (2 * (sigma**2)))
    s = ts1 * np.exp(ts2)
    tot = b + s
    return tot


def fitter(xval, yval, initial):
    """
    Function to fit the given data using a 'fitfunc' TBD.

    The curve_fit function is called. Only the best fit values
    are returned to be utilized in a main script.
    """
    best, _ = curve_fit(fitfunc, xval, yval, p0=initial)
    return best

# Use functions with script below for plotting parts (a) and (b)


# start value parameter definitions, see equations for s(m) and b(m).
# init[0] = mu
# init[1] = sigma
# init[2] = R
# init[3] = A
# init[4] = b1
# init[5] = b2
init = (126, 2, 470, 5000, 1, 5)
xvalues = np.arange(start=105.5, stop=160.5, step=1)
data = np.array([4780, 4440, 4205, 4150, 3920, 3890, 3590, 3460, 3300, 3200, 3000,
                 2950, 2830, 2700, 2620, 2610, 2510, 2280, 2330, 2345, 2300, 2190,


    2080, 1990, 1840, 1830, 1730, 1680, 1620, 1600, 1540, 1505, 1450,
             1410, 1380, 1380, 1250, 1230, 1220, 1110, 1110, 1080, 1055, 1050,
             940, 920, 950, 880, 870, 850, 800, 820, 810, 770, 760])


def main():
"""."""
arr = np.ndarray(init)
fitt = fitfunc(xvalues, init[0], init[1], init[2], init[3], init[4], init[5])

def plota(xval, yval):
    fig = plt.figure()
    axis1 = fig.add_axes([0.12, 0.1, 0.85, 0.85])
    axis1.plot(xval, yval, marker="+", color="red")
    axis1.set_title("Combined", size=12)
    axis1.set_xlabel("Mass [GeV]", size=12)
    plt.show()
    return
plota(xvalues, fitt)
plota(xvalues, fitter(xvalues, fitt, arr))


main()

请注意,main上的缩进按1个制表符/空格分组关闭。

我认为您很接近,但有两件事:

  • b1
    b2
    >0的值可能导致指数无穷大
  • 曲线拟合的返回值是最佳参数值,而不是最佳拟合。你得自己计算一下
    您可能还想适应数据阵列,对吗?我想这可能就是你要找的

    import math
    import numpy as np
    import matplotlib.pyplot as plt
    from scipy.optimize import curve_fit
    
    def fitfunc(m, mu, sigma, R, A, b1, b2):
        """comment about Higgs mass here"""
        tb1 = b1 * (m - 105.5)
        tb2 = b2 * ((m-105.5)**2)
        b = A * np.exp(tb1 + tb2)
        ts1 = R / (sigma * np.sqrt(2 * np.pi))
        ts2 = -(((m - mu)**2) / (2 * (sigma**2)))
        s = ts1 * np.exp(ts2)
        tot = b + s
        return tot
    
    xvalues = np.arange(start=105.5, stop=160.5, step=1)
    data = np.array([4780, 4440, 4205, 4150, 3920, 3890, 3590, 3460, 3300, 3200, 3000,
                     2950, 2830, 2700, 2620, 2610, 2510, 2280, 2330, 2345, 2300, 2190,
                     2080, 1990, 1840, 1830, 1730, 1680, 1620, 1600, 1540, 1505, 1450,
                     1410, 1380, 1380, 1250, 1230, 1220, 1110, 1110, 1080, 1055, 1050,
                     940, 920, 950, 880, 870, 850, 800, 820, 810, 770, 760])
    
    # start value parameter definitions, see equations for s(m) and b(m).
    # init[0] = mu
    # init[1] = sigma
    # init[2] = R
    # init[3] = A
    # init[4] = b1
    # init[5] = b2
    
    init = np.array([125.8, 2, 470, 5000., -0.05, -0.001])
    
    init_fit = fitfunc(xvalues, *init)
    
    best, _ = curve_fit(fitfunc, xvalues, data, p0=init)
    print(best)
    
    best_fit = fitfunc(xvalues, *best)
    
    plt.plot(xvalues, data, color='red', marker='+', label='data')
    plt.plot(xvalues, init_fit, color='black',  label='init')
    plt.plot(xvalues, best_fit, color='blue',  label='fit')
    plt.gca().set_title("Combined", size=12)
    plt.gca().set_xlabel("Mass [GeV]", size=12)
    plt.legend()
    plt.show()
    
    如果您允许的话,我还建议您为此使用
    lmfit
    ()(披露:我是作者之一)。使用此库,上面带有
    曲线拟合的代码将转换为

    import lmfit
    h_model = Model(fitfunc)
    params = h_model.make_params(mu=125.8, sigma=2, R=470, 
                                 A=5000, b1=-0.05, b2=-0.001)
    result = h_model.fit(data, params, m=xvalues)
    
    print(result.fit_report())
    
    plt.plot(xvalues, data, color='red', marker='+', label='data')
    plt.plot(xvalues, result.init_fit, color='black',  label='init')
    plt.plot(xvalues, result.best_fit, color='blue',  label='fit')
    plt.gca().set_title("Combined", size=12)
    plt.gca().set_xlabel("Mass [GeV]", size=12)
    plt.legend()
    plt.show()
    
    请注意,使用lmfit时,参数是使用函数参数命名的。在
    lmfit
    中,所有参数都可以有边界,因此您可以执行以下操作

    params['b1'].max = 0.0
    
    要确保
    b1
    保持为负值,还可以修复任何参数值。还有许多其他特点

    该拟合的打印报告将包括不确定性和相关性的估计以及拟合统计:

    [[Model]]
        Model(fitfunc)
    [[Fit Statistics]]
        # fitting method   = leastsq
        # function evals   = 100
        # data points      = 55
        # variables        = 6
        chi-square         = 106329.424
        reduced chi-square = 2169.98824
        Akaike info crit   = 428.183028
        Bayesian info crit = 440.227027
    [[Variables]]
        mu:     125.940465 +/- 0.34609625 (0.27%) (init = 125.8)
        sigma:  1.52638256 +/- 0.37354633 (24.47%) (init = 2)
        R:      677.016219 +/- 163.585050 (24.16%) (init = 470)
        A:      4660.71073 +/- 24.3437093 (0.52%) (init = 5000)
        b1:    -0.04279037 +/- 7.7658e-04 (1.81%) (init = -0.05)
        b2:     1.7476e-04 +/- 1.7587e-05 (10.06%) (init = -0.001)
    [[Correlations]] (unreported correlations are < 0.100)
        C(b1, b2)    = -0.952
        C(A, b1)     = -0.775
        C(sigma, R)  =  0.655
        C(A, b2)     =  0.650
        C(R, b1)     = -0.492
        C(R, b2)     =  0.445
        C(sigma, b1) = -0.317
        C(sigma, b2) =  0.287
        C(R, A)      =  0.230
        C(sigma, A)  =  0.146
    
    [[Model]]
    模型(fitfunc)
    [[Fit统计数据]]
    #拟合方法=最小二乘法
    #函数evals=100
    #数据点=55
    #变量=6
    卡方=106329.424
    缩减卡方检验=2169.98824
    Akaike信息临界值=428.183028
    贝叶斯信息标准=440.227027
    [[变量]]
    mu:125.940465+/-0.34609625(0.27%)(初始值=125.8)
    西格玛:1.52638256+/-0.37354633(24.47%)(初始值=2)
    R:677.016219+/-163.585050(24.16%)(初始值=470)
    A:4660.71073+/-24.3437093(0.52%)(初始值=5000)
    b1:-0.04279037+/-7.7658e-04(1.81%)(初始值=-0.05)
    b2:1.7476e-04+/-1.7587e-05(10.06%)(初始值=-0.001)
    [[相关性]](未报告的相关性<0.100)
    C(b1,b2)=-0.952
    C(A,b1)=-0.775
    C(西格玛,R)=0.655
    C(A,b2)=0.650
    C(R,b1)=-0.492
    C(R,b2)=0.445
    C(σ,b1)=-0.317
    C(西格玛,b2)=0.287
    C(R,A)=0.230
    C(西格玛,A)=0.146
    
    情节看起来就像

    尝试使用//进行整数除法,但不要使用浮点。我已经修正了这个问题,这个错误不是主要问题,原因是我不知道fitter方法调用时需要使用什么作为参数,我不确定是否正确使用了它。我会查看您的curve_fit()函数,看看p0是什么,这是fitter方法的第三个输入,它可能只是某些数据中的第0个元素。如果没有更多的信息,似乎很难提供帮助。fitfunc错误在哪一行?看起来您传入的值很好。我添加了错误报告,但我不知道发生了什么,我认为p0应该是一个“初始猜测”数组,但我不知道这些是什么。当我将您的init数组修改为
    init=(126,2470,5000,1,5)时
    要解决负值等问题,切换Overmit_内存,我会得到一个运行时警告,输入参数没有错误。我不确定缩进为什么是这样,它只会给我错误,否则它会编译,但不会绘制任何图形感谢您为此付出的时间和精力,我真的很感激