【问题标题】:Non-linear Least Squares fit does not minimize非线性最小二乘拟合不会最小化
【发布时间】:2021-05-31 11:18:53
【问题描述】:

我试图用三个指数的总和来拟合衰减,并使用下面的代码。表面上看起来一切都很好,但优化并没有收敛(或为此做任何事情)。当我调用 lsq_res.x 时,我可以看到参数与最初的猜测相同。我怀疑最小化函数本身的问题 (def fun(x, t, y):...) 并且不确定我是否正确传递了变量。非常感谢您对此提供帮助,因为这也可以让我将其应用于其他模型!

import numpy as np
import matplotlib.pyplot as plt
import math
from scipy.optimize import least_squares

def Intensity(x_data, A21, T21, A22, T22, A23, T23, y0):
    I_model=A21*np.exp(-x_data/T21)+A22*np.exp(-x_data/T22)+A23*np.exp(-x_data/T23)+y0
    return I_model


#generate example data set (should be replaced by load of csv data file)
def gen_data(t, b1, c1, b2, c2, b3, c3, y0, noise=0, n_outliers=0, random_state=0):
    y = b1 * np.exp(-t / c1) + b2 * np.exp(-t / c2) + b3 * np.exp(-t / c3)+y0

    rnd = np.random.RandomState(random_state)
    error = noise * rnd.randn(t.size)
    outliers = rnd.randint(0, t.size, n_outliers)
    error[outliers] *= 10

    return y + error
# these are the parameters used to calculate the function, correspond to my first guess
y0 = 0.5
b1 = 0.25
c1 = .01
b2 = 0.4
c2 = .3
b3 = 0.35
c3 = 10

t_min = -3
t_max = 2
n_points = 1000

x_data = np.logspace(t_min, t_max, n_points)
y_data = gen_data(x_data, b1, c1, b2, c2, b3, c3, y0, noise=0.1, n_outliers=3) 

# the following is the minimization function where the appropriate model needs to be entered in the return line. 

def fun(x, t, y):
    return Intensity(x_data, A21, T21, A22, T22, A23, T23, y0) - y_data 
x0 = np.array([A21, T21, A22, T22, A23, T23, y0]) # give starting values for the fit parameters in the model


res_lsq = least_squares(fun, x0, args=(x_data, y_data)) #this performs the actual minimization of

y_lsq = gen_data(x_data, *res_lsq.x)

【问题讨论】:

    标签: python least-squares scipy-optimize


    【解决方案1】:

    正如我看到的问题,您尝试为强度函数找到最佳参数。

    我建议你使用 scipy 的 curve_fit 函数。

    import numpy as np
    from scipy.optimize import curve_fit
    
    def Intensity(x_data, A21, T21, A22, T22, A23, T23, y0 ):
        I_model=A21*np.exp(-x_data/T21)+A22*np.exp(-x_data/T22)+A23*np.exp(-x_data/T23)+y0
        return I_model
    
    
    #generate example data set (should be replaced by load of csv data file)
    def gen_data(t, b1, c1, b2, c2, b3, c3, y0, noise=0, n_outliers=0, random_state=0):
        y = b1 * np.exp(-t / c1) + b2 * np.exp(-t / c2) + b3 * np.exp(-t / c3)+y0
    
        rnd = np.random.RandomState(random_state)
        error = noise * rnd.randn(t.size)
        outliers = rnd.randint(0, t.size, n_outliers)
        error[outliers] *= 10
    
        return y + error
    
    #%%
    # these are the parameters used to calculate the function, correspond to my first guess
    y0 = 0.5
    b1 = 0.25
    c1 = .01
    b2 = 0.4
    c2 = .3
    b3 = 0.35
    c3 = 10
    
    t_min = -3
    t_max = 2
    n_points = 1000
    
    x_data = np.logspace(t_min, t_max, n_points)
    y_data = gen_data(x_data, b1, c1, b2, c2, b3, c3, y0, noise=0.1, n_outliers=3)
    
    res = curve_fit(Intensity, x_data, y_data) 
    

    可以在here 找到文档。希望我没有误解你的问题。

    如果你想最小化函数,你应该提供静态参数值和变量的初始猜测。 在您的问题中,没有给出参数值。

    【讨论】:

    • 感谢您将我指向curve_fit!这有助于解决我的问题,我现在能够执行非线性最小二乘拟合。
    • 不用担心,您可以将问题标记为已回答并点赞吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-29
    • 2017-02-24
    • 1970-01-01
    • 2012-06-29
    • 2013-06-12
    • 1970-01-01
    • 2014-03-05
    相关资源
    最近更新 更多