【问题标题】:fitting an inverse proportional function拟合反比例函数
【发布时间】:2019-04-17 17:18:14
【问题描述】:

我想将函数 f(x) = b + a / x 拟合到我的数据集。为此,我发现来自 optimize 的 scipy leastsquares 是合适的。

我的代码如下:

x = np.asarray(range(20,401,20))

y 是我计算的距离,但是是一个长度为 20 的数组,这里只是以随机数为例

y = np.random.rand(20)

对参数 a 和 b 的初步猜测:

params = np.array([1,1])

最小化函数

def funcinv(x):
    return params[0]/x+params[1]

res = least_squares(funinv, params, args=(x, y))

给出的错误:

 return np.atleast_1d(fun(x, *args, **kwargs))

TypeError: funinv() 接受 1 个位置参数,但给出了 3 个

如何拟合我的数据?

【问题讨论】:

    标签: python scipy


    【解决方案1】:

    为了澄清一点。有两个相关的问题:

    1. 最小化函数
    2. 将模型拟合到数据

    将模型拟合到观察数据就是找到模型的这样的参数,这些参数最小化模型数据和观察数据之间的某种误差

    least_squares 方法只是最小化关于x 的跟随函数(x 可以是一个向量)。

    F(x) = 0.5 * sum(rho(f_i(x)**2), i = 0, ..., m - 1)

    rho 是一个损失函数,默认是rho(x) = x 所以暂时不要介意)

    least_squares(func, x0) 期望调用func(x) 将返回一个向量[a1, a2, a3, ...],将为其计算平方和:S = 0.5 * (a1^2 + a2^2 + a3^2 + ...)

    least_squares 将调整x0 以最小化S

    因此,为了使用它来拟合模型到数据,必须在模型和实际数据之间构建一个误差函数 - residuals,然后最小化该 residuals功能。在你的情况下,你可以这样写:

    import numpy as np
    from scipy.optimize import least_squares
    
    x = np.asarray(range(20,401,20))
    y = np.random.rand(20)
    params = np.array([1,1])
    
    def funcinv(x, a, b):
        return b + a/x
    
    def residuals(params, x, data):
        # evaluates function given vector of params [a, b]
        # and return residuals: (observed_data - model_data)
        a, b = params
        func_eval = funcinv(x, a, b)
        return (data - func_eval)
    
    res = least_squares(residuals, params, args=(x, y))
    

    这给出了一个结果: print(res)

    ... 
    message: '`gtol` termination condition is satisfied.'
        nfev: 4
        njev: 4   optimality: 5.6774618339971994e-10
        status: 1
        success: True
        x: array([ 6.89518618,  0.37118815])
    

    然而,作为一个残差函数几乎一直是相同的 (res = observed_data - model_data),scipy.optimize 中有一个快捷方式,称为curve_fitcurve_fit(func, xdata, ydata, x0)curve_fit 自动构建残差函数,你可以简单地写:

    import numpy as np
    from scipy.optimize import curve_fit
    
    x = np.asarray(range(20,401,20))
    y = np.random.rand(20)
    params = np.array([1,1])
    
    def funcinv(x, a, b):
        return b + a/x
    
    res = curve_fit(funcinv, x, y, params)
    print(res)  #  ... array([ 6.89518618,  0.37118815]), ...
    

    【讨论】:

      猜你喜欢
      • 2014-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      • 2021-04-30
      相关资源
      最近更新 更多