optimagic-dev / optimagic

optimagic is a Python package for numerical optimization. It is a unified interface to optimizers from SciPy, NlOpt and other packages. optimagic's minimize function works just like SciPy's, so you don't have to adjust your code. You simply get more optimizers for free. On top you get diagnostic tools, parallel numerical derivatives and more.
https://optimagic.readthedocs.io/
MIT License
255 stars 29 forks source link

Prepare estimagic for very noisy optimization problems #184

Closed janosg closed 5 months ago

janosg commented 3 years ago

Problem description

We have some local optimizers that can deal with some level of noise (pounders, pybobyqa and dfols) but they fail on very noisy problems such as our covid simulation model. In particular, the covid simulation model has the following features

Components we need

Exploration algorithms

By exploration algorithms I mean algorithms that evaluate the criterion function at random or deterministic points in the parameter space and save the results in a database. They can be simple or sophisticated in the sense that they try to focus on promising regions. Those algorithms might also produce an estimate of the function minimum, but we will probably not use that and instead analyze the function evaluations ourselves.

The key insight is that we do not have to implement any of the sophisticated algorithms ourselves. We can just use add existing optimization algorithms that explore the parameter space and use the fact that estimagic stores all parameters and function evaluations in a database.

I suggest the following algorithms:

We can of course also check out all the other algorithms available in those libraries. Typically, it is easy to add all at once.

Simply adding the exploration algorithms as optimizers, also answers basically all possible design questions we might have had (database layout, user interface, ...).

Meta analysis algorithms

While most of the above algorithms should in principle be able to produce a good parameter estimate on their own, we need our own meta analysis for the following reasons:

While it would be possible to add the meta algorithms as optimizers, it does not make much sense. The interface is just very different (bunch of databases instead of criterion function, never need any derivatives, no logging needed, ...). Instead I propose a meta_minimize and meta_maximize function. Internally implemented as meta_optimize with direction argument.

def meta_minimize(databases, params=None, algorithm="auto", constraints=None):
    """Minimize a function, given evaluations stored in databases.

    Args:
        databases (str, pathlib.Path or lists thereof): Paths to databases. 
        params (pd.DataFrame): Can be used to provide bounds or start values for any local
            optimization that might be run on a surrogate model.
        algorithm (str): One of ["auto", "gaussian_process", "ols"]. Determines which kind of surrogate
            model is used for the meta analysis. 
        algo_options (dict): Further keyword options for the algorithm
        constraints (list): Same as during optimization. 
    """

This would just be the user interface to internal meta minimization algorithms with an interface that abstracts aways from constraints, parameters labels and so on:

def take_best(criterion_values, parameter_values, lower_bounds, upper_bounds): # others might have more algo_options
    """Return the minimal entry of y and the corresponding entry in x.

    Args:
        criterion_values (numpy.ndarray): 1d numpy array with function evaluations. 
        parameter_values (numpy.ndarray): 2d numpy array. Each row is a parameter vector. This is already
            the internal parameter vector that is only subject to lower and upper bounds, no other
            constraints. 
        lower_bounds (numpy.ndarray): 1d numpy array with lower bounds. Has length parameter_values.shape[1]
        upper_bounds (numpy.ndarray): 1d numpy array with upper bounds. Has length parameter_values.shape[1]

    Returns:
        dict: Similar dictionary as an optimization algorithm would return.

    """
janosg commented 5 months ago

Solved better with tranquilo.