我对 python 和 lmfit 模型很陌生,遇到了一些麻烦。我想为我的实验数据拟合一个峰值函数(比如高斯或 Voigtian 轮廓),但它从来没有给我任何好的结果。它的最佳拟合是线性函数,它描述了我的峰轮廓的基线。
拟合过程的 x 数据只是从 0 到 100 的数字。这是我的 y 数据:
array([ 0.99518284, 0.99449661, 0.99609029, 0.996 , 0.994307 ,
0.999693 , 0.99826185, 0.99680361, 0.99474041, 0.99793228,
0.99385553, 0.99869526, 1.00044695, 0.99625734, 0.99758916,
0.99489842, 1.00032957, 0.9967088 , 0.99655982, 0.99990068,
0.99515576, 0.99665914, 0.99990068, 0.99595034, 0.99792777,
0.9941851 , 0.99458691, 0.99312415, 0.99815801, 0.99851919,
0.99637472, 0.996 , 0.99632957, 0.99185102, 0.99173363,
0.9915395 , 0.99038826, 0.9917246 , 0.99315124, 0.98968397,
0.99120993, 0.98981038, 0.9892009 , 0.99009932, 0.98853725,
0.98624379, 0.98620316, 0.9826772 , 0.99204966, 0.98455982,
0.99049661, 0.98591422, 0.98906546, 0.98664108, 0.98740858,
0.99076298, 0.99046953, 0.99067269, 0.99255982, 0.99264108,
0.99215801, 0.99990068, 0.9948623 , 0.99616704, 0.99307449,
0.99626637, 0.9934447 , 0.99476749, 0.99636117, 0.99840181,
0.9984921 , 0.99782844, 0.99853273, 0.99575621, 0.9985553 ,
0.99936343, 0.99643792, 0.99825734, 0.9964605 , 0.99879007,
1.00068172, 0.99580135, 0.99898871, 1.00069074, 0.99920993,
0.9963702 , 0.99591874, 0.99730023, 0.99765237, 0.99334537,
0.99798194, 0.99770655, 0.99702935, 0.99716027, 0.99662754,
0.99779684, 0.9967088 , 0.99736343, 0.99786907, 0.9968623 ,
0.99961174])
我尝试了以下具有不同模型函数(Gaussian、Voigtian 和 PseudoVoigtian)的方法:
>>> from lmfit.models import PseudoVoigtModel
>>> mod = PseudoVoigtModel()
>>> pars = mod.guess(y, x=x)
>>> out = mod.fit(y, pars, x=x)
>>> print(out.fit_report(min_correl=0.25))
>>> out.plot()
完全相同的代码对于我创建的配置文件测试功能非常有效,所以我想它没有任何问题。但是对于真实的测量数据,无论我选择哪种剖面模型,它总是给出一个线性函数。这是一个例子:
>>> out.best_fit
array([ 0.99410398, 0.99412124, 0.99413851, 0.99415577, 0.99417303,
0.99419029, 0.99420755, 0.99422481, 0.99424207, 0.99425932,
0.99427658, 0.99429383, 0.99431108, 0.99432833, 0.99434558,
0.99436283, 0.99438007, 0.99439732, 0.99441456, 0.9944318 ,
0.99444904, 0.99446628, 0.99448351, 0.99450075, 0.99451798,
0.99453522, 0.99455245, 0.99456968, 0.99458691, 0.99460413,
0.99462136, 0.99463858, 0.99465581, 0.99467303, 0.99469025,
0.99470747, 0.99472468, 0.9947419 , 0.99475912, 0.99477633,
0.99479354, 0.99481075, 0.99482796, 0.99484517, 0.99486237,
0.99487958, 0.99489678, 0.99491398, 0.99493118, 0.99494838,
0.99496558, 0.99498278, 0.99499997, 0.99501716, 0.99503436,
0.99505155, 0.99506874, 0.99508592, 0.99510311, 0.9951203 ,
0.99513748, 0.99515466, 0.99517184, 0.99518902, 0.9952062 ,
0.99522338, 0.99524055, 0.99525772, 0.9952749 , 0.99529207,
0.99530924, 0.9953264 , 0.99534357, 0.99536074, 0.9953779 ,
0.99539506, 0.99541222, 0.99542938, 0.99544654, 0.9954637 ,
0.99548085, 0.99549801, 0.99551516, 0.99553231, 0.99554946,
0.99556661, 0.99558376, 0.9956009 , 0.99561805, 0.99563519,
0.99565233, 0.99566947, 0.99568661, 0.99570375, 0.99572088,
0.99573802, 0.99575515, 0.99577228, 0.99578941, 0.99580654,
0.99582367])
我使用以下方法进行了另一次尝试,但在这里,它根本不适合某些东西,我只得到了 nan 值,尽管它适用于我的高斯测试函数:
from lmfit.models import GaussianModel
from lmfit import Model
import numpy as np
def gaussian(x, amp, cen, wid):
"1-d gaussian: gaussian(x, amp, cen, wid)"
return (amp/(sqrt(2*pi)*wid)) * exp(-(x-cen)**2 /(2*wid**2))
gmod = Model(gaussian)
mod.set_param_hint('x', value=10)
mod.set_param_hint('cent', value=47)
mod.set_param_hint('wid', value=20)
mod.set_param_hint('amp', value=0.2)
pars = gmod.make_params()
out = gmod.fit(normedy, pars, x=x)
print(out.fit_report(min_correl=0.1))
plt.figure(5, figsize=(8,8))
out.plot_fit()
我试图用原点拟合数据,它肯定有效(所以数据不是'不合适'),但我怎样才能用 python 正确地做到这一点?你有没有其他我可以尝试的方法或我可以初始化的东西来使它工作?