Use optimize.minimize from scipy with 2 variables

2020-06-06 06:33发布

问题:

I didn't find a way to perform optimize.minimize from scipy with a multidimensional function. In nearly all examples an analytical function is optimized while my function is interpolated. The test data set looks like this:

x = np.array([2000,2500,3000,3500])
y = np.array([10,15,25,50])
z = np.array([10,12,17,19,13,13,16,20,17,60,25,25,8,35,15,20])
data = np.array([x,y,z])

While the function is like F(x,y) = z

What I want to know is what happens at f(2200,12) and what is the global maximum in the range of x (2000:3500) and y (10:50). The interpolation works fine. But finding the global maximum doesn't work so far.

The interpolation

 self.F2 = interp2d(xx, -yy, z, kind, bounds_error=False)

yields

<scipy.interpolate.interpolate.interp2d object at 0x0000000002C3BBE0>

I tried to optimize via:

x0 = [(2000,3500),(10,50)]
res = scipy.optimize.minimize(self.F2, x0, method='Nelder-Mead')

An exception is thrown:

TypeError: __call__() missing 1 required positional argument: 'y'

I think that the optimizer can't handle the object from the interpolation. In the examples the people used lambda to get values from their function. What do I have to do in my case?

Best, Alex

回答1:

First, to find global maximum (instead of minimum) you need to interpolate your function with opposite sign:

F2 = interp2d(x, y, -z)

Second, the callable in minimize takes a tuple of arguments, and interp2d object needs input coordinates to be given as separate positional arguments. Therefore, we cannot use interp2d object in minimize directly; we need a wrapper that will unpack a tuple of arguments from minimize and feed it to interp2d:

f = lambda x: F2(*x)

And third, to use minimize you need to specify an initial guess for minimum (and bounds, in your case). Any reasonable point will do:

x0 = (2200, 12)
bounds = [(2000,3500),(10,50)]
print minimize(f, x0, method='SLSQP', bounds=bounds)

This yields:

  status: 0
 success: True
    njev: 43
    nfev: 243
     fun: array([-59.99999488])
       x: array([ 2500.00002708,    24.99999931])
 message: 'Optimization terminated successfully.'
     jac: array([ 0.07000017,  1.        ,  0.        ])
     nit: 43