将其他参数传递给numdifftools Hessian

时间:2019-11-11 09:55:40

标签: python kalman-filter hessian log-likelihood

我想获得以下函数的黑森州:

def llik_scalars(param_vector, *args):
    Fsc = param_vector[0]
    Qsc = param_vector[1]
    Rsc = param_vector[2]

    y = args[0]
    burnin = args[1]

    F = np.matrix(Fsc)
    Q = np.matrix(Qsc)
    R = np.matrix(Rsc)

    predstate, predp, _, _ = kalmanfilter(F=F, Q=Q, R=R, y=y, plot = False)
    T = len(predp)
    predstate = np.array([predstate[t].item() for t in range(len(predstate))])
    predp = np.array([predp[t].item() for t in range(len(predp))])

    Sigmat = predp + Rsc
    Mut = predstate

    LL = 0
    for t in range(burnin, T):
        exponent = -0.5 * (y[t]-Mut[t])**2 / Sigmat[t]
        cc = 1 / math.sqrt(2*math.pi*Sigmat[t])
        LL -= math.log(cc*math.exp(exponent))
    return LL

我正在尝试使用numdifftools软件包的Hessian函数来完成此操作。 在文档中,我找到了以下信息。例如,如果您想要定义为Rosen的rosenbrock函数的粗麻布,则粗麻布的计算方法如下:

> H = nd.Hessian(rosen)([1, 1])

在点[1,1]中计算黑森州的位置

根据文档,应该可以为Hessian函数提供参数:

class Hessian(f, step=None, method=’central’, order=2, full_output=False, **step_options)
Parameters
fun [function] function of one array fun(x, *args, **kwds)

我通过以下方式尝试了这一点:

hess = nd.Hessian(kf.llik_scalars(themin.x, (y,burnin)))(themin.x)

themin.x是我要评估Hessian的点。

themin.x
Out[49]: array([0.67605231, 0.7457089 , 0.72205726])

运行上面的代码时出现的错误:

burnin = args[1]

IndexError: tuple index out of range

我不明白元组如何超出范围

1 个答案:

答案 0 :(得分:0)

在没有完整功能和参数的情况下调试电话有点困难,这就是为什么我只是使用rosen函数制作了一个简单示例。

我添加了两个伪造的附加参数,并将新函数命名为rosen_ext

将numdifftools导入为nd 将numpy导入为np

def rosen(x):
    return (1-x[0])**2 + 105.*(x[1]-x[0]**2)**2

def rosen_ext(x, *args):
    y = args[0]
    burnin = args[1]

    print(y)
    print(burnin)

    return (1-x[0])**2 + 105.*(x[1]-x[0]**2)**2

以您的方式调用Hessian的{​​{1}}时,我可以重现您的错误。

x = [2,2]中rosen_ext的{​​{1}}应该是

Hessian

要获得rosen的结果,您需要这样称呼:

[[4202. -840.]
 [-840.  210.]]

它返回一堆2和3(有助于查看是否正确放置了其他参数)和正确答案。

rosen_ext

使用这种方法,我想您的电话应该是这样的:

# call of the Hessian for the modified rosen in some point X = [2, 2]
H = nd.Hessian(rosen_ext)([2, 2], 2, 3)
print(H)

我无法调试它,所以请您检查一下是否可以运行?