3

我正在尝试通过 估计不同分布的参数scipy.stats."some_dist".fit(),并且在检索有关正在使用的优化过程的任何信息时遇到了极大的困难。具体来说,我正在寻找 Hessian,这是大多数实现的算法输出,如此所述。

对于所有的优化,SciPy 返回一个名为 的对象OptimizeResult,其中包含有用的信息,例如 Hessian,那么在.fit()调用相同优化的一些数据之后如何得到这个?

4

1 回答 1

2

看起来需要一点源头潜水;幸运的是,它不需要复制大量源代码。这就是基本合身的工作原理:

from scipy.stats import cauchy
data = [0, 3, 4, 4, 5, 9]
res = cauchy.fit(data)   # (3.9798237305661255, 0.9205374643383732)

这就是修改它以返回 OptimizeResult 的方式:

from scipy.optimize import minimize
args = cauchy._fitstart(data)
x0, func, restore, args = cauchy._reduce_func(args, {})
res = minimize(func, x0, args=(data,), method='BFGS')

现在res

      fun: 14.337039523098689
 hess_inv: array([[ 0.23321703, -0.0117229 ],
       [-0.0117229 ,  0.36807373]])
      jac: array([ 0.0000000e+00, -1.1920929e-07])
  message: 'Optimization terminated successfully.'
     nfev: 32
      nit: 5
     njev: 8
   status: 0
  success: True
        x: array([3.9798262 , 0.92055376])

您可以将参数识别为res.x. 被最小化的函数是“惩罚 NNLF”(非负似然函数)。


顺便一提,

对于所有优化,SciPy 返回一个名为 OptimizeResult 的对象

是过度概括。这对于minimize方法来说是正确的。默认情况下scipy.stats.fit使用fmin,它不返回这样的东西。

因此,如果想要与 相同的输出fmin,可以安排,但那里不会有额外的信息。

from scipy.optimize import fmin
args = cauchy._fitstart(data)
x0, func, restore, args = cauchy._reduce_func(args, {})
res = fmin(func, x0, args=(data,))
print(tuple(res))   #(3.9798237305661255, 0.9205374643383732)

使用minimizewith method='Nelder-Mead' 具有基本相同的效果。您确实得到了一些额外的信息,但鉴于该方法是基于单纯形的(不计算导数),这些信息的用途有限。

res = minimize(func, x0, args=(data,), method='Nelder-Mead')
print(res)
print(tuple(res.x))

印刷

 final_simplex: (array([[3.97982373, 0.92053746],
       [3.97983057, 0.92060317],
       [3.97977536, 0.92059568]]), array([14.33703952, 14.33703953, 14.33703953]))
           fun: 14.337039523477827
       message: 'Optimization terminated successfully.'
          nfev: 58
           nit: 31
        status: 0
       success: True
             x: array([3.97982373, 0.92053746])
(3.9798237305661255, 0.9205374643383732)
于 2018-04-10T03:05:40.910 回答