-
-
Notifications
You must be signed in to change notification settings - Fork 26k
[MRG+2?] Metaestimator delegation #3982
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
[MRG+2?] Metaestimator delegation #3982
Conversation
if we are to use the factory directly in the decorating lines, I would rather change its name, for instance, have: @make_delegation_decorator('_final_estimator')
def predict(self, X):
... replaced by: @if_delegate_has_method(delegate='_final_estimator')
def predict(self, X):
... WDYT? I am not 100% decided about this either. |
@amueller can you rebase on master and fix the conflicts to get travis to run? |
6c607ae
to
86f4ee1
Compare
rebased. |
Thanks for working on this. I like @ogrisel's naming suggestion, and I think @amueller is right that naming the decorators was an unnecessary indirection. However, I probably should have tested the following: #2854 will transfer the docstring from the function defining from sklearn.pipeline import Pipeline
help(Pipeline) (comparing both PRs) We could write a test along the lines of: def foo():
"""str"""
pass
assert foo.__doc__ == my_wrapper(foo).__doc__ In either case the function signature isn't shown which is unfortunate, and may need to be compensated for by writing out the signature within the docstring. A related problem, that I didn't test for in #2854, and which might not be so easy to fix, is that none of those methods render in the sphinx documentation :((( |
How about |
Hum, that is odd. I checked the docstring on the decision function and it was transferred. |
@larsmans It doesn't delegate to that object necessarily. For the gridsearch, the parameter is |
@jnothman from sklearn.pipeline import Pipeline
from sklearn.svm import SVC
help(Pipeline([('svm', SVC)]).decision_function) gives the right docstring, though |
What I still don't understand: what is it that |
it seems you can use |
Fixed the docstrings in sphinx. |
The somewhat odd fix with checking if the object is @property
def predict_proba(self):
if self is not None:
self.final_estimator.predict_proba
return self._predict_proba On the other hand, I think the |
dc86a16
to
3c8df92
Compare
@GaelVaroquaux It would be great if you had time to have a look. The actual implementation is really short and not that meta any more. The only downside that I can currently see is that introspection doesn't find the right line numbers for the function any more. |
3c8df92
to
41e2c10
Compare
Sure. In the first case you retrieved the attribute (i.e. executed the |
|
||
|
||
class _IffHasAttrDescriptor(object): | ||
"""Implements a conditional propery using the descriptor protocol. |
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.
*property
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.
this typo has not yet been fixed.
Perhaps in the future we will hack sphinx to show the correct signature and source link. In the meantime I think this is a moderately serious bug that results in silent misbehaviour, and we should merge it ASAP. Although there are concerns about code quality, as expressed by @GaelVaroquaux, the perfect solution can wait, as the bug fix cannot. I give @amueller's work a +1, and he has implicitly given my contributions to this a +1... @larsmans has given an earlier version of this a +1, so as far as I'm concerned this has +2. If an external party would like to give this another look over, that would be great, but otherwise we should aim to merge. |
... def __init__(self, sub_est): | ||
... self.sub_est = sub_est | ||
... | ||
... @iff_sub_est_has_attr |
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 would put @if_delegate_has_method(delegate='sub_est')
directly here instead of introducing the iff_sub_est_has_attr
indirection that does not only bring complexity to the example.
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.
sure.
I think I like this solution as well. |
I think we should merge. As @jnothman points out, this is a fix to a long-standing bug, and does not break or introduce any public changes. Changing the implementation if we are unhappy with it should therefore be easy. |
except sphinx ;) |
Metaestimator delegation/ducktyping. Fixes #1805.
Slight change to #2854.