【问题标题】:Curve-Fitting over an integral containing both a data array and function in pythonpython中包含数据数组和函数的积分的曲线拟合
【发布时间】:2019-04-17 19:10:31
【问题描述】:

我有一个由未知常数积分描述的数据集,我试图使用 python 的 curve_fit 来确定。但是,被积函数包含一个与数据集相乘的函数

def integrand(tm, Pm, args):
    dt, alpha1, alpha2 = args
    return Pm*(1-np.e**( -(alpha1 * (tm+dt))) )*np.e**(-(alpha2 * (tm+dt)))

其中 Pm 是收集的脉冲响应数据、脉冲数据图像和积分曲线的一维数组

橙色曲线代表脉冲数据,蓝色曲线是积分应该评估的结果

tm 是积分变量,dt, alpha1, alpha2 是未知常数,积分范围为 0 到 tm。

在这种积分上执行曲线拟合的最佳方法是什么,或者可能是其他解决未知常数的方法?

The Data sets are linked here

【问题讨论】:

    标签: python signal-processing curve-fitting


    【解决方案1】:

    从数据集的长度来看,似乎意图是将被积函数(t)拟合到输出(t+dt)。 scipy 优化模块中有几个函数可用于执行此操作。举一个简单的例子,我们展示了一个使用 scipy.optimize.leastsqr() 的实现。有关详细信息,请参阅scipy optimize的教程

    基本方案是创建一个函数,该函数在独立坐标上评估模型函数,并返回一个包含残差、模型和每个点的观察值之间的差异的 numpy 数组。 leastsq() 找到一组参数的值,使残差的平方和最小。

    我们需要注意的是,拟合可能对初始猜测很敏感。 模拟退火通常用于找到可能的全局最小值,并在细化拟合之前提供拟合参数的粗略估计。此处用于初始猜测的值仅用于概念目的。

    from scipy.optimize import leastsq
    import numpy as np
    
    # Read the data files    
    Pm = np.array( [ float(v) for v in open( "impulse_data.txt", "r" ).readlines() ] )
    print type(Pm), Pm.shape
    
    tm = np.array( [ float(v) for v in open( "Impulse_time_axis.txt", "r" ).readlines() ] )
    print type(tm), tm.shape
    
    output = np.array( [ float(v) for v in open( "Output_data.txt", "r" ).readlines() ] )
    print type(output), output.shape
    
    tout = np.array( [ float(v) for v in open( "Output_time_axis.txt", "r" ).readlines() ] )
    print type(tout), tout.shape
    
    # Define the function that calculates the residuals
    def residuals(  coeffs, output, tm ):
        dt, alpha1, alpha2 = coeffs
        res = np.zeros( tm.shape )
        for n,t in enumerate(tm):
            # integrate to "t"
            value = sum( Pm[:n]*(1-np.e**( -(alpha1 * (tm[:n]+dt))) )*np.e**(-(alpha2 * (tm[:n]+dt))) )
            # retrieve output at t+dt
            n1 = (np.abs(tout - (t+dt) )).argmin()
            # construct the residual
            res[n] =  output[n1] - value
        return res
    
    # Initial guess for the parameters
    x0 = (10.,1.,1.)
    
    # Run the least squares routine
    coeffs, flag = leastsq( residuals, x0, args=(output,tm) )
    
    # Report the results
    print( coeffs )
    print( flag )
    

    【讨论】:

    • 尝试此方法导致错误响应:“具有多个元素的数组的真值不明确。使用 a.any() 或 a.all()”。根据您的建议,我已包含指向相关数据集的链接
    • 好的,这是一个关于如何去做的示意图。我会尝试找一些时间使用您的数据来构建一个特定的示例。
    • @J.zendejas。就是这样,让我们​​看看它是否适合你。您将需要对参数进行合理的猜测。由于积分的缘故,它的拟合很长,本质上是每个 t 处的 t 循环。
    • 我还不能让它完全工作,但它帮助取得了进展,我会继续努力,谢谢你的帮助!
    • 可能值得尝试模拟退火作为初步循环,然后使用最小二乘法优化结果。但是,请注意,一些退火器会对参数的每个候选配置进行改进(我记得优化模块中的退火器就是这样做的)。这通常是不必要的,并且可能会使您的问题变得过于昂贵(即缓慢)。在选择与最佳局部最小值对应的配置之前,您很可能希望保存最小二乘。我会尝试找一些时间来研究一下,也许会编辑答案。
    猜你喜欢
    • 2022-01-13
    • 2018-10-09
    • 1970-01-01
    • 1970-01-01
    • 2022-11-29
    • 2015-07-01
    • 2021-01-30
    • 2018-10-07
    相关资源
    最近更新 更多