【问题标题】:Nonlinear e^(-x) regression using scipy, python, numpy使用 scipy、python、numpy 进行非线性 e^(-x) 回归
【发布时间】:2023-03-05 04:41:01
【问题描述】:

下面的代码为我提供了一条最佳拟合线的平线,而不是沿着适合数据的 e^(-x) 模型的一条漂亮曲线。谁能告诉我如何修复下面的代码以使其适合我的数据?

import numpy as np  
import matplotlib.pyplot as plt
import scipy.optimize

def _eNegX_(p,x):
    x0,y0,c,k=p  
    y = (c * np.exp(-k*(x-x0))) + y0
    return y

def _eNegX_residuals(p,x,y):
    return y - _eNegX_(p,x)

def Get_eNegX_Coefficients(x,y):
    print 'x is:  ',x  
    print 'y is:  ',y 

    # Calculate p_guess for the vectors x,y.  Note that p_guess is the
    # starting estimate for the minimization.
    p_guess=(np.median(x),np.min(y),np.max(y),.01)

    # Calls the leastsq() function, which calls the residuals function with an initial 
    # guess for the parameters and with the x and y vectors.  Note that the residuals
    # function also calls the _eNegX_ function.  This will return the parameters p that
    # minimize the least squares error of the _eNegX_ function with respect to the original
    # x and y coordinate vectors that are sent to it.
    p, cov, infodict, mesg, ier = scipy.optimize.leastsq(  
        _eNegX_residuals,p_guess,args=(x,y),full_output=1,warning=True)

    # Define the optimal values for each element of p that were returned by the leastsq() function. 
    x0,y0,c,k=p  
    print('''Reference data:\  
    x0 = {x0}
    y0 = {y0}
    c = {c}
    k = {k}
    '''.format(x0=x0,y0=y0,c=c,k=k))  

    print 'x.min() is:  ',x.min()
    print 'x.max() is:  ',x.max()
    # Create a numpy array of x-values
    numPoints = np.floor((x.max()-x.min())*100)
    xp = np.linspace(x.min(), x.max(), numPoints)
    print 'numPoints is:  ',numPoints
    print 'xp is:  ',xp
    print 'p is:  ',p
    pxp=_eNegX_(p,xp)
    print 'pxp is:  ',pxp

    # Plot the results  
    plt.plot(x, y, '>', xp, pxp, 'g-')
    plt.xlabel('BPM%Rest') 
    plt.ylabel('LVET/BPM',rotation='vertical')
    plt.xlim(0,3)
    plt.ylim(0,4)
    plt.grid(True) 
    plt.show()

    return p

# Declare raw data for use in creating regression equation 
x = np.array([1,1.425,1.736,2.178,2.518],dtype='float')  
y = np.array([3.489,2.256,1.640,1.043,0.853],dtype='float')  

p=Get_eNegX_Coefficients(x,y)

【问题讨论】:

    标签: python statistics numpy scipy scientific-computing


    【解决方案1】:

    您最初的猜测似乎有问题; (1, 1, 1, 1) 之类的东西可以正常工作:
    你有

    p_guess=(np.median(x),np.min(y),np.max(y),.01)
    

    函数

    def _eNegX_(p,x):
        x0,y0,c,k=p  
        y = (c * np.exp(-k*(x-x0))) + y0
        return y
    

    那就是 test_data_maxe^(-.01(x - test_data_median)) + test_data_min

    我对选择好的起始参数的艺术了解不多,但我可以说几句。 leastsq 在这里找到一个局部最小值 - 选择这些值的关键是找到合适的山来攀登,而不是试图减少最小化算法必须做的工作。您最初的猜测如下所示 (green): (1.736, 0.85299999999999998, 3.4889999999999999, 0.01)

    这会导致您的平线(蓝色): (-59.20295956, 1.8562 , 1.03477144, 0.69483784)

    与增加 k 值相比,调整线的高度获得了更大的收益。如果您知道自己适合这种数据,请使用更大的 k。如果您不知道,我想您可以尝试通过对数据进行采样或从上半年和下半年的平均值之间的斜率回溯来找到一个不错的 k 值,但我不知道该怎么做关于那个。

    编辑:您也可以从几个猜测开始,多次运行最小化,然后选择残差最低的线。

    【讨论】:

    • 猜测k 的另一个简单选项是只使用y.ptp() / x.ptp()(即点的斜率)。无论如何,它应该进入球场。如果k 的值通常不接近 0.01,那肯定比最初的固定起始猜测 0.01 更好!无论如何,我要 +1... 这绝对是一开始的猜测的问题。
    • 这对我很有帮助,谢谢。我认为这个问题已经得到解答。
    • @MedicalMath,那为什么不点击绿色复选标记并奖励他的回答。
    猜你喜欢
    • 1970-01-01
    • 2016-07-21
    • 2018-02-03
    • 1970-01-01
    • 1970-01-01
    • 2015-01-19
    • 2016-04-19
    • 2021-03-11
    • 2018-07-23
    相关资源
    最近更新 更多