Conversation
f481e52 to
fd4055b
Compare
d9343ce to
4e03cef
Compare
Codecov Report
@@ Coverage Diff @@
## main #1838 +/- ##
=========================================
+ Coverage 100.0% 100.0% +0.1%
=========================================
Files 255 260 +5
Lines 20644 20832 +188
=========================================
+ Hits 20636 20826 +190
+ Misses 8 6 -2
Continue to review full report at Codecov.
|
| evaluation_result = EngineBase.train_and_score_pipeline(pipeline, self.automl, self.X_train, self.y_train) | ||
| new_pipeline_ids.append(self._post_evaluation_callback(pipeline, evaluation_result)) | ||
| pipelines.pop(0) | ||
| return new_pipeline_ids |
There was a problem hiding this comment.
A weakness of this code: if train_and_score_pipeline or one of the callbacks errors out, the whole while loop would halt.
We use the error callback inside train_and_score_pipeline to handle errors during pipeline evaluation, so this isn't a big concern. But if the data splitter errors, it would move up the stack. I think that behavior is acceptable for now.
There was a problem hiding this comment.
dumb question: can we wrap train_score in a try/except and just continue/alert on exception?
There was a problem hiding this comment.
That's not dumb! You are correct, adding proper error handling now is the responsible thing to do. I was being lazy. Will do.
There was a problem hiding this comment.
I took a close look at this. I still agree that we should update the way we do error handling. But I'd like us to do it in a separate PR. There's a decent amount to consider. This PR doesn't change the existing error handling pattern; we will have to in order to complete the parallel work.
2b83ab5 to
4328c60
Compare
chukarsten
left a comment
There was a problem hiding this comment.
This looks good to me. Looks like a lot, but looks good.
| evaluation_result = EngineBase.train_and_score_pipeline(pipeline, self.automl, self.X_train, self.y_train) | ||
| new_pipeline_ids.append(self._post_evaluation_callback(pipeline, evaluation_result)) | ||
| pipelines.pop(0) | ||
| return new_pipeline_ids |
There was a problem hiding this comment.
dumb question: can we wrap train_score in a try/except and just continue/alert on exception?
bchen1116
left a comment
There was a problem hiding this comment.
Big PR! Tests and implementation looks good, but had a few cleanup suggestions. Had a question about add_to_rankings. It seems like the performance of it changed compared to main, because when I run
from evalml import AutoMLSearch
from evalml.demos import load_breast_cancer
from evalml.pipelines import BinaryClassificationPipeline
class NewPipeline(BinaryClassificationPipeline):
component_graph = ['Imputer', 'LightGBM Classifier']
X, y = load_breast_cancer()
automl = AutoMLSearch(X_train=X, y_train=y, problem_type='binary', objective='f1')
automl.search()
automl.add_to_rankings(NewPipeline({}))
automl.full_rankingsI get

whereas running on main doesn't give me this same error.
|
@bchen1116 thanks for your comments! That example you included is fantastic. You are correct. The way this code is laid out in this PR currently, it would prevent users from adding pipelines to the rankings leaderboard if they were not initially included in I just updated the code to preserve the existing behavior for |
bchen1116
left a comment
There was a problem hiding this comment.
Thanks for addressing the comments! The implementation looks good to me, just left a few nit-picky comments but nothing too pressing here.
Do you think it'd be useful to run perf tests on this to ensure that the new search algo performances don't differ too much from what we currently have on main?
| Returns: | ||
| list (int): a list of the new pipeline IDs which were created by the AutoML search. | ||
| """ | ||
| if self.X_train is None or self.y_train is None: |
There was a problem hiding this comment.
That's true. I suppose it can't hurt to add that. Since there's only one call site at the moment, and if we didn't set automl search there all the tests will fail, I will hold off on adding that right now.
angela97lin
left a comment
There was a problem hiding this comment.
Wow, this is an incredible PR with a lot of great refactoring 👁️ 👁️
Removed extra evaluate_pipeline mock and set unprocessed pipelines to batch. Added test to check for unprocessed pipelines Move tune_binary_threshold to helper, and fix some ifs Put optional max on the number of pipelines generated in a particular automl batch Docstring fix First pass Lint Reorder code to minimize diff Remove unused code Changelog A couple small fixes Fix name Send the right callback Fix callback May not need callback helper Show traceback during automl search errors A couple fixes more use of is_binary / is_multiclass Fix tests Lint Remove unused tests Have AutoMLAlgorithm.add_result raise exception if there's a nonexistent pipeline name provided Reword Add another test Simplify err msg Fix more tests Move logic from search up to __init__ to avoid errors with add_to_rankings Lint Fix import Attempt to fix test Lint Fix add_to_rankings and test more test fixes Fix another test Fix var name Only print out best pipeline at end if one exists! Fix keyboard interrupt. make it easier to use pdb with Have engine return new pipeline IDs. Fix the way the all-nan check works update all-nan tests Fix another test Fix a test case in huge parametrize Fix test: use appropriate objective subclass so that can_optimize_threshold is defined for binclass objective Lint More test fixes Update classification tests Fix a few tests, and stopiteration Lint Fix regression tests Fix more regression tests Rename 'engines' package to 'engine' Refactor, start updating engine tests More test updates Remove unneeded test No need to return pipeline from helper Remove vestigial arg Add test coverage for train_and_score_pipelines Lint Unit test coverage for engine Add patience/tolerance back in Lint Back out unused max_num_pipelines change Remove unused docstring Remove single-call helper Move test files Docstrings Make helper method static Fix mocking in test for py3.7 Amend previous Log cleanup Fix prev Fix conditional Remove set_data helper, simplify API Docs nit-pick Back out another unnecessary change Simplify loop Add test coverage for tune_binary_threshold and is_defined_for_problem_type; allow str input for is_defined_for_problem_type Add assert Codecov Mock input directly Try to add pipelines to results, but if the automl algo wasn't initialized with them, ignore the error Little changes
956d32f to
e9eaea2
Compare
|
Perf test results here. Flat as expected! |

Fix #1296
Changes
EngineBasebase class to define engine interface, andSequentialEnginewhich preserves existing behavior, evaluates pipelines in series_pre_evaluation_callbackfor logging and_post_evaluation_callbackto add evaluation results toAutoMLSearchAutoMLSearch. _compute_cv_scorestoEngineBase.train_and_score_pipelineas astaticmethodAutoMLSearchbinary threshold tuning logic intotune_binary_thresholdso it could be reused. Fixed bug where all bin class pipelines were getting a threshold of 0.5 -- now will getNoneas was the original intent.AutoMLSearchconstructor expects data, move much of thesearchsetup logic into the constructor to simplify the behavior.AutoMLAlgorithm.add_resultraise error if pipeline is unrecognized_check_stopping_conditionto_should_continuelog_error_callback, which I believe partially handles No stack trace visible in debug log #1778 (@bchen1116 heads up). This was helpful to me when debugging so I just went ahead and did it.test_automl.py,CustomClassificationObjectivewasn't subclassed fromBinaryClassificationObjective, same for regressionscorebut not providing a return value, causing scores to benanFuture:
AutoMLSearchinstance. I couldn't easily do this today because of the logging callback -- it expects a reference toAutoMLSearchto add the error to theresultsstructureAutoMLSearchstate without any sort of locking or atomicity. This is fine for this PR, but when we implement parallel evaluation, we'll need to address this.EngineBasesubclass as input toAutoMLSearch, rather than creating internally. This would require thought about how to pass parameters and create the instance. We'd probably wanna switch to using a config object first forAutoMLSearchBig credit to @christopherbunn for providing the initial implementation this PR is based on! 🙏