繁体   English   中英

scipy.optimize.leastsq in Python 在拟合数据时不返回协方差矩阵

[英]scipy.optimize.leastsq in Python not returning covariance matrix when fitting data

我正在使用 optimize.leastsq 来拟合我从穆斯堡尔光谱实验中收集的数据。 数据拟合成功,返回的最佳拟合参数良好。 但是当我想象我应该得到一个矩阵时,第二个 output cov_x,如文档中所称,给出了 1 的 integer。 为什么会发生这种情况以及如何获得正确的矩阵?

编辑:@slothrop 澄清说,我认为是 cov_x 的 output 实际上是 ier,一个 integer 代表一个错误。 1 代表 [“平方和的实际和预测相对减少\n 最多为 %f” % ftol,无]。 谁能帮我理解这是什么意思?

编辑 2:已解决。 @slotrop 礼貌地告诉我,我必须传递参数 full_output=1 才能让 optimize.leastsq 返回 cov_x。

PS 我不想使用 optimize.curve_fit 因为我想将参数作为列表而不是单个变量传递给我的 model function。

文档: https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.leastsq.html

这是我的代码。 由于我想概括为任意起点、终点,它的某些部分似乎是不必要的。

import numpy as np
import matplotlib.pyplot as plt
from scipy import optimize, signal

# sample of data

x = np.array([100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179])
y = np.array([17714, 17582, 17377, 17292, 17210, 17248, 16667, 16479, 16609, 16461, 16584, 16898, 17033, 17162, 17231, 17349, 17420, 17762, 17650, 17511, 17607, 17525, 17818, 17628, 17576, 17576, 17865, 17963, 18005, 17860, 17769, 17935, 17829, 17770, 17847, 17855, 18085, 18123, 17706, 17790, 17766, 17864, 17864, 18094, 17826, 17662, 17693, 17767, 17905, 17805, 17738, 17812, 17690, 17722, 17747, 17679, 17763, 17405, 17570, 17396, 17291, 16892, 16727, 16797, 17003, 17180, 17245, 17436, 17565, 17388, 17522, 17504, 17715, 17585, 17782, 17652, 17736, 17897, 17766, 17789])


def lorentz(x, xpeak, linewidth, intensity):    # parameters: xpeak, linewidth, intensity
    return -intensity*(linewidth/2)**2/((x-xpeak)**2+(linewidth/2)**2)

def curve_fit(start,stop):
    
    xp_est = signal.find_peaks(-y[start:stop], width=5, height=-17250)[0]    # parameter estimates
    xp_est = start + xp_est
    npeaks = np.size(xp_est)
    lw_est = np.full(npeaks,7)
    I_est = (17800-y[xp_est])
    estimates = [xp_est, lw_est, I_est]
        
    def model(x, par):    # sum of lorentz distributions of peaks
        
        xpeak = par[:npeaks]
        linewidth = par[npeaks:2*npeaks]
        intensity = par[2*npeaks:]
        
        lorentz_sum = 17800
        for i in range(npeaks):
            lorentz_sum = lorentz_sum + lorentz(x,xpeak[i],linewidth[i],intensity[i])
        return lorentz_sum
    
    def residual(par, x, y):     
        return y - model(x, par)
    
    par, cov = optimize.leastsq(residual, estimates, (x[start:stop], y[start:stop]))
    plt.plot(x[start:stop], y[start:stop], '.', markersize=2)
    plt.plot(x[start:stop], model(x[start:stop], par))
    
    return par, cov

par, cov = curve_fit(0, 80)
print(par, type(par))
print(cov, type(cov))
plt.show()

Output

[ 162.67354556  108.5074825     5.99266549    7.74311055 1048.1092175
 1361.99804297] <class 'numpy.ndarray'>
1 <class 'int'>
[link]

https://i.stack.imgur.com/Ixqql.png

默认情况下,它只输出结果(一维数组)和一个 integer 标志(你得到的 integer 数字)。 如果你想要完整的 output,使用这个:

x0, cov, info, msg, status = optimize.leastsq(residual, estimates, (x[start:stop], y[start:stop]), full_output=True)

cov就是你想要的

您必须在leastsq() function 中传递full_output=True参数

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM