为什么scipy.optimize.minimize试图将奇怪的参数传递给我的目标函数?

时间:2015-04-25 23:56:38

标签: python scipy mathematical-optimization

我有一个帮助实例化统计模型的类。它的一些数据成员是参数。我正在尝试编写一个优化这些参数的方法。异议函数基于似然函数的否定。该似然函数本身实现为类方法,该方法在其计算中使用类数据成员的值。

我知道这是一种糟糕的风格,但每次scipy.optimize.minimize()调用目标函数时,它都会将对象数据成员更改为更好的成员。我不太关心为什么这是坏的,更关心为什么这不起作用。代码下面是完整的追溯。

它似乎部分有效。它在测试数据上运行几秒钟,但随后它会触发我的断言。似乎minimize()在接近优化结束时做了一些奇怪的事情。为什么它会尝试将不同类型的参数传递给目标函数obj_fun()?在我的IPython解释器中,我之后检查了对象的参数,它似乎达到了预期的结果。

我试着查看一些scipy的来源。但这很令人困惑。有很多模糊的变量命名和函数包装。任何人都可以给我一些关于为什么会发生这种情况的颜色,以及如何解决它?我想再次将这些优化内容保留在我的课程中。

class MyThing(object):
    .
    .
    .
    def mle_fit(self, y, inpt, optim_these):
        #step 1: figure out what you want to optimize
        self.optimize_these = optim_these
        #step 2: get inital flat parameter vector 
        self._make_list_optimizable_hyp_pars()
        init_guess = self.flat_hyper_params
        #step 3: run minimize
        def obj_fun(pars):
            # returns negative log likelihood 
            assert len(pars) == len(init_guess) # HERE #
            self.flat_hyper_params = pars
            self._unflatten_new_hps()
            self.like(y, inpt)
            return .5 * self.neg_2_log_like

        res = minimize(obj_fun, init_guess, method = 'BFGS')

回溯:

  File "/home/taylor/anaconda/lib/python2.7/site-packages/scipy/optimize/_minimize.py", line 419, in minimize
    return _minimize_bfgs(fun, x0, args, jac, callback, **options)

  File "/home/taylor/anaconda/lib/python2.7/site-packages/scipy/optimize/optimize.py", line 850, in _minimize_bfgs
    old_fval, old_old_fval)

  File "/home/taylor/anaconda/lib/python2.7/site-packages/scipy/optimize/optimize.py", line 690, in _line_search_wolfe12
    old_fval, old_old_fval)

  File "/home/taylor/anaconda/lib/python2.7/site-packages/scipy/optimize/linesearch.py", line 263, in line_search_wolfe2
    derphi0, c1, c2, amax)

  File "/home/taylor/anaconda/lib/python2.7/site-packages/scipy/optimize/linesearch.py", line 363, in scalar_search_wolfe2
    phi0, derphi0, c1, c2)

  File "/home/taylor/anaconda/lib/python2.7/site-packages/scipy/optimize/linesearch.py", line 498, in _zoom
    phi_aj = phi(a_j)

  File "/home/taylor/anaconda/lib/python2.7/site-packages/scipy/optimize/linesearch.py", line 239, in phi
    return f(xk + alpha * pk, *args)

  File "/home/taylor/anaconda/lib/python2.7/site-packages/scipy/optimize/optimize.py", line 281, in function_wrapper
    return function(*(wrapper_args + args))

  File "MyThing.py", line 222, in obj_fun
    assert len(pars) == len(init_guess)

1 个答案:

答案 0 :(得分:1)

如果我没记错的话,SciPy在优化时可以将标量和数组都发送到最小化的函数中。因此,如果您优化f(x),您会得到x = 3.14x = array([1, 4])。 (这将用于加速计算,对于使用NumPy数组函数的目标函数f。) 如果确实如此,让代码处理这将解决问题。

现在,您可以使用print pars, type(pars), len(pars)中的obj_fun()等支票轻松查看情况。