【问题标题】:How to set bounds for only one parameter如何只为一个参数设置界限
【发布时间】:2020-08-25 22:06:41
【问题描述】:

我正在使用 scipy.optimize 中的 curve_fit 来拟合我的数据。我有一个适合三个参数(Z1、Z2、Z3)的函数。我想提供界限。但是,我只想提供对 Z2 的限制(Z2 应低于 40)。我不想为 Z1 和 Z3 设置界限。那可能吗?

            popt, pcov = curve_fit(func, xdata, ydata, p0 = [Z1, Z2, Z3],
                           bounds = ((10, 20, 5), (100, 50, 100,)))

            # This way I provide bounds to Z1, Z2 and Z3
            # I, however, only want to say that Z2 < 40
            # Also interesting would be to say Z2 < Z1, with no bounds for Z1 or Z3

【问题讨论】:

    标签: python scipy curve-fitting bounds


    【解决方案1】:

    这里我提供了一个伪代码解决方案,它只使用参数的重新映射而不是实际的边界条件

    最初我们会这样做:

    bestA, bestB, bestC = fit( function( x, a, b, c, guesses=( guessA, guessB, guessC) ) )
    

    但是,我们想要 b

    wrapper_function( x, a, d, c ) = function( x, a, c - d**2, c )   
    bestA, bestD, bestC = fit( wrapper_function( x, a, d, c ) )
    

    像这样b 发送到function() 的值将始终小于c。 假设拟合收敛,我们只计算b = c - d**2。如果我们也对b 的错误感兴趣,我们必须进行错误传播,包括相关性。 (参见例如 Joel Tellinghuisen, J. Phys. Chem. A 2001, 105, 3917-3921)

    所以s_b**2 = gT V g。其中V 是方差-协方差矩阵,g = df/duu in [a, d, c]。那是gT=(0, -2 * bestD, 1 )

    现在我们想要b &lt; min( c, 40 )。也就是说,正如我在评论中提到的,有点复杂,但也是可能的。我们重写包装函数并有

    wrapper_function( x, a, d, c ) = function( x, a, 0.5 * ( c + 40 - abs( c - 40 ) ) - d**2, c )   
    bestA, bestD, bestC = fit( wrapper_function( x, a, d, c ) )
    

    这可能并不明显,但如果有人绘制0.5 * ( c + 40 - abs( c - 40 ) ),它就会变得清晰。再次直接计算b。不过,对于错误,我们必须小心计算g。我们得到

    g = ( 0, -2 * bestD, 1 - numpy.heaviside( bestC - 40, 0.5 ) )
    

    注意:如果c 的值和错误使得重映射的不连续性在误差范围内,则需要重新考虑。

    【讨论】:

      【解决方案2】:

      来自documentation

      bounds:array_like 的 2 元组,可选

      参数的下限和上限。默认为无边界。元组的每个元素必须是长度等于的数组 参数的数量,或一个标量(在这种情况下,界限是 所有参数都被认为是相同的。)使用 np.inf 和 适当的标志来禁用所有或部分参数的界限。

      因此,您只需提供 np.inf 作为 Z1 和 Z3 的上限和 -np.inf 作为 Z1 和 Z3 的下限:

      import numpy as np
      popt, pcov = curve_fit(func, xdata, ydata, p0 = [Z1, Z2, Z3],
                                 bounds = ((-np.inf, -np.inf, -np.inf), (np.inf, 40, np.inf)))
      

      【讨论】:

      • 感谢您的回复!我不明白如何说 Z2
      • @Alfred ...所以...这是什么:Z2 &lt; Z1Z2 &lt; 40Z2 &lt; min(Z1,40)
      • @mikuszefski 对不起,我忘了标记。中间的还好。但我不知道如何实现第一个和最后一个。类似于:1) (-np.inf, -np.inf. -np.inf), (np.inf, &lt; Z1, np.inf)) 和 3) (-np.inf, -np.inf. -np.inf), (np.inf, 40 and &lt; Z1, np.inf))
      • @Alfred first 很容易通过将 fit 函数中的参数从 z2 更改为 z1- z4**2 来实现。这小于z1,您可以通过错误传播获得相应的z2。因此,您根本不需要界限。您可以通过稍微复杂一点的方式来实现第三个版本。
      • 第三种情况可以由0.5 * ( z1 + 40 - abs( z1 - 40 ) ) - z4**2完成。 abs 不是最好的衍生品,但它应该可以工作
      猜你喜欢
      • 2016-02-08
      • 1970-01-01
      • 2020-03-02
      • 2013-06-26
      • 1970-01-01
      • 1970-01-01
      • 2021-12-02
      • 2023-03-11
      • 1970-01-01
      相关资源
      最近更新 更多