3

我正在尝试使用作为ROOT数据分析框架的一部分的 Minuit2 最小化器为具有物理限制的参数生成等高线图。不幸的是,当我尝试生成等高线图时,Minuit2 似乎有意将参数漂移到超出其限制的区域:

>>> from minuit2 import Minuit2
>>> def f(x,y):
...     if x < 0 or y < 0:
...             print 'x = %.2f, y = %.2f' % (x,y)
...             raise Exception
...     return x**2 + y**2
... 
>>> m = Minuit2(f)
>>> m.limits['x'] = 0, 10
>>> m.limits['y'] = 0, 10
>>> m.migrad()
>>> xy = m.contour('x','y',3)
Info in <Minuit2>: MnMinos UP value has changed, need to update FunctionMinimum class
x = -9.95, y = 0.00
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in f
Exception

有没有其他人处理过这个或类似的问题?有什么解决方法吗?

我已经在ROOT 论坛上问过这个问题,但我认为可能还有一些堆栈溢出用户已经处理过这个或类似的问题。

4

1 回答 1

0

在不引发异常的情况下尝试您的示例

def f(x,y):
    return x ** 2 + y ** 2

并且您将获得合理的 xy 轮廓点(即在真实轮廓的 1e-3 范围内)。

请注意,sigmas=3您的轮廓调用中的参数m.contour('x', 'y', 3)意味着sigmas ** 2 == 9将计算轮廓,并计算沿参数限制的轮廓点。据我所知, contour() pyminuit 文档中没有提到这一点)。在您的示例中,轮廓从 开始(0, 0),上升到(3, 0),沿着圆圈到(0, 3),然后返回到(0, 0)

一种常见的方法是通过为排除的参数返回非常高的值来在成本函数中实现参数限制(任意形状,不仅是最小值/最大值):

def f(x,y):
    if x < 0 or y < 0:
        return 1e10
    return x ** 2 + y ** 2

这确实将优化器抛出了禁止区域,但它并不阻止它有时探测它们(即f在那里评估)。

我不知道为什么contour()要严格遵守您设置的限制

m.limits['x'] = 0, 10
m.limits['y'] = 0, 10

这是 Minuit(和 Minuit2)使用的轮廓算法的简短描述,这里是ROOT 中 Minuit2 代码的文档,我没有找到显示实现的实际 C 文件。

于 2012-07-27T10:23:37.050 回答