Scipy的fmin有时只在无穷大处停留

1 投票
1 回答
1342 浏览
提问于 2025-04-17 02:58

我正在使用Scipy的fmin搜索来计算某个分布与一些数据的拟合的对数似然值。我用fmin来寻找能让对数似然值最大的参数,像这样:

j = fmin(lambda p:-sum(log(likelihood_calculator(data, p))), array([1.5]), full_output=True)

(likelihood_calculator这个函数接收数据和一个参数,然后输出每个数据点的似然值数组。)

如果我们从一个能让似然值为0的参数开始搜索,那么对数似然值就是负无穷大(-inf),所以它的负和就是无穷大(inf)。理论上,fmin应该会远离这个初始参数,但实际上它却在这个值上停留了最大调用次数,然后返回这个值:

In [268]: print j
(array([ 1.5]), inf, 67, 200, 1)

我原以为这可能是fmin处理无穷大的问题,但如果我们去掉似然计算器,直接给一个0,结果就好多了:

In [269]: i = fmin(lambda p: -sum(log(p)), array([0]), full_output=1)
Warning: Maximum number of function evaluations has been exceeded.

In [270]: i
Out[270]: (array([  3.16912650e+26]), -61.020668415892501, 100, 200, 1)

如果我们使用一个全是0的数组,或者这些0是浮点数,或者使用fmin_bfgs,都会得到同样的正确结果。如果使用fmin_bfgs,函数调用时仍然会出现不正确的行为,但如果我们从一个不会让似然值为0的参数开始,fmin就能正常工作(也就不会出现无穷大)。

有什么想法吗?谢谢!

更新:

如果有一大块参数会导致似然值为零,我们可以把参数值推到边缘。如果参数足够接近边缘,fmin就能跳出零的范围,开始搜索。例如,当p<1时会得到无穷大,那么在p=0.99时fmin会正常工作,但在p=0.95时就不行了。

1 个回答

3

也许你的更新回答了这个问题。因为 fmin 使用的是一种向下的梯度算法,它会在你最开始猜测的附近寻找最陡峭的下降方向。如果你进入了一个参数区域,在这个区域里函数总是返回 inf(无穷大),那么这个算法就无法判断该往哪个方向走了。

撰写回答