【问题标题】:Scipy least squares positional argument issueScipy最小二乘位置参数问题
【发布时间】:2019-08-25 18:38:44
【问题描述】:

我正在尝试对以下数据进行稳健的非线性拟合:

r_fast:

[0.2065 0.2661 0.2026 0.22   0.2065 0.2661 0.264  0.2173 0.2615 0.2682
 0.407  0.4085 0.409  0.4045 0.405  0.3985 0.5235 0.5846 0.5171 0.5385
 0.6415 0.7661 0.699  0.6523 0.7745 0.7332 0.842  0.9085 0.909  0.8445
 0.84   0.8635]

a_fast:

[-43.3  -3.  -86.8 -10.5 -56.2  -2.5  -7.2 -12.2  -4.6  -9.  -21.3  -2.
  -3.2  -2.7  -5.8  -6.8 -15.5  -1.8 -22.1  -0.5  -8.7  -0.8   0.   -3.3
  -0.8  -0.8 -12.5  -0.5  -0.7   0.3  -1.   -1.2]

我尝试了以下方法。但是,我在这一行收到一个错误:

res_soft_l1 = least_squares(f, x, loss='soft_l1', f_scale=0.1, args=(r_fast, a_fast))

错误是:

f() missing 1 required positional argument: 'x2'

全部代码如下:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.optimize import least_squares
def f(r_fast, x0, x1, x2):
    return x[0] + r_fast**x[1] * x[2]
data= pd.read_table('/Users/Hrihaan/Desktop/Data.txt', dtype=float, header=None, sep='\s+').values
r_fast=data[:,1]
a_fast=data[:,2]
r_min=np.min(r_fast)
r_max=np.max(r_fast)
x = np.array([1.0, 1.0, 0.0])
rr= np.linspace(r_min, r_max, len(r_fast))
res_soft_l1 = least_squares(f, x, loss='soft_l1', f_scale=0.1, args=(r_fast, a_fast))
aa= f(rr, *res_soft_l1.x)
plt.xlabel('r_fast', fontsize=30)
plt.ylabel('a_fast', fontsize=30)
plt.scatter(r_fast, a_fast, c='burlywood', s=10**2)
plt.plot(rr, aa, linewidth=3, label='Power law fit')
plt.legend(fontsize=25, loc=8, framealpha=1.0, edgecolor='maroon') 
plt.show()

我无法弄清楚我错过了什么。任何帮助将不胜感激。提前致谢。

【问题讨论】:

    标签: python scipy least-squares


    【解决方案1】:

    这是因为x 需要 4 个参数,但只接收 3 个。 在least_squares(f, x, loss='soft_l1', f_scale=0.1, args=(r_fast, a_fast)) 行中,least_squares 使用以下参数调用f

    f(r_fast=x, x0=r_fast, x1=a_fast, x2=)
    

    如您所见,x2 不见了。无论如何,这些都无济于事,因为您的函数f 不使用x0x1x2

    您可以将函数定义更改为:

    def f(x, r_fast):
        return x[0] + r_fast**x[1] * x[2]
    

    least_squares 致电

    least_squares(f, x, loss='soft_l1', f_scale=0.1, args=(r_fast))
    

    【讨论】:

    • 谢谢,我尝试按照您的建议进行操作。但是,收到此错误: f() 接受 2 个位置参数,但给出了 33 个
    【解决方案2】:

    代码几乎没有问题。

    1. 该函数必须返回“残差”,即预测值与实际值 (y) 之间的误差,而不是预测值。我猜a_fast 是您的实际值。
    2. 要优化的参数必须始终是函数的第一个参数。在这种情况下 [x0, x1, and x2]
    3. 该函数的任何其他附加参数应作为args 传递给least_squares 函数。我相信“r_fast”是您的附加参数。

    以下代码是可以工作的最少代码。

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    from scipy.optimize import least_squares
    
    r_fast = np.array([0.2065 ,0.2661,0.2026,0.22,0.2065,0.2661,0.264,0.2173,0.2615,0.2682
    ,0.407,0.4085,0.409,0.4045,0.405,0.3985,0.5235,0.5846,0.5171,0.5385
    ,0.6415,0.7661,0.699,0.6523,0.7745,0.7332,0.842,0.9085,0.909,0.8445
    ,0.84,0.8635])
    a_fast = np.array([-43.3 , -3. , -86.8 ,-10.5 ,-56.2,  -2.5 , -7.2 ,-12.2,  -4.6  ,-9., -21.3  ,-2  , -3.2,  -2.7 , -5.8 , -6.8 ,-15.5 , -1.8, -22.1 , -0.5 , -8.7,  -0.8,   0. ,  -3.3 ,  -0.8,  -0.8, -12.5,  -0.5,  -0.7,   0.3 , -1. ,  -1.2])
    
    def f(X ,r_fast):
        x0 ,x1 ,x2 = X
        return x0 + r_fast**x1 * x2 -a_fast
    
    
    
    x_init = np.array([1.0, 1.0, 0.0])
    
    res_soft_l1 = least_squares(f, x_init, args= ([r_fast]) ,loss='soft_l1', f_scale=0.1)
    

    输出:

    res_soft_l1.x
    
    array([-5.43168803e+03,  1.31665146e-03,  5.43206946e+03])
    

    【讨论】:

    • 谢谢,这行得通。但是,我得到了一个小的 R_Sq 值。我相信这种方法将提供更高的 R_Sq。关于如何优化 R_Sq 有什么建议吗?
    • 预处理数据(去除异常值),提供更好的初始猜测可能会有所帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-16
    • 1970-01-01
    • 1970-01-01
    • 2021-02-17
    • 2019-02-25
    • 1970-01-01
    • 2019-07-19
    相关资源
    最近更新 更多