[ENH] detection module suite tests coverage extension for methods#6958
[ENH] detection module suite tests coverage extension for methods#6958fkiraly merged 26 commits intosktime:mainfrom
Conversation
Using Pandas' datetime object and numpy's datetime object was causing issues.
This is especially important with datetimes
|
let me know when you would like a review! |
|
@fkiraly, I am trying to run some of the tests that are failing locally but I am having some trouble. One of the failing tests is: I am trying to recreate this test with the following code: >>> from sktime.annotation.tests.test_all_annotators import TestAllAnnotators, AnnotatorsFixtureGenerator
>>> from sktime.annotation.hmm_learn.gaussian import GaussianHMM
>>> results = TestAllAnnotators().run_tests(GaussianHMM, tests_to_run="test_predict_segments")
>>> results
{'test_predict_segments[AnnotatorPipeline-0]': 'PASSED', 'test_predict_segments[AnnotatorPipeline-1]': 'PASSED', 'test_predict_segments[AnnotatorPipeline-2]': 'PASSED'}By putting a breakpoint at the start of the AnnotatorPipeline(steps=[('transformer',
TabularToSeriesAdaptor(transformer=StandardScaler())),
('anomaly',
SubLOF(n_neighbors=5, novelty=True,
window_size=datetime.timedelta(days=25)))])I am unsure why this |
|
My high-level guess would be, there's something about identity of estimators that links the fitted and unfitted objects, i.e., identical objects end up in the fixtures where you would have wanted copies, and that has side effects. This has been a persistent problem btw, I have not figured out how to pass fitted estimators to some tests, to avoid refitting - this is why none of the other test suits pass fitted estimtors as fixtures. Based on this - unless you want to dig into the functioning of the test suite - I would recommend to always use unfitted estimator instances, or classes, and not modify the test class logic. |
|
Thanks for the suggestions. |
|
If you find out how we can cache fitted estimators without running into memory problems (e.g., avoiding that all estimators are cached at once, including fitted deep learning and foundation models), or "change by reference" or mutability problems, that would be a great contribution! As said, I could not find out how to do this with pytest or the custom extensions we are currently using. |
|
Okay, I'll take a look at this and see what I can find. If I think it is too hard I'll open a separate issue and leave it for another day. I am also going to log some of findings here in this thread so I don't lose it: The TestAllAnnotators().run_tests(GaussianHMM, tests_to_run="test_predict_segments")I think the reasons these HMM models were not generated on my machine is because I didn't have I will try installing hmmlearn and see what effect that has. |
|
Installing hmmlearn has helped. Here is the output from running the same code from my previous comment. >>> from sktime.annotation.tests.test_all_annotators import TestAllAnnotators, AnnotatorsFixtureGenerator
>>> from sktime.annotation.hmm_learn.gaussian import GaussianHMM
>>> results = TestAllAnnotators().run_tests(GaussianHMM, tests_to_run="test_predict_segments")
>>> results
{'test_predict_segments[AnnotatorPipeline-0]': ValueError('min() arg is an empty sequence'), 'test_predict_segments[AnnotatorPipeline-1]': 'PASSED', 'test_predict_segments[AnnotatorPipeline-2]': 'PASSED', 'test_predict_segments[GMMHMM-0]': AssertionError(), 'test_predict_segments[GMMHMM-1]': AssertionError(), 'test_predict_segments[GaussianHMM]': AssertionError(), 'test_predict_segments[PoissonHMM]': AssertionError(), 'test_predict_segments[PyODAnnotator]': TypeError("'>' not supported between instances of 'Timestamp' and 'int'")}I am still not certain why the annotator pipelines are being included given that I have asked for only the |
|
that is indeed strange. Have you tried on If it happens on |
|
At a first glance, it doesn't seem like this is happening on >>> from sktime.annotation.tests.test_all_annotators import TestAllAnnotators, AnnotatorsFix
>>> from sktime.annotation.hmm_learn.gaussian import GaussianHMM
>>> results = TestAllAnnotators().run_tests(GaussianHMM, tests_to_run="test_output_tags")
>>> print(results)
{'test_output_type[GaussianHMM]': 'PASSED'}I am going to work under the assumption that the issue was caused by a change made in this PR for now. |
|
I think I have an idea what is happening. I'll explain it through two examples. Example 1This examples runs the >>> from sktime.annotation.tests.test_all_annotators import TestAllAnnotators, AnnotatorsFixtureGenerator
>>> from sktime.annotation.hmm_learn.gaussian import GaussianHMM
>>> results = TestAllAnnotators().run_tests(GaussianHMM, tests_to_run="test_annotator_tags")
>>> print(results)
{'test_annotator_tags[GaussianHMM]': 'PASSED'}This works as expected. The {
'estimator_class': <function QuickTester.run_tests.<locals>._generate_estimator_class at 0x7f7b56663d90>,
'estimator_instance': <function QuickTester.run_tests.<locals>._generate_estimator_instance_cls at 0x7f7afd2be320>,
'fitted_estimator': <bound method AnnotatorsFixtureGenerator._generate_fitted_estimator of <sktime.annotation.tests.test_all_annotators.TestAllAnnotators object at 0x7f7afd287040>>,
'method_nsc': <bound method BaseFixtureGenerator._generate_method_nsc of <sktime.annotation.tests.test_all_annotators.TestAllAnnotators object at 0x7f7afd287040>>,
'method_nsc_arraylike': <bound method BaseFixtureGenerator._generate_method_nsc_arraylike of <sktime.annotation.tests.test_all_annotators.TestAllAnnotators object at 0x7f7afd287040>>,
'scenario': <bound method BaseFixtureGenerator._generate_scenario of <sktime.annotation.tests.test_all_annotators.TestAllAnnotators object at 0x7f7afd287040>>
}This dictionary contains the generators for generating annotator classes, annotator instances, and the fitted annotators. Notice that value for the key The Example 2This examples runs the >>> from sktime.annotation.tests.test_all_annotators import TestAllAnnotators, AnnotatorsFixtureGenerator
>>> from sktime.annotation.hmm_learn.gaussian import GaussianHMM
>>> results = TestAllAnnotators().run_tests(GaussianHMM, tests_to_run="test_predict_segments")
>>> print(results)
{
'test_predict_segments[AnnotatorPipeline-0]': 'PASSED',
'test_predict_segments[AnnotatorPipeline-1]': 'PASSED',
'test_predict_segments[AnnotatorPipeline-2]': 'PASSED',
'test_predict_segments[GMMHMM-0]': AssertionError(),
'test_predict_segments[GMMHMM-1]': AssertionError(),
'test_predict_segments[GaussianHMM]': AssertionError(),
'test_predict_segments[PoissonHMM]': AssertionError(),
'test_predict_segments[PyODAnnotator]': TypeError("'>' not supported between instances of 'Timestamp' and 'int'")
}This test calls the annotator pipelines when it should only use gaussian HMM. Again, we print the contents of {
'estimator_class': <function QuickTester.run_tests.<locals>._generate_estimator_class at 0x7f9da71dfd90>,
'estimator_instance': <function QuickTester.run_tests.<locals>._generate_estimator_instance_cls at 0x7f9d4de32320>,
'fitted_estimator': <bound method AnnotatorsFixtureGenerator._generate_fitted_estimator of <sktime.annotation.tests.test_all_annotators.TestAllAnnotators object at 0x7f9d4ddfaec0>>,
'method_nsc': <bound method BaseFixtureGenerator._generate_method_nsc of <sktime.annotation.tests.test_all_annotators.TestAllAnnotators object at 0x7f9d4ddfaec0>>,
'method_nsc_arraylike': <bound method BaseFixtureGenerator._generate_method_nsc_arraylike of <sktime.annotation.tests.test_all_annotators.TestAllAnnotators object at 0x7f9d4ddfaec0>>,
'scenario': <bound method BaseFixtureGenerator._generate_scenario of <sktime.annotation.tests.test_all_annotators.TestAllAnnotators object at 0x7f9d4ddfaec0>>
}The value for Short SummaryThe If you look at the @fkiraly, does this make sense and what are your thoughts on this? |
|
Yes, this makes absolutely sense! The With you adding a new "fitted estimator" fixture, this mechanism is not implemented for the fitted estimator. I would hence strongly suggest to split the current PR in two parts:
|
|
Looks like the remaining issues are API non-compliances by concrete estimators, right? |
|
Yes I think so. I am going to add the failing estimators to the list of excluded estimators for the time being to try and get the pipeline to pass. |
|
@Alex-JG3, I think this is ready now? Let's merge, so other people can add more tests. |
Yeah, I think this is ready. I can't merge since it still needs a review. |
) #### Reference Issues/PRs Closes #6895. #### What does this implement/fix? Explain your changes. * Extends the test suite for all annotators to ensure better interface compliance. * Adds test skips for non-compliant estimators.
Reference Issues/PRs
Closes #6895.
What does this implement/fix? Explain your changes.