New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ENH: add scipy's minimize to optimizer #3193
Conversation
statsmodels/base/optimizer.py
Outdated
@@ -156,11 +155,14 @@ def _fit(self, objective, gradient, start_params, fargs, kwargs, | |||
extra_fit_funcs = kwargs.setdefault('extra_fit_funcs', dict()) | |||
|
|||
methods = ['newton', 'nm', 'bfgs', 'lbfgs', 'powell', 'cg', 'ncg', | |||
'basinhopping'] | |||
'basinhopping', 'dogleg'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought of adding here a 'minimize'
keyword directly, so we can use whatever scipy minimize provides without having to hardcode any methods.
There user will have to provide the name of the actual method, either in the **keywords, or we could try parsing a double method here e.g. `'minimize-dogleg'.split('-')
adding some specific methods like you did with dogleg is also possible
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I definitely like that idea more, but what about existing methods? Should I keep them as is or refactor to make use of _fit_minimize
?
On a somewhat related note, I've noticed that newton
method has it's own implementation entirely. Is there a specific edge case that scipy.optimize.newton
doesn't cover?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I answered the first part in main comments.
about newton: the statsmodels newton predates scipy's dogleg and newton by many years. #449
the newer scipy newton style optimizer are one of the prime candidates for adding as default use, are are potentially big improvements compared to our newton.
Again, our newton works reasonably well (and we have more control over some details, like regularization), so we need separate keywords. But I would guess that if the scipy newton methods work as advertised, then we will switch the discrete_models to use those as default.
related to travis failures: the problems are with oldest scipy version which will be dropped as supported versions, most likely before this is merged. So, you can ignore those failures for now. |
To continue the inline comment: The plan was to add a generic method as enhancement so we have access to whatever scipy minimize provides without having to hardcode the options to minimize (including selection of optimizer method). It's safer to stick with the enhancement in this PR, and not replace/refactor the existing use of the old connected optimizers. The old wrappers have been working for a long time, but we don't have any experience with how well And idea for a followup is to create a testing PR that internally switches the old |
@josef-pkt alright, that makes sense. Thanks for the detailed responses, I should be able to wrap up this PR now. |
@josef-pkt should be working now. If all is ok, I'll start working on documentation updates. |
statsmodels/base/optimizer.py
Outdated
xopt = res.x | ||
retvals = None | ||
if full_output: | ||
retvals = {'fopt': res.fun, 'iterations': res.nit, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since it's just one line, we can add scipy 0.14 compatibility, AFAICS
use np.nan if res.nit is not available
nit = getattr(res, 'nit', np.nan)
Looks good to me, you can add the documentation for the way it is now. I still need to check some details |
statsmodels/base/optimizer.py
Outdated
options['maxiter'] = maxiter | ||
|
||
# we're using BFGS by default, which doesn't need hessian | ||
if kwargs['min_method'] == None: hess = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to avoid the runtimewarning (based on your comment in the tests, I didn't check myself)
we could expand this to the other major "known" min_methods
e.g.
no_hess = ['Nelder-Mead', 'bfgs', ...] # could also be defined outside of function, but likely not worth doing that
if kwargs['min_method'] in no_hess:
hess = None
I think that's reasonable, even if the plan is to move away from older versions eventually. Shouldn't complicate the code too much.
Note that these errors appear only in the test suite due to the way it's set up. In the real world a user would follow the documentation and/or knowledge of how methods work, so the only way he'd see the extra hessian/jac errors is if he's done something wrong - in which case it most definitely makes sense to notify him about it. |
About the last point RuntimeWarning for jacobian and hessian: |
@josef-pkt ah, okay then filtering is the way to go. 👍 |
for scipy version compatibility: |
BTW: this is going to be a nice focused enhancement PR that is easy to review and merge, but adds a lot of improvement options. |
Compatibility issues should be fixed. I've removed the |
Added documentation as well. Not sure how specific should I be in there, any relevant info is available at Should I do something about the coveralls error? I think the decrease only happens due to version it's checked at, where |
@inoryy Thank you for your first contribution Everything looks fine from what I can see reading through it. We will soon update the python/dependencies version that coveralls uses, so there is nothing to worry about. And your unit tests look good. (I might not be back to merging/maintenance for a few more days.) |
@josef-pkt, thank you for working me through this! I've squashed the commits, should be good to go. |
@inoryy Can you rebase this on master? We have changed the versions of our dependencies on TravisCI to more recent versions. Based on the previous comments, this should be ready to merge. |
@josef-pkt done (rebase worked without conflicts) |
a bit behind master but it's still ok @inoryy Thank you, that should help a lot for some difficult estimation problems |
Initial implementation for #2629.
Right now I've used it to add a proof-of-concept access to
dogleg
optimization method.As a next step I see a lot of room for refactoring of existing internal
_fit_*
methods to make use of the added_fit_minimize
, rather than accessingscipy
's methods directly. @josef-pkt would that fit in with what you've envisioned for #2629?