Giter VIP home page Giter VIP logo

opensourceeconomics / estimagic Goto Github PK

View Code? Open in Web Editor NEW
227.0 227.0 27.0 26.6 MB

Estimagic is a Python package for nonlinear optimization with or without constraints. It is particularly suited to solve difficult nonlinear estimation problems. On top, it provides functionality to perform statistical inference on estimated parameters.

Home Page: https://estimagic.readthedocs.io/

License: MIT License

Python 99.97% HTML 0.02% CSS 0.01%
numerical-differentiation numerical-optimization parallel-computing python statistical-inference

estimagic's People

Contributors

aidatak97 avatar alanlujan91 avatar amageh avatar asouther4 avatar baharcos avatar christianzimpelmann avatar hmgaudecker avatar jacekb95 avatar janosg avatar lindamaok899 avatar loikein avatar luiscald avatar maxblesch avatar mchandra12 avatar mo2561057 avatar mpetrosian avatar pre-commit-ci[bot] avatar roecla avatar segsell avatar sidd3888 avatar sofiabadini avatar sofyaakimova avatar stelios-c avatar timmens avatar tobiasraabe avatar vgangaprasad avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

estimagic's Issues

Documentation of corner cases in constraints

This occurred to me in the context of thinking about #61: What happens if you set the upper bound and lower bound of a parameter to be equal but don't specify it to be fixed? Will it

  1. be treated as a fixed parameter by estimagic or
  2. left to the optimizer to handle or
  3. raise an error or
  4. ?

I could not find it in the docs and don't have time to play around.

My 2c if behavior has not been set explicitly: I would suggest 3 - requiring the user to do it the right way seems not be too much to ask... In any case, 2. is evil (you would see "weird" stuff if the code pondered in #57 was implemented -- rather fail early).

Re-use bokeh server

Current Situation

Every optimization starts its own bokeh server. When doing several optimizations in parallel on a remote computer, you have to configure many ports to see the different dashboards. For jupyter notebooks I can run just one server and then still open several notebooks.

Desired Situation

There should be a way to have several dashboards use the same bokeh server. This server could either be started manually or even better by the first optimization. When it gets started there should be an overview page that shows which dashboards are running. Then the individual dashboards can be selected and opened in new tabs.

This would also be very useful for pseudo global optimizations or any kind of parallelizing optimizer.

Implementation

I have no idea. Maybe @roecla can make a proposal.

autodoc documentation of the differentiation module fails

When trying to compile the estimagic documentation with Sphinx I get the following warnings:

WARNING: autodoc: failed to import function 'differentiation.gradient' from module 'estimagic.differentiation'; the following exception was raised:
No module named 'numdifftools'
WARNING: autodoc: failed to import function 'differentiation.hessian' from module 'estimagic.differentiation'; the following exception was raised:
No module named 'numdifftools'
WARNING: autodoc: failed to import function 'differentiation.jacobian' from module 'estimagic.differentiation'; the following exception was raised:
No module named 'numdifftools'

In the rendered documentation the documentation of the mentioned functions are missing.

I made sure that numdifftools is in my environment. Maybe it has to be added to sphinx in some way extra?

Allow user to specify steps for numdifftools, scaling

I set the Richardson extrapolation version running yesterday. Still running.

I would be willing to sacrifice some precision for speed here; surely for testing. So it would be great if it was possible to pass the options step_ratio=2.0, step=1, order=1, num_terms=2 there. Although I must admit that I have not gotten my head what precisely they do yet.

I have not really verified, but it seems to me that the steps are absolute. They certainly were for the manually specified finite-differencing derivative. With large parameter values, this leads to numerical error dominating. To be on the safe side here, I would suggest dividing by the absolute value of the parameter value.

Rewrite _create_algorithm

Problem

Currently create_algorithm is very minimal and does not allow to configure the algorithms.

Task

  • pass the algorithm options through
  • document the options for each algorithm
  • make sure that all defaults are sensible and change them if necessary

Improve gradient based optimization

Notes

This might be a controversial issue. @tobiasraabe, @hmgaudecker, @roecla, @peisenha feel free to comment. If we implement this, #51 will be solved on the way.

Current Situation

If no gradient is specified, most optimizers will do some form of numerical differentiation. Since we don't influence this, we don't get any gradient information out and can't distinguish between function evaluations for gradient calculation and actually interesting function evaluations

Desired Situation

  • Distinguish between function evaluations done for gradient calculation (those should not be reflected in the convergence or fitness plots and probably don't have to be saved and logged) and actual function evaluations during the optimization
  • Plot the evolution of the gradient in the dashboard (similar to the parameter convergence plots)
  • Maybe: implement custom termination criteria based on gradient

Possible Implementation

Write a function that uses the fast (but not too precise) gradient functions from pygmo to calculate a numerical gradient. Pass this to the optimizers as custom gradient function. Inside the gradient function we would call a slightly different version of the internal_criterion that does not update the convergence plot in the dashboard and has a different iteration counter. After each evaluation, the gradient information is sent to the dashboard.

Discussion

The main disadvantage is that we could not guarantee to reproduce the same results as when the original library with their default numerical derivative is called. This should not make a difference and if it does, the optimization problem is probably very problematic anyways, but it is something we have to discuss.

Dashboard fails with large starting values or large initial fitness

When the dashboard is started with an extremely high value (order 1e17) the dashboard opens an empty tab with just the tab rider but with no plot. It also does not throw an Error.

When extremely high values are added to the ColumnDataSource later the dashboard does handle them (at least up to 1e20).

Make closed form derivatives optional for gradient based nlopt algorithms

Current Situation

gradient based nlopt algorithm require a user specified gradient function

Goal

Use numerical differentiation when the user does not specify one

Open questions

  • Should we use the estimagic functions for numerical derivatives or the ones from pygmo. Pygmo has probably a version that is imprecise but very fast, which is what we need here.

Make functions that use constraints fool-proof

Current situation

Some functions have to be called with processed constraints, others with user written constraints. This can be confusing for users.

Goal and Implementation

All public functions that take constraints as an argument get an additional boolean argument called processed which is by default False. If processed is False, the function calls process_constraints first.

This requires to change process_constraints such that it can be called with already processed constraints and in that case does nothing.

Remarks

  • We cannot simply omit the new argument and always call process_constraints first since process_constraints is a rather expensive function and I don't want to be forced to make it faster.
  • This is a good issue for someone who wants to develop a deeper understanding of how constraints are implemented in estimagic.

Size of plots in dashboard

Currently the size of all plots in the dashboard is hardcoded. This might not be optimal for all screen resolutions. Maybe there is a better way ...

Update Documentation

  • Adjust credit section with new contributions
  • Document the use of group and name columns in params
  • Improve the order and overall structure
  • More description of constraints, including tutorials and corner cases.
  • Write section about contributing
    • Describe the PR workflow
    • Explain how to run tests and activate pre-commit hooks locally
    • Explain importance of using environment.yml
    • Explain how important it is that functions have no side effects.

Add dashboard to monitor optimization

Goal

We want a bokeh dashboard with the following tabs:

  • Convergence Monitor: Interactive live convergence plots for different types of parameters. When clicking on one line, the others become opaque
  • Profiling Information: show snakeviz profile of criterion function
  • System Monitor: show resource usage
  • Log: show whatever is printed during the optimization

Resources

Add a robust cholesky decomposition to the utilities

Background

The standard cholesky decompositions in numpy.linalg and scipy.linalg only work for positive-definite covariance matrices. However, there are two places where we might want to take a cholesky factor of a covariance matrix that is only positive semi-definite:

  • During the reparametrization step (to_internal), if the user provided I covariance matrix that is only semi-definite in the start values
  • In user code, when we need a cholesky factor of of a covariance matrix for random number generation and the optimizer tried a semi-definite covariance matrix. We could directly use it in skillmodels and respy and then probably don't need the bounds_distance anymore.

Proposed Solution

Add a cholesky function based on an LDL decomposition. See also here

How much work is it

If we only want to accept square matrices as inputs, we'll just need a few lines. If we want the functions to work with higher dimensional arrays (i.e. shape [..., k, k]) we should wait until numba-scipy supports scipy.linalg.ldl

Make optimize.py more readable

Current situation

optimize.py has become increasingly complex and hard to read over time as features have been sequentially added.

There are three main reasons for this:

  1. 3 nested levels of minimize (_single, _internal)
  2. Differing layers of abstraction
  3. Scattering of tasks across the nested levels

Desired Situation

As one of the core modules of estimagic optimize.py should be an easy entry point into the code. For this the minimize function should read like a table of contents.

Proposed implementation

Rationale

minimize consists of five main steps:

  1. broadcast the user supplied arguments
  2. clean the arguments:
    Generate the inputs a perfect user would supply. This step includes:
    • _process_params
    • expand_criterion_output
    • handling maximizations
    • process_constraints
    • processing the algorithm (l. 477-490)
  3. create the internal inputs:
    This includes:
    • setting up the database
    • creating the internal objects (params, criterion, gradient)
  4. run the optimization (l. 494-532)
  5. post processing of the optimization results: This will include reparametrizing and harmonizing the output across supported algorithms.

The functions of 1., 2. and 5. should be imported from different modules as they are not at the core of optimize. The steps of 3. and 4. are central and would be included.

Pseudo Code

def minimize(...):
	# Step 1: called process_optimization_arguments at the moment
	raw_arguments, n_cores = broadcast_arguments(...) 

	# Step 2: convert to input of a perfect user
	cleaned_arguments = []
	for i, raw_arg in enumerate(raw_arguments):
		cleaned_arguments[i] = clean_and_check_arguments(raw_arg)

	# Step 3: create internal inputs
	internal_arguments = []
	for i, clean_arg in enumerate(cleaned_arguments):
		general_options, comparison_plot_data = _initial_evaluation(...)
		database = _initialize_database(...)
		
		internal_params = reparametrize_to_internal(...)
		internal_criterion = _create_internal_criterion(...)
		internal_gradient = _create_internal_gradient(...)

	# Step 4. Run the Optimization
	results = Parallel(n_jobs=n_cores)(
	    delayed(_single_minimize)(arg) for arg in internal_arguments)

	# Step 5. Process the optimization results
    results = process_optimization_results(results)
    return results

Notes

  • this will be much easier after the dashboard is rewritten and outside minimize
  • does process_constraints and processing the algorithm belong to the cleaning step or to creating internal inputs?

Switch sign in fitness plot when called from `maximize`

Current Situation

The fitness plot always displays a minimization problem

Desired situation

The dashboard knows whether it is running a maximization or minimization and changes the plot accordingly

Possible implementation

In estimagic.optimize we have _minimize and minimize am maximize. _minimize is an internal function that does most of the hard work. minimize is a public function and adds the dashboard. maximize calls minimize. This makes it hard to pass the information on whether a maximization or minimization is run into the dashboard. We could change it in the following way:

  • _minimize stays as it is. It's job is to provide a unified interface to minimizers from other libraries
  • There is a new internal function called _optimize that adds the dashboard (currently in minimize and the sign switch when needed (currently in maximize). Thus it is easy to pass the relevant information into the dashboard.
  • maximize and minimize are then constructed from _optimize with functools.partial

I can do all the interface changes, but will need @roecla's help for the actual dashboard change.

Error Handling during Optimization

Current situation

We do not catch errors during optimization.

Desired Situation

  • KeyboardInterrupt should abort the optimization and return a result object similar to a normal optimization result, but at current parameter values and with "success" = False. Do we need any other clean-up?
  • SystemExit should just be raised. All information about the current status is in the database. A question is if we should dump a pickle file with the current status if no logging is used.
  • For other errors, the desired outcome depends on the situation:
    • If the user code is correct, and the exception is due to extreme parameter values we want to continue and just return a very large criterion value.
    • During debugging, we want to raise them.

Problem of flat spots in invalid regions

Gradient based optimizers will usually reach invalid parameter regions during an "actual step" and then not leave them during the subsequent gradient evaluation. If we implement the above naively, the gradient would be 0 and some optimizers will interpret this as convergence (without doing further checks).

Assuming that the start parameters are valid, a simple way of avoiding this flat spot would be to make the penalty increasing in the euclidean distance to the start parameters. Intuitively, we would tell the optimizer to take a step back to where it started from when hitting invalid parameters (which is what I would do if I were an optimizer).

We can put the start_values in the params DataFrame (if we do not already have them). Then it is really easy to implement.

Proposed Implementation

We would first run one evaluation of the criterion function without error catching to make sure that the error is not due to user code. The internal criterion function used during optimization is then wrapped into a try-except block.

There is one new entry to general_options:

{"criterion_exception_penalty": (constant, slope)}

The penalty is:

min(HUGE_FLOAT, constant + slope * np.linalg.norm(params - start_params))

@tobiasraabe This is a bit different than what we talked about today, but I think it is much better and even simpler to implement. Can you do this as part of the decorator PR?

Do not use db as abbreviation for dashboard.

Current situation

we use db as abbreviation for dashboard, for example in db_options. However, for most people db is short for database and now that we have a database this becomes problematic.

Solution 1:

Write it out everywhere. This might, however, lead to very long variable names in some internal functions.

Solution 2:

Rename the dashboard to something that can be abbreviated or is shorter. Does anyone have a good idea? If so, please post here. So far I only came up with magic_board, abbreviated as mb.

Allow for user specified derivative functions during optimization

Current situation

We do pass a user specified gradient or hessian functions through to to the optimizer, but this function will be called with an internal parameter vector.

Desired situation

A user should not have to bother about the internals and be able to provide a gradient or hessian functions that work on an external parameter vector. Estimagic converts this automatically into a corresponding function that operates on an internal parameter vector.

Implementation

We will have to write closed form derivative functions for the reparametrization steps (from_internal) and use the chain rule. Everyone who has seen me taking derivatives knows that I will need help with the math. The most difficult one should be the cholesky transformation, but below I post some references.

Some references

Wrong order of automatically created lower bounds for sdcorr constraints

res["value"] = chol_coeffs

This line reassigns the cholesky coefficients such that the standard deviations are not at their original location. (The standard deviation which is the (n,n) entry of the cholesky decomposition is now at the last position) Thereafter I am getting errors because my box bounds are not valid anymore.(The code changes the lower bound of the first dim entries to zero these entries do however not only contain sd now but also non diagonal cholesky factors which can be negative) Am I using the constraints wrong or is this a mistake ?
To me it seems like

chol_coeffs = chol[np.tril_indices(dim)]
induces a wrong order or at least an order that is incompatible with the original lower and upper values.

Add scaling of the parameter vector

Scale the parameter vector by the inverse of the start parameters in reparametrize_to_internal and undo the scaling in reparametrize_from_internal.

Automatically open dashboard in browser.

Sure, it is not much to ask the user to copy-paste the localhost link, but it is more convenient, if the dashboard is opened automatically in another tab.

There is a stdlib module for that called webbrowser. Just insert

import webbrowser

webbrowser.open("http://localhost:2321")

From my experience, "http" seems necessary at least on Windows.

keep comparison_plot informative for very large numbers of models

Current situation

When too many models are passed to comparison_plot the scatter plot becomes uninformative

Goal and possible implementation

Keep comparison_plot informative even for very large numbers of models.

One way this could be done is to switch from a scatter_plot to a kde or histogram plot when the number of models passed to comparison_plot exceeds some threshold.

large parallelism results in database failure

Bug description

All continues to work well with the previous version of estimagic. However, when using the most recent version with the logging capabilities, the parallel workflow breaks down. See the attached screenshots.

To Reproduce

Unfortunately, I cannot reproduce the error on my local machine even when using mpiexec. We should probably discuss it over the phone on Thursday. I think I have isolated the problem to the UserWarning for the inability to write to the database.

Screenshots/Error messages

directory

logging

Add standard errors for MSM / GMM.

Now that the numerical differentiation is there, it would be great to add the matrix algebra bit for (nonlinear) GMM or the Method of Simulated Moments.

Section 13.25 / Page 525 of Bruce Hansen's book should do, else Davidson / MacKinnon is probably an even better reference, but I do not have a copy on my desk right now.

I am happy to provide guidance, I suppose @MaxBlesch you know your way around the code enough? Else we need to remember that thankfully, @janosg will not take his laptop along on vacation this time around!

maximize and minimize should return just one result

Current Behavior

The functions return a params DataFrame and a json serializable dictionary with other information about the optimization

Desired Behavior

Have one results object that contains all the information. This has the advantage that just one object has to be passed into visualization functions like the comparison plot.

Possible implementations

Add metadata to the params DataFrame

This would be the nicest interface and very useful in many places of estimagic, but it is probably impossible to implement. Of course we could add attributes to the DataFrame like here but they wouldn't be preserved after operations that make copies (merging, ...). There was an issue to change that, but my impression is that it won't be part of pandas soon. We don't want to make a custom subclass of DataFrame.

Put the DataFrame in the dictionary

The only problem here is that we lose the ability to save the dictionary as json. To do so, one would first have to make a copy of the dictionary without the DataFrame

Collect dictionary and df in a namedtuple (proposed solution)

The fields could be named params and info. While this is similar to putting the df in a dictionary, I think it has several advantages:

  • It is easier to split it into the json serializable dict and the df
  • Its two components are very simple and well known (a flat dict and the df). So it's very clear which operations can be done with them and there would never be a surprising loss of metadata
  • It is immutable, so people could not accidentally combine the params and info from different optimizations

@tobiasraabe @roecla I think I see this much clearer now than yesterday. So if you agree we could just assume this new interface in #26 and then implement it in the optimization in a separate PR.

logging and checkpointing

We need the ability for long estimations runs on compute servers. The use of the dashboard is not an option there. We need a lightweight logging infrastructure that writes information about the estimation progress to disk. This allows to monitor the optimization as it progresses and also to potentially restart at an intermediate outcome.

Using dashboard within waf-process causes waf to never terminate

Bug description

I am using skillmodels integrated in a waf-process to analyse some HRS data. Calling the fit method of SkillModel with dashboard=True opens up the dashboard as expected, but prevents the waf-process from finishing. That means I do not receive the 'build' finished succesfully message. I expected the waf-process to finish after ~3 hours on my computer (runtime with dashboard=False). The python script runs correctly and returns a csv-file in both cases.

To Reproduce

mod = SkillModel(model_dict=model_dict, dataset=dataset, model_name="baseline", dataset_name="hrs")
res = mod.fit(start_params=start_params, dashboard=True, algo_options={"ftol": 1e-5})

Expected behavior

I expected the waf-process to finish the build after ~3 hours. It did not finish after 8-9 hours even tough the expected output was saved in the bld-folder.

System

  • OS: Windows 10
  • Version 0.0.25

Change Interface of Sum and Probability Constraints to remove over-specification

Current Situation

When using sum and probability constraints, currently all involved parameters are part of the external params, even though one of them can be calculated from the others. During the reparametrization step we fix one of them and in the probability case enforce the remaining constraints via transformations. In this step we also make sure that the constraint holds. If we keep this we should make sure that the constraint holds in the external params vector up to floating point accurracy.

Proposed Change

Only specify free parameters in external params. This means that sum constraints would not do anything, i.e. could be dropped. Probability constraints would still do the transformation

Advantages of current implemenation

  • Parameter vector is easier to parse because all required transformations are done by estimagic as opposed to the user

Advantages of Proposed Change

  • No over-specification that has to be checked
  • No difficulties when calculating standard errors

Discussion

For sum constraints the current situation is clearly better because otherwise they would just be dropped. For probability constraints it could be more intuitive to only specify the free ones. A compromise would be to add another type of constraint called free_probability. While this ensures that everyone finds a solution they are happy with, it could also be confusing to have two very similar but slightly different options.

@hmgaudecker and me already discussed this in #57. Maybe it's time to hear some other opinions @peisenha, @tobiasraabe, @mo2561057

Robust standard error calculation for constraint estimations and better standard error interface

Current Situation

  • Standard error functions are relatively low level. The user explicitly calculates numerical derivatives and then passes them into the covariance/standard error functions
  • It is possible (and happens frequently) that calculation of numerical derivatives fails because the stepsize is so large that some constraints are violated

Desired Situation

  • Standard error calculation can be done in one step
  • Numerical derivatives should respect constraints

Proposed Implementation

Write high level standard error functions that have a similar interface to maximize and minimize. Numerical derivatives are calculated on on a reparametrized version of the objective functions, such that all constraints hold. Then first calculate the covariance matrix for internal_params and use a parametric bootstrap (i.e. monte carlo integration) to calculate the covariance matrix of the external parameters

Discussion

  • Is anybody aware of literature on the topic? Is there any other approach that is similarly easy to apply?
  • How would we handle simple box constraints?

Improve deployment infrastructure

Tasks

  • Automatic deployment on PYPI when a tag is pushed (as in respy)
  • Build conda package from PYPI instead of local source code. The build should be triggered automatically when a tag is pushed, but maybe we need a sleep until the PYPI upload has finished. We can use the current release.py to do the conda build
  • Adjust documentation.

More efficient Dashboard

@tobiasraabe and I looked at the dashboard today and made the following observations:

  • After the optimization terminates, the dashboard still keeps one core busy at 100 %. @roecla, Is this just the bokeh server, or is it because we keep checking for new data at a very high frequency?

Logging and output for extremely long running problems

Current situation

The optimization functions return the optimal parameters and some additional information. After #54 this will be just one object. Moreover, after #45 we will have a persistent log of parameters.

Desired situation

When optimization takes very long (between a few days and potentially weeks) and we run different optimizations in parallel, it is very easy to lose track. It has definitely happened to me that I found an optimization result on my computer and had difficulties to find out to which of many models it belonged.

In the worst case the script that started the optimization does not exist anymore or we forgot the commit we would have to check out to get it.

Therefore, the result of the optimization functions should (in addition to what we have currently) contain the following information:

  • The start and end time of the optimization
  • All arguments to maximize or minimize
  • All criterion_args and criterion_kwargs
  • The conda environment (exported via condas python api)
  • The complete parameter log
  • Optionally: additional information the user provided and that help him to reproduce the same result (e.g. the commit at which he started the optimization or a message that explains why this particular optimization was started.)

Implementation

Collecting the data is easy. The main question is in what format we want to store it on disk.

Ideally everything would be in one "immutable" file and not just a directory where a user could save or delete files manually. .pickle is not a good idea because some pickle objects will only load in the right environment and the information on the environment is inside the pickle file. .json won't work because we have some binary objects. My current favorite is something like a zipped folder but I'm open to other ideas. Inside this folder we could choose the best file type for each information. The environment would be a .yml file, for all dictionaries and lists we could first try to store them as .yml and only if that fails resort to .pickle.

This is based on a conversation with @fediskhakov. Feel free to comment below. Other people can also add ideas and wishes. Right now there are more pressing issues in estimagic but this will be a nice addition in the long run.

Improve the results returned by minimize and maximize

Current Situation

  1. in the results dictionary the status value is always set to "success" when the optimization finishes. This results in unwanted behavior (e.g. status is set to "success" when scipy stops after the maximum number of iterations).

  2. in _process_scipy_results entries like the Jacobian are saved twice, once under the unified name and once under the original name.

  3. The results dictionary does not contain a path to the database.

  4. We still fitness as the name of the final criterion value and x for the parameter vector.

  5. At the moment all internal columns that start with _ are returned to the user in the final params DataFrame as well. Do we want this?

Desired Situation

  1. status is only set to "success" if the optimizer claims to have successfully finished. In addition, we might want to check that the current function evaluation is the lowest one recorded in the database.

  2. Not sure if this is the behavior we want. One the one hand people coming from scipy might appreciate that they can use the results object as before. One the other hand it is duplication and users might wonder if the entries refer to different concepts and just happen to be the same.

  3. The results dictionary should include this.

  4. I would suggest criterion_value and final_internal_params.

  5. I would propose to remove all private (i.e. starting with a _) columns before returning params to the user.

Remove `criterion_args`

Currently, maximize and minimize as well as the derivatives take criterion_args and criterion_kwargs as arguments. I propose that we remove the criterion_args and only use keyword arguments everywhere for the following reasons:

  1. Everything that can be achieved with criterion_args can also be achieved with criterion_kwargs
  2. Keyword arguments are less error prone
  3. It is impossible to find a good broadcasting rule for criterion_args since it is a list or tuple with no known structure that would allow to detect whether the user specified a list of criterion_args or a single set of criterion_args he wants to be broadcasted. This is relevant for #77

@hmgaudecker, @peisenha, @roecla, @tobiasraabe can you please let me know if you are ok with this change?

Ignore pandas PerformanceWarning

Current Situation

Most estimagic criterion functions will produce the following warning: PerformanceWarning: indexing past lexsort depth may impact performance which can always be ignored because params is way too small for this to be relevant.

See here for more info.

Desired situation

The warning is disabled at the beginning of minimize.

Name pattern for criterion functions.

Current situation

In #107 we implemented an interface for the estimation via maximum likelihood. Since the criterion function does not return a scalar and instead the log likelihood contributions, we chose log_like_obs as a preliminary name for the criterion function in estimate.py.

Desired Situation

At least, we should have brainstormed a little bit whether we would like to have unique names for the criterion functions for different estimation techniques and the general maximize and minimize interface. Couple of notes:

  • The naming is probably limited to estimate.py as the estimation functions can reuse maximize() and minimize() and other functions.
  • Having a different name for the public interface highlightens the fact that the function needs a different criterion function than maximize() and minimize().

Proposed implementation

Again only preliminary notes.

  • We might want to have the same name for GMM, MSM, and ML which would be something like contributions.
  • Maybe we also want to have unique name for not closely-related concepts such as log_like_obs for ML and moments for GMM and MSM.

Rewrite _create_population

Problem

The randomly drawn initial populations in pygmo uses the bounds that are enforced during optimization.

Goal

Separate bounds used during optimization from bounds used for random draws of initial parameters.

Implementation

Hopefully we can re-use most of the sampling methods and just change the bounds to 'draws_lower' and 'draws_upper' from the params_df.

Extend package description

Here are some clues from pyroma:

(estimagic) PS C:\Users\tobia\git\estimagic> pyroma .
------------------------------
Checking .
Found estimagic
------------------------------
The package had no description!
The package's long_description is quite short.
You should specify what Python versions you support.
Your package does not have keywords data.
Your package does not have license data.
You should specify license in classifiers.
You are using Setuptools or Distribute but do not specify if this package is zip_safe or not. You should specify it, as it defaults to True, which you probably do not want.
------------------------------
Final rating: 0/10
This cheese seems to contain no dairy products
------------------------------

rewrite _process_pygmo_results

Problem

currently _process_pygmo_results does nothing not extract a lot of information.

Goal

We want to collect all information from the optimization in a json serializable dictionary, similar to what is done when using a scipy algorithm. The string representation of a pygmo results class contains a lot of information but I did not find out how to extract it easily.

Even more dashboard improvements

Plans:

  • pass through of basic server options (such as the port)
  • try random port if one port is occupied
  • Better position of legend

Make the package conda installable

Tasks:

Add the conda recipe and adjust setup.py

Notes

  • required libraries can be taken from environment.yml; Pandas has to be 0.24.0 or newer!

Sqlite Column Limit

Current situation

Hard limit of 2000 parameters, due to default max columns in sqlite. See the corresponding skillmodels issue for more information.

Desired Situation

No practical limit to size of parameter vectors.

Proposed implementation

We know the number of parameters before the tables are created. Thus we can just check if this number is larger than 2000 and if so, set the max columns to the number of parameters.

I would not just set it to the theoretical maximum of 32767. The fact that the default is much lower than that makes me think that this is used for some optimization.

Moreover we should only log those parameters that are not fixed explicitly or implicitly by equality constraints. This will also make the convergence plots more informative.

The sqlite pragma is called SQLITE_MAX_COLUMNS. The right place is probably here

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.