Skip to content

[ENH] Add flexible quality measures to RandomShapeletTransform#3244

Open
nimra06 wants to merge 3 commits intoaeon-toolkit:mainfrom
nimra06:enh/flexible-quality-measures
Open

[ENH] Add flexible quality measures to RandomShapeletTransform#3244
nimra06 wants to merge 3 commits intoaeon-toolkit:mainfrom
nimra06:enh/flexible-quality-measures

Conversation

@nimra06
Copy link
Copy Markdown
Contributor

@nimra06 nimra06 commented Jan 17, 2026

Reference Issues/PRs

Addresses #186

What does this implement/fix? Explain your changes.

Adds a quality_measure parameter to RandomShapeletTransform to support multiple quality measures for evaluating shapelets. Currently, the transform is hardcoded to use information gain. This PR makes it flexible while maintaining backward compatibility.

Changes:

  • Added quality_measure parameter (default: "information_gain") to RandomShapeletTransform.__init__
  • Implemented f_statistic quality measure as an alternative option
  • Created new _quality_measures.py module for numba-optimized quality measure functions
  • Added comprehensive tests covering default behavior, validation, and both quality measures
  • Updated docstrings to document the new parameter and options

Implementation details:

  • Uses string-based parameter selection with conditional logic inside numba-decorated functions
  • Follows the pattern from tsml-eval's quality measures implementation
  • Maintains numba performance - both measures are fully optimized with @njit
  • Information gain remains the default to preserve existing behavior

Performance:
Benchmarked both quality measures on unit test and basic motions datasets. F-statistic performs similarly to information gain (slightly faster in most cases, within 1-2%). The default behavior shows no performance regression.

Does your contribution introduce a new dependency? If yes, which one?

No new dependencies.

Any other comments?

This addresses the flexibility requested in issue #186. Based on community feedback, F-statistic may have lower accuracy than information gain on some datasets, but it runs faster. The trade-off is documented in the parameter description, and users can now choose based on their needs.

The implementation follows existing patterns in aeon and maintains full backward compatibility - existing code will continue to work exactly as before.

- Add quality_measure parameter to support multiple quality measures
- Implement f_statistic quality measure as alternative to information_gain
- Create _quality_measures.py module for numba-optimized quality measures
- Add comprehensive tests for new functionality
- Maintain backward compatibility (information_gain remains default)
- Addresses issue aeon-toolkit#186
@aeon-actions-bot aeon-actions-bot bot added enhancement New feature, improvement request or other non-bug code enhancement transformations Transformations package labels Jan 17, 2026
@aeon-actions-bot
Copy link
Copy Markdown
Contributor

Thank you for contributing to aeon

I have added the following labels to this PR based on the title: [ enhancement ].
I have added the following labels to this PR based on the changes made: [ transformations ]. Feel free to change these if they do not properly represent the PR.

The Checks tab will show the status of our automated tests. You can click on individual test runs in the tab or "Details" in the panel below to see more information if there is a failure.

If our pre-commit code quality check fails, any trivial fixes will automatically be pushed to your PR unless it is a draft.

Don't hesitate to ask questions on the aeon Discord channel if you have any.

PR CI actions

These checkboxes will add labels to enable/disable CI functionality for this PR. This may not take effect immediately, and a new commit may be required to run the new configuration.

  • Run pre-commit checks for all files
  • Run mypy typecheck tests
  • Run all pytest tests and configurations
  • Run all notebook example tests
  • Run numba-disabled codecov tests
  • Stop automatic pre-commit fixes (always disabled for drafts)
  • Disable numba cache loading
  • Regenerate expected results for testing
  • Push an empty commit to re-run CI checks

Copy link
Copy Markdown
Member

@MatthewMiddlehurst MatthewMiddlehurst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks.

Comment on lines +11 to +14
def test_shapelet_transform_default_quality_measure():
"""Test that default quality measure is information_gain."""
t = RandomShapeletTransform(n_shapelet_samples=10, max_shapelets=5)
assert t.quality_measure == "information_gain"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not really necessary

Comment on lines +2 to +3

__maintainer__ = ["MatthewMiddlehurst"]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dont need this

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this should be in utils/numba and have its own tests

n_jobs: int = 1,
parallel_backend=None,
random_state: int | None = None,
quality_measure: str = "information_gain",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you put this above batch_size, remember to do the docstring entry as well

Comment on lines +192 to +200
# Validate quality_measure
valid_measures = ["information_gain", "f_statistic"]
if quality_measure not in valid_measures:
raise ValueError(
f"quality_measure must be one of {valid_measures}, "
f"got {quality_measure}"
)
self.quality_measure = quality_measure

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

validation should be done in _fit or a function called from it

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a bad change but why?

Comment on lines +590 to +593
@staticmethod
@njit(fastmath=True, cache=True)
def _find_shapelet_quality_f_stat(
X,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is having a new function for each new quality measure necessary? Feel like this could be done better

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature, improvement request or other non-bug code enhancement transformations Transformations package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants