-
-
Notifications
You must be signed in to change notification settings - Fork 25.8k
WIP GridSearch with advanced score functions. #1198
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
Conversation
@@ -447,11 +444,4 @@ def _fit(self, X, y): | |||
return self | |||
|
|||
def score(self, X, y=None): | |||
if hasattr(self.best_estimator_, 'score'): | |||
return self.best_estimator_.score(X, y) | |||
if self.score_func is 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.
This code was untested and also unreachable afaik.
How should the grid-search be done without a score function any way?
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.
hm forgot about the loss_function
case. should fix that.
Btw I think this solution is more elegant than #1014 and I am quite happy with it. |
Give me till the week end :} |
def requires_thresholds(f): | ||
"""Decorator to tag scores that need continuous inputs.""" | ||
f.requires_thresholds = True | ||
return f |
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.
We could even check the input in the wrapper and yield a meaningful error message if the second input array has a 1D shape.
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.
how does that work? Write a wrapper function for f that does the check and then applies f?
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.
yes
Ok so two things:
|
On Sun, Oct 14, 2012 at 01:40:52PM -0700, Andreas Mueller wrote:
Really. It seems to me that as long as there is a well-defined 'score',
I'd say return a sensibly-shaped decision_function, as the problem will G |
take the FactorAnalysis now that you have a score function you can optimize |
@agramfort @GaelVaroquaux My reasoning was that you don't need to use a validation set for unsupervised tasks. You can just optimize parameters on the training set. How I would do it is GridSearch on the training set, then optionally test once on the hold-out set so see how it generalizes. Would you use another pattern? And do you have any examples where this was useful? @GaelVaroquaux could you please also comment on the inheritance issue I raised? |
I agree if the training set is also splitted in 2.
I agree but you still need GridSearch with unsupervised. |
sorry, bad working. I would grid search on the training set - not use GridSearchCV. There is no cross-validation going on. I am not saying we don't need unsupervised grid search. What I was thinking was that supporting unsupervised grid search in GridSearchCV is weird, as you don't need cross-validation. I'd rather have a separate estimator that does grid search without cross-validation and evaluates the score on the training set. |
I am not so experienced here and unsupervised model selection is not that well explored - so if you think cross-validation is appropriate, ok. Then I'd like a reference and an example ;) |
I am lost. To me GridSearchCV is doing exactly this when fit although it |
http://www.compstat2012.org/Proceedings_COMPSTAT2012.pdf search for 'varoquaux'. You also want an example in the scikit's examples, right? I have in mind I'll try to think of something... |
Even on an unsupervised setting you need to compute the score (e.g. negative log-likelihood) on a held out test set to avoid overfitting (yet "overfitting" can happen in an unsupervised setting). So let's keep the unsupervised setting and write a test with FA instead. Also we should improve the documentation of the |
But even for FA, the largest the number of components, the highest the neg log-likelihood will be, isn't it? |
@agramfort Sorry, I must have been unclear. GridSearchCV splits the training data for each iteration. Trains on one, scores on the other. I would rather fit and score on the same. In particular, for most clustering algorithms, you can not predict and therefore not score on anything but the test set - ergo GridSearchCV can not be used. If you think that this grid search is helpful, then let's just do a FA example as @ogrisel suggests. We still need a different estimator for the clustering algorithms that don't have a predict. |
Most often yes, I believe. That's why we need optional penalizations (eg |
On Wed, Oct 17, 2012 at 05:39:40AM -0700, Andreas Mueller wrote:
No. You will never be able to control for overfitting, i.e. fitting
Agreed. G |
Coming back to the real content of the PR: Is this ok with everybody? |
On Wed, Oct 17, 2012 at 05:42:38AM -0700, Andreas Mueller wrote:
No, I don't think so. I may want to apply my own score_func to an I don't understand why you want to remove this possibility. |
Because then different score-functions would be handled very differently. Can you give an example of using grid-search on an estimator without a score function? |
Btw, we could put a score function into the Btw, do you really use GridSearchCV on estimators that don't inherit from BaseEstimator? |
On Wed, Oct 17, 2012 at 05:48:21AM -0700, Andreas Mueller wrote:
Any clustering algorithm, if I have a specific logic to set the number of If you really don't like 'score_func', we can depreciate it and remove |
Sorry, I think there is really a misunderstanding. I like about your example: sorry, that doesn't exist. |
Btw, I am totally against subclassing for different score functions. |
On Wed, Oct 17, 2012 at 02:34:58PM +0200, Gael Varoquaux wrote:
Other example: I do this all the time. |
On Wed, Oct 17, 2012 at 05:50:36AM -0700, Andreas Mueller wrote:
I don't understand the logic. How would 'score_func' be used in the score
I don't often. However, it is good design not to enforce inheritence. That's what duck typing is about. It's used all over Python: you can use
Inheritence is what kills a large C++ codebase (VTK, I am looking at In my experience, relying on inheritence for a codebase is bad design. |
By default,
So you did reimplement get_params and set_params?
I think this is impossible already as pointed out above. I just wanted to get auc_score to work in a way that is not totally hacky. |
So the solution to the problem is then: try:
if score_func is None:
score = estimator.score(X[test], y[test])
else:
score = estimator.score(X[test], y[test], score_func=score_func)
except TypeError, AttributeError:
if score_func.requires_threshold:
raise TypeError("score func passed that needs threshold but estimator can't accept it.")
else:
score = score_func(y[test], estimator.predict(X[test]) The only problem here is that GridSearchCV needs to know about So I don't really see how it is possible to leave GridSearchCV unaware of |
The above "solution" has the disadvantage to break if using |
On Wed, Oct 17, 2012 at 05:56:50AM -0700, Andreas Mueller wrote:
OK, sorry for not looking at the code and discussing the PR based on the I now looked at the code. I am afraid that I disagree with the PR: I Below follows a very long email that tries to argue why I think that it I think that by asking the score method of an estimator to take a That said, I agree with you that we have a design problem with the way This is a much bigger discussion, but I would personnally much prefer if Quoting another of your comments, about using
I think that the core problem s that auc_score, like any score in Is there something you don't like with the idea of having an As a side note, to justify this last usecase, for such models, it does
Good. I am happy. Indeed, I'd like as many objects as possible to define score Sorry for the long email. I hope that my arguments are somewhat |
Thanks for the response. Sorry, I was a bit frustrated after my second proposal being rejected. Do I understand the "estimator parameter" idea correctly: If you specify a score-func in the estimator, and one in GridSearch, it is not clear at all to the user which one will be used. But following your argument, we can not drop the ability to use score functions in GridSearch, as you want to use score functions with estimators that don't know anything about score functions. |
Btw, I totally agree that we should aim at minimizing requirements on estimators and the API. About making some applications impossible: I will always take great care not to break anything within the scikit. |
here is a quick an dirty demo script if it can help: HTH |
@agramfort Thanks :) |
@GaelVaroquaux Btw, this PR is the third iteration of trying to integrate the score function into the estimator. I tried making it a constructor argument, but after adding it to half of the estimators in sklearn I was convinced that it is not a good solution and dropped the stash. I'd really like to include grid search with |
no problem. If you feel like adding this test please do so. maybe @jaquesgrobler can also take a look at it :) |
Closed via #1381. |
Follow up on #1014.
This PR does the handling of score functions in the regressor and classifier mixins with minimal intrusion into the code.
This enables estimator to overwrite the score function and do whatever they see fit - though that shouldn't be necessary atm.
To complete this PR, I will probably also need to do some minor adjustments to the other CV classes,
I'm a bit tempted to add a test to the "common tests" to see if
cross_valdation_score
with AUC works.