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
[WIP] Bandits regressors for model selection #391
[WIP] Bandits regressors for model selection #391
Conversation
river/expert/bandit.py
Outdated
def __init__(self, epsilon=0.1, epsilon_decay=None, **kwargs): | ||
super().__init__(**kwargs) |
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 part seems to make the tests fail (same part for UCBBandit). Should I enumerate all the parameters (that are in Bandit.__init__
) instead of using **kwargs
?
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, you should :)
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.
Actually I try with it but the tests do fail again. I see also that expert.SuccessiveHalving* are purposely exclude from the test (in get_all_estimators
) while expert.EWARegressor
is not. Is the kind of regressor I implemented supposed to pass this test at all ?
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.
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 just add default LinearRegression
in a Pipeline
and tests pass. It somehow surprise me since I didn't gave default arg for metric
and reward_scaler
.
Not related to this PR but one test failed :
======================================================================== FAILURES ========================================================================
___________________________________________________ [doctest] river.neighbors.sam_knn.SAMKNNClassifier ___________________________________________________
052 >>> from river import metrics
053 >>> from river import neighbors
054
055 >>> dataset = synth.ConceptDriftStream(position=500, width=20, seed=1).take(1000)
056
057 >>> model = neighbors.SAMKNNClassifier(window_size=100)
058
059 >>> metric = metrics.Accuracy()
060
061 >>> evaluate.progressive_val_score(dataset, model, metric)
Expected:
Accuracy: 59.90%
Got:
Accuracy: 58.20%
/path/to/package/river/neighbors/sam_knn.py:61: DocTestFailure
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.
@smastelini any idea why the above test is failing?
I could not reproduce that failure in my local setup (in the
master
branch). Pinging @jacobmontiel, since he has more experience with this specific k-NN variant than I do.
FYU the master
branch in my fork is 10 commits behind master
in online-ml/river
however these 10 commits are mostly doc so..
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.
It passes on my local setup using pytest but it did fail on the CI pipeline (https://travis-ci.org/github/online-ml/river/jobs/745694837).
Very weird! Not sure what to say. Are you sure your development setup is correct?
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.
My bad :/ I forget that I add the bandits classes in the ignored
tuple in get_all_estimators
.
I can now confirm that it fails as in the CI when I do not provide the arguments.
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.
@smastelini any idea why the above test is failing?
I could not reproduce that failure in my local setup (in the master branch). Pinging @jacobmontiel, since he has more experience with this specific k-NN variant than I do.
I am confused, is this failing?
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 clone and rebuild the whole package (following https://github.com/online-ml/river/blob/master/CONTRIBUTING.md#installation) and it fails at the same place:
======================================================================== FAILURES ========================================================================
___________________________________________________ [doctest] river.neighbors.sam_knn.SAMKNNClassifier ___________________________________________________
052 >>> from river import metrics
053 >>> from river import neighbors
054
055 >>> dataset = synth.ConceptDriftStream(position=500, width=20, seed=1).take(1000)
056
057 >>> model = neighbors.SAMKNNClassifier(window_size=100)
058
059 >>> metric = metrics.Accuracy()
060
061 >>> evaluate.progressive_val_score(dataset, model, metric)
Expected:
Accuracy: 59.90%
Got:
Accuracy: 58.20%
/home/etienne/PROJETS/river_test/river/river/neighbors/sam_knn.py:61: DocTestFailure
I am using Python 3.7.7 and Ubuntu 20.04.1 LTS.
I can open an issue to keep it out of the PR
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.
Thanks for the PR! It's a good start, and I agree that starting with regression only is a good idea :). I've made a few comments to get the ball rolling. High five!
river/expert/bandit.py
Outdated
def __init__(self, epsilon=0.1, epsilon_decay=None, **kwargs): | ||
super().__init__(**kwargs) |
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, you should :)
Thanks, also thank you for this review ! I incorporate all your points and left some conversation unresolved (when your feedback is needed). I will quickly test this new class since I introduce noticeable change by removing the numpy dependency. Also I need to finish writing docstring (Parameters and Example) then you can merge if it looks good to you. If you see other desirable change tell me too. |
The test To put it differently, if there is two arms (A1, A2) and two bandits (B1, B2), and if the bandit B1 pull arm A1 and bandit B2 pull arm A2 at round 0, they won't output the same prediction at round 1 because their internals (in particular |
@etiennekintzler, can you close and reopen the pull request? We've switched to GitHub actions for CI, which should be much faster and more enjoyable than Travis :) |
@etiennekintzler: you need to a seed parameter and seed the random generation process to make it reproducible. Regarding unit tests, I guess that for the moment you can rely CI and locally ignore that SamKNN test that isn't passing. |
Description
The PR introduce bandits (epsilon-greedy and UCB) for model selection (see issue #270 ). The PR concerns only regressors, but I can add the classifiers in a subsequent PR.
The use of the classes are straightforward :
There are convenience methods such as :
percentage_pulled
: to get the percentage each arm was pulledbest_model
: return the model with the highest average rewardAlso I added a method
add_models
where the user can add models on the fly.I am also working on a notebook that studies the behavior of the bandits for model selection. The notebook also include Exp3, which seems promising but has numerical stability issue and yields counter-intuitive results (see section 3 of the NB). That's why I kept it out of this PR. More generally, the performances of UCB and epsilon-greedy are rather good but there seems to be some variance in the performance.
Improvements
It's still WIP on the following points :
save_metrics
parameter) inBandits
I would appreciate inputs regarding the functionalities and the methods/classes naming.