Scipy 使用双 nat log 函数返回荒谬的曲线拟合结果

问题描述 投票:0回答:1

我正在编写质谱数据缩减软件,并尝试拟合一组原始数据

y, t
,其中
y
是质谱仪中给定气体种类的强度,
t
是与该强度相关的时间戳测量,双重自然对数函数。

我正在使用以下功能:

def double_ln_func(t, a, b, p, c, q, d):
    return a + b * np.log(p * t) + c * np.log(q * t)

def double_ln_fit(t, y):
    popt, pcov = curve_fit(double_ln_func, t, y)

    fitted_t = np.linspace(min(t), max(t), 100)
    fitted_y = double_ln_func(fitted_t, *popt)

    return fitted_t, fitted_y, popt

通常,自然对数项之一为正,表示记忆的向内生长,另一个为负,表示电离的消耗。

这通常会返回合理的结果:

enter image description here

上例数据:

He 3798 Q1520_  2024-06-25T09:49:42 
time_sec    2.22    3.25    4.24    40.27
2.691   1.918947E-9 1.353086E-9 1.083636E-9 2.424798E-11
8.393   1.924420E-9 1.352441E-9 1.081825E-9 2.451031E-11
13.995  1.924468E-9 1.350765E-9 1.082597E-9 2.493171E-11
19.595  1.925282E-9 1.349962E-9 1.081301E-9 2.494261E-11
25.195  1.927887E-9 1.349370E-9 1.080510E-9 2.491214E-11
30.895  1.930570E-9 1.348243E-9 1.079783E-9 2.517592E-11
36.495  1.932480E-9 1.347466E-9 1.079611E-9 2.510602E-11
42.095  1.931847E-9 1.348131E-9 1.079237E-9 2.513002E-11
47.795  1.934760E-9 1.346782E-9 1.078437E-9 2.512803E-11
53.395  1.929853E-9 1.345735E-9 1.078367E-9 2.498039E-11
58.996  1.934834E-9 1.345541E-9 1.077280E-9 2.520110E-11
64.596  1.932654E-9 1.344552E-9 1.077504E-9 2.550219E-11

但是,在其他情况下,拟合线会变得锯齿状且非参数化,例如下面的 4 和 40 amu 示例:

enter image description here

以上示例的数据:

He 3800 CB1 2024-06-25T10:19:42 
time_sec    2.22    3.25    4.24    40.27
1.616   1.890576E-9 1.359579E-9 7.204719E-13 1.014118E-11
7.218   1.894592E-9 1.357168E-9 7.196407E-13 1.130713E-11
12.819  1.894756E-9 1.355699E-9 7.183293E-13 1.139818E-11
18.519  1.895724E-9 1.354677E-9 7.262793E-13 1.098621E-11
24.119  1.899128E-9 1.354235E-9 7.101848E-13 1.077834E-11
29.729  1.898467E-9 1.353402E-9 7.125748E-13 1.187576E-11
35.430  1.899100E-9 1.351661E-9 7.355859E-13 1.104034E-11
41.032  1.899836E-9 1.352259E-9 7.077889E-13 1.089571E-11
46.633  1.902685E-9 1.351637E-9 7.197934E-13 1.141361E-11
52.235  1.902119E-9 1.351389E-9 7.155005E-13 1.151000E-11
57.835  1.902982E-9 1.350957E-9 7.118936E-13 1.155836E-11
63.535  1.907762E-9 1.351266E-9 7.195685E-13 1.208988E-11

虽然上面的结果包含高度分散性,并且这些类型的“解”经常出现在高分散性测量中,但该函数能够拟合许多高分散性情况,而无需求助于此类“解”。

有时,我会在终端中看到警告:

OptimizeWarning: Covariance of the parameters could not be estimated

但不足以解释每一个“疯狂”的例子。

出于某种原因,4 amu 数据比任何其他数据集最敏感且最容易失配。

curve_fit
怎么可能返回像这样绘制的参数,以及如何强制它坚持“真实”解决方案?或者在这种情况下可能有比 curve_fit 更好的函数?

python curve-fitting
1个回答
0
投票

呸,当然我在写完这篇文章后就明白了。

这是一个缩放问题,因为原始强度数字太低。

这对大多数数据来说都是完全合理的拟合:

def double_ln_func(t, a, b, p, c, q):
    return a + b * np.log(p * t) - c * np.log(q * t)

def double_ln_fit(t, y):
    y = y * 1e10
    
    popt, pcov = curve_fit(double_ln_func, t, y)#, p0=initial_guess)
    
    fitted_t = np.linspace(min(t), max(t), 100)
    fitted_y = double_ln_func(fitted_t, *popt) / 1e10
    
    return fitted_t, fitted_y, popt

它拒绝完全适合某些测量,但这是另一篇文章的主题。

© www.soinside.com 2019 - 2024. All rights reserved.