使用曲线拟合的Python数据拟合
(此任务使用jupyter笔记本系统) 这不是 拟合希格斯质量-给定下面的fitter(xvalues,data,init)函数,编写一个函数fitfunc(…),描述用于拟合数据的组合背景和信号模型。创建两张图片: (a) 使用交叉标记(“+”符号)和最佳拟合曲线在第一个绘图上绘制数据,然后 (b) 在第二个图上绘制带有交叉标记的残差,残差定义为最佳拟合模型和纯背景模型之间的差异,见下文 拟合函数由3个参数的背景模型组成使用曲线拟合的Python数据拟合,python,data-analysis,Python,Data Analysis,(此任务使用jupyter笔记本系统) 这不是 拟合希格斯质量-给定下面的fitter(xvalues,data,init)函数,编写一个函数fitfunc(…),描述用于拟合数据的组合背景和信号模型。创建两张图片: (a) 使用交叉标记(“+”符号)和最佳拟合曲线在第一个绘图上绘制数据,然后 (b) 在第二个图上绘制带有交叉标记的残差,残差定义为最佳拟合模型和纯背景模型之间的差异,见下文 拟合函数由3个参数的背景模型组成 我修改了你的代码来运行,所以你的init数组在这里为我做了更改 """.
我修改了你的代码来运行,所以你的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_内存,我会得到一个运行时警告,输入参数没有错误。我不确定缩进为什么是这样,它只会给我错误,否则它会编译,但不会绘制任何图形感谢您为此付出的时间和精力,我真的很感激