Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
229 commits
Select commit Hold shift + click to select a range
ac185e2
added numba prange to all pairwise distances
chrisholder Feb 17, 2025
c406623
sfa update
chrisholder Feb 18, 2025
cbf5e19
changed warning
chrisholder Feb 18, 2025
2b7acac
Merge branch 'main' into distance-module-n-jobs
baraline Feb 18, 2025
2efb8ce
Merge branch 'distance-module-n-jobs' into knn-update
chrisholder Feb 28, 2025
5f74e4e
thread kneighbors
chrisholder Feb 28, 2025
4c95abb
fix test
chrisholder Feb 28, 2025
d35954d
Merge branch 'main' into distance-module-n-jobs
chrisholder Feb 28, 2025
3ff96b1
custom pairwise threaded
chrisholder Mar 3, 2025
2a74496
fixed
chrisholder Mar 3, 2025
4afc8df
added threaded decorator
chrisholder Mar 4, 2025
331bf6f
Merge branch 'distance-module-n-jobs' into knn-update
chrisholder Mar 4, 2025
3b6233e
merge changes and fixed call
chrisholder Mar 4, 2025
b603ddb
fix
chrisholder Mar 4, 2025
24b46b0
fix
chrisholder Mar 4, 2025
3ee0152
Merge branch 'distance-module-n-jobs' into knn-update
chrisholder Mar 4, 2025
85dfdab
Merge branch 'main' into distance-module-n-jobs
MatthewMiddlehurst Mar 6, 2025
26c309d
Merge branch 'distance-module-n-jobs' into knn-update
chrisholder Mar 7, 2025
9f2e010
fixed
chrisholder Mar 7, 2025
541e7fd
expanded threaded decorator to work with classes
chrisholder Mar 7, 2025
405bdda
Merge branch 'distance-module-n-jobs' into knn-update
chrisholder Mar 7, 2025
32e93eb
fixed
chrisholder Mar 7, 2025
add714e
fix
chrisholder Mar 7, 2025
ac6eabe
Merge branch 'distance-module-n-jobs' into knn-update
chrisholder Mar 7, 2025
7b02683
merge
chrisholder Mar 7, 2025
a94cc8d
added test for kneighbors
chrisholder Mar 7, 2025
4470989
added test for kneighbors
chrisholder Mar 7, 2025
7ee5846
Merge branch 'main' into distance-module-n-jobs
MatthewMiddlehurst Mar 15, 2025
d9d594c
fix
chrisholder Apr 2, 2025
7658c12
Automated `CONTRIBUTORS.md` update (#2614)
aeon-actions-bot[bot] Mar 15, 2025
ebbe614
Updated Interval Based Notebook (#2620)
kavya-r30 Mar 16, 2025
ff4d501
[DOC] Added Docstring for regression forecasting (#2564)
kavya-r30 Mar 16, 2025
deefbae
GSoC announcement (#2629)
MatthewMiddlehurst Mar 17, 2025
e922bca
Automated `pre-commit` hook update (#2632)
aeon-actions-bot[bot] Mar 17, 2025
c79fa9c
[MNT] Bump tj-actions/changed-files from 45 to 46 in the github-actio…
dependabot[bot] Mar 17, 2025
da13dee
[MNT] Update numpy requirement in the python-packages group (#2643)
dependabot[bot] Mar 17, 2025
26853e3
[MNT,DEP] _binary.py metrics deprecated (#2600)
aryanpola Mar 18, 2025
f1dceea
Support for unequal length timeseries in itakura parallelogram (#2647)
tanishy7777 Mar 19, 2025
db0ff49
[ENH] Implement DTW with Global alignment (#2565)
tanishy7777 Mar 19, 2025
218cf60
[ENH] Adds kdtw kernel support for kernelkmeans (#2645)
tanishy7777 Mar 19, 2025
3375173
[MNT] Skip some excected results tests when numba is disabled (#2639)
MatthewMiddlehurst Mar 20, 2025
c4fa185
[MNT] Remove REDCOMETs from testing exclusion list (#2630)
MatthewMiddlehurst Mar 20, 2025
e6020ac
[ENH] Replace `prts` metrics (#2400)
aryanpola Mar 21, 2025
2bd6e68
Clarify documentation regarding unequal length series limitation (#2589)
Kaustbh Mar 23, 2025
9816c79
Automated `pre-commit` hook update (#2683)
aeon-actions-bot[bot] Mar 24, 2025
7483398
[MNT] Bump tj-actions/changed-files in the github-actions group (#2686)
dependabot[bot] Mar 24, 2025
9d85fa7
[ENH] Set `outlier_norm` default to True for Catch22 estimators (#2659)
tanishy7777 Mar 27, 2025
6ddfc95
[MNT] Use MacOS for examples/ workflow (#2668)
shinymack Mar 27, 2025
b64ac00
Update dependencies.md (#2717)
TinaJin0228 Apr 2, 2025
e19ddb6
Automated `pre-commit` hook update (#2708)
aeon-actions-bot[bot] Apr 3, 2025
df6df7f
[ENH] Test Coverage for Pairwise Distance (#2590)
kavya-r30 Apr 3, 2025
5c838a5
re-running notebook for fixing cell output error (#2597)
Kaustbh Apr 3, 2025
0f3343d
Docstring (#2609)
kavya-r30 Apr 3, 2025
f7b57df
[DOC] Add 'Raises' section to docstring #1766 (#2617)
ayushsingh9720 Apr 3, 2025
0fd1b51
[DOC] Contributor docs update (#2554)
MatthewMiddlehurst Apr 4, 2025
8c3f739
prevent assignment on PRs (#2703)
shinymack Apr 4, 2025
530cc09
Update run_examples.sh (#2701)
MatthewMiddlehurst Apr 5, 2025
c547ac6
[BUG] SevenNumberSummary bugfix and input rename (#2555)
MatthewMiddlehurst Apr 5, 2025
d727d95
readme (#2556)
MatthewMiddlehurst Apr 5, 2025
eb3a111
remove MutilROCKETRegressor from alias mapping (#2623)
Kaustbh Apr 5, 2025
ebcd632
Automated `pre-commit` hook update (#2731)
aeon-actions-bot[bot] Apr 7, 2025
7d589b0
[MNT] Bump the github-actions group with 2 updates (#2733)
dependabot[bot] Apr 7, 2025
4f4e1fe
Fixed a few spelling/grammar mistakes on TSC docs examples (#2738)
HaroonAzamFiza Apr 11, 2025
ace55e7
Fix docstring inconsistencies in benchmarking module (resolves #809) …
adityagh006 Apr 11, 2025
4c15cc7
[ENH] `best_on_top` addition in `plot_pairwise_scatter` (#2655)
aryanpola Apr 11, 2025
792dbef
[ENH] Add dummy clusterer tags (#2551)
MatthewMiddlehurst Apr 11, 2025
7240e98
[ENH] Collection conversion cleanup and `df-list` fix (#2654)
MatthewMiddlehurst Apr 11, 2025
f1d4da2
[MNT] Updated the release workflows (#2638)
MatthewMiddlehurst Apr 11, 2025
5ab8b6b
[MNT,ENH] Update to allow Python 3.13 (#2608)
MatthewMiddlehurst Apr 11, 2025
4be76cb
[ENH] Hard-Coded Tests for `test_metrics.py` (#2672)
aryanpola Apr 11, 2025
376705f
Changed single ticks to double (#2640)
Val-2608 Apr 11, 2025
5a0f229
📝 Add HaroonAzamFiza as a contributor for doc (#2740)
allcontributors[bot] Apr 11, 2025
4235288
[ENH,MNT] Assign Bot (assigned issues>2) (#2702)
aryanpola Apr 12, 2025
c322291
[MNT,ENH] Assign-bot (Allow users to type alternative phrases for ass…
Ramana-Raja Apr 12, 2025
6169ed2
📝 Add Ramana-Raja as a contributor for code (#2741)
allcontributors[bot] Apr 12, 2025
7c25328
Release v1.1.0 (#2696)
MatthewMiddlehurst Apr 13, 2025
f9c0fef
Automated `pre-commit` hook update (#2743)
aeon-actions-bot[bot] Apr 14, 2025
8cf3277
[MNT] Bump the github-actions group with 2 updates (#2744)
dependabot[bot] Apr 14, 2025
78a4a75
[DOC] Add implementation references (#2748)
MatthewMiddlehurst Apr 20, 2025
c92958f
use gpu installs for periodic tests (#2747)
MatthewMiddlehurst Apr 20, 2025
f7618c6
Use shape calculation in _fit to optimize QUANTTransformer (#2727)
shinymack Apr 20, 2025
917123b
[REF] Refactor Anomaly Detection Module into Submodules by Algorithm …
Kaustbh Apr 20, 2025
1269091
Automated `pre-commit` hook update (#2756)
aeon-actions-bot[bot] Apr 21, 2025
ce29de4
[ENH]Type hints/forecasting (#2737)
Ahmed-Zahran02 Apr 25, 2025
a87ed2d
Automated `pre-commit` hook update (#2766)
aeon-actions-bot[bot] Apr 30, 2025
0d4f5c7
[ENH] Implement `load_model` function for ensemble classifiers (#2631)
inclinedadarsh May 1, 2025
9c42e52
Update _ae_abgru.py (#2771)
hadifawaz1999 May 2, 2025
ab7864e
Automated `pre-commit` hook update (#2779)
aeon-actions-bot[bot] May 5, 2025
8a151e4
[DOC] Fix Broken [Source] Link and Improve Documentation for suppress…
Kaustbh May 5, 2025
ff0cb4f
base transform tidy (#2773)
MatthewMiddlehurst May 8, 2025
96ac60b
DOC: Add Raises section for invalid weights in KNeighborsTimeSeriesCl…
SomtoOnyekwelu May 8, 2025
35e1ade
[ENH] Fixes Issue Improve `_check_params` method in `kmeans.py` and `…
tanishy7777 May 8, 2025
16c7bb8
[ENH] Add type hints for deep learning regression classes (#2644)
saadaltohamy May 8, 2025
af0a25c
[DOC] Add RotationForest Classifier Notebook for Time Series Classifi…
Kaustbh May 8, 2025
beadc75
fix: Codeowners for benchmarking metrics AD (#2784)
SebastianSchmidl May 9, 2025
21c2280
[GOV] Supporting Developer role (#2775)
MatthewMiddlehurst May 9, 2025
0ede6e3
[MNT, ENH, DOC] Rework similarity search (#2473)
baraline May 10, 2025
cf0d478
[ENH] Adapt the DCNN Networks to use Weight Norm Wrappers (#2628)
aadya940 May 11, 2025
17d5081
[GOV] Remove inactive developers (#2776)
MatthewMiddlehurst May 12, 2025
02b6c52
Automated `pre-commit` hook update (#2792)
aeon-actions-bot[bot] May 12, 2025
1372640
Add SomtoOnyekwelu to .all-contributorsrc (#2788)
SomtoOnyekwelu May 13, 2025
01850a7
Automated `CONTRIBUTORS.md` update (#2794)
aeon-actions-bot[bot] May 13, 2025
5c92811
[BUG] Fix a bug in ClaSP Series Transformer when using floatXX as Inp…
patrickzib May 15, 2025
4ea649c
[DOC] Changed SummaryClusterer's summary_stat from "percentiles" to "…
Ramana-Raja May 15, 2025
a668f6d
[ENH] Test coverage for AEAttentionBiGRUNetwork Improved (#2540)
lucifer4073 May 15, 2025
bb36e91
[BUG] Better error message for Rotation Forest with no usable attribu…
MatthewMiddlehurst May 16, 2025
2d32e0f
[DOC] Inconsistent double ticks in segmentation package, public docst…
nMaax May 16, 2025
9ece5af
put lower bound keras (#2808)
hadifawaz1999 May 16, 2025
7f4b38c
[REF] Refactor smoothing transformers into a sub-package (#2783)
MatthewMiddlehurst May 16, 2025
572c3d8
[ENH] Refactor range-based metrics to restore original behavior (#2781)
SebastianSchmidl May 16, 2025
90ea9a6
[ENH]Use n_jobs parameter in KNeighborsTimeSeriesClassifier. (#2687)
steenrotsman May 16, 2025
b33e6c7
[ENH] add informational tags back to estimator docs (#2652)
inclinedadarsh May 17, 2025
41c14ac
[DOC] Documentation improvement of BaseSeriesEstimator and BaseAeonEs…
kevinzb56 May 18, 2025
8a6cfaf
[ENH] HydraTransformer Output changed (#2656)
lucifer4073 May 18, 2025
06f7a58
[DOC] Improved Hidalgo Segmentation Notebook (#2616)
kavya-r30 May 18, 2025
4b8aa59
new devs and workflow consolidation (#2797)
MatthewMiddlehurst May 18, 2025
b87c252
all branches (#2809)
MatthewMiddlehurst May 18, 2025
32318d8
Automated `pre-commit` hook update (#2820)
aeon-actions-bot[bot] May 19, 2025
afd8dfb
[MNT] Bump crs-k/stale-branches in the github-actions group (#2821)
dependabot[bot] May 19, 2025
7be99dc
fix: indexing in kdtw (#2826)
SebastianSchmidl May 20, 2025
7153d63
[ENH] Added test cases for feature based clustering (#2690)
Ramana-Raja May 21, 2025
ff7c94f
[DOC] Fix inconsistent double backticks in updated similarity_search…
adityagh006 May 21, 2025
3c6f78b
[ENH] Update `_continuous.py` functions (#2822)
aryanpola May 23, 2025
b4e7906
[MNT] stop segmenters changing state in predict (#2526)
TonyBagnall May 23, 2025
3960a9a
refactor dummy to naive (#2831)
TonyBagnall May 23, 2025
9331bd0
[ENH] add a difference transformer to series transformations (#2729)
TinaJin0228 May 23, 2025
2b49aa7
Automated `CONTRIBUTORS.md` update (#2832)
aeon-actions-bot[bot] May 23, 2025
2fac9f7
[BUG] Fix data loader (#2810)
TonyBagnall May 26, 2025
ff1c383
Automated `pre-commit` hook update (#2841)
aeon-actions-bot[bot] May 26, 2025
6d0c86f
📝 Add lucifer4073 as a contributor for code (#2846)
allcontributors[bot] May 27, 2025
38690fa
[BUG] Adds test case for using csr_matrix with pickle - invalidates #…
patrickzib May 28, 2025
4ac2633
[DOC] Docstring improved for dummy regressor (#2839)
lucifer4073 May 29, 2025
22b9677
remove numba typing (#2858)
TonyBagnall May 30, 2025
45d8d8f
[DOC] Regression forecaster docstring (#2837)
TonyBagnall May 30, 2025
bdbcd89
[ENH] Whole-series anomaly detection (#2326)
MatthewMiddlehurst May 30, 2025
2f5330e
[MNT] Bump the github-actions group across 1 directory with 2 updates…
dependabot[bot] Jun 2, 2025
c3cb9a0
Automated `pre-commit` hook update (#2867)
aeon-actions-bot[bot] Jun 2, 2025
c0c6684
[ENH] introduce revised version of ETS (#2834)
TonyBagnall Jun 2, 2025
2932628
[DOC] Update the projects lists (#2146)
TonyBagnall Jun 3, 2025
0620255
[DEP] Remove `prts` dependency (#2863)
MatthewMiddlehurst Jun 3, 2025
3ce184b
[ENH] Starting Self Supervised Model with first example (#2385)
hadifawaz1999 Jun 3, 2025
8890036
update slack link (#2877)
MatthewMiddlehurst Jun 5, 2025
ca509f4
[BUG] Switch results loaders from http to https (#2883)
TonyBagnall Jun 6, 2025
f8c6d8c
[ENH] Correct broken source links for `set_params` and `get_params` i…
Kaustbh Jun 6, 2025
d28a134
open PR comment changes (#2878)
MatthewMiddlehurst Jun 8, 2025
f1e0b96
[ENH] Implemented Tracking differentiator-based multiview dilated cha…
lucifer4073 Jun 8, 2025
1262254
Automated `pre-commit` hook update (#2888)
aeon-actions-bot[bot] Jun 9, 2025
eb85272
[MNT] Update pandas requirement in the python-packages group (#2889)
dependabot[bot] Jun 9, 2025
a5fdb59
[MNT] Drop Python 3.9 (#2845)
MatthewMiddlehurst Jun 9, 2025
4f23992
[ENH] Series transformer pipeline and datatype list tidy (#2830)
MatthewMiddlehurst Jun 9, 2025
139239f
[ENH] Multivariate and unequal PF, speed-ups and distance classifier …
MatthewMiddlehurst Jun 9, 2025
16b848e
[ENH] Add two forecasting tags (#2882)
TonyBagnall Jun 9, 2025
b949eab
[DOC] A fix to inconsistent double tick quote for the classification.…
Ahmed-Zahran02 Jun 9, 2025
ec505f9
📝 Add Ahmed-Zahran02 as a contributor for doc (#2892)
allcontributors[bot] Jun 9, 2025
72944dc
[BUG] Forecasting regressor fix and notebook (#2885)
TonyBagnall Jun 9, 2025
3f6ef5f
📝 Add AnaghDeshpande as a contributor for doc (#2896)
allcontributors[bot] Jun 9, 2025
9e66f16
[GOV] Use the NumFOCUS code of conduct and rename `aeon` workgroup (#…
MatthewMiddlehurst Jun 10, 2025
2a5485b
[DOC] resolved the inconsistency of double ticks for the anomaly dete…
AnaghDeshpande Jun 11, 2025
c69fd75
[ENH] Forecasting testing (#2891)
MatthewMiddlehurst Jun 11, 2025
a1e9dc0
[MNT] Fixing CI issues and separate doctests from regular CI runners …
MatthewMiddlehurst Jun 14, 2025
3235b35
[BUG] Fixes a bug with SFAFast throwing an error when calling transfo…
patrickzib Jun 15, 2025
57207e0
[MNT] Bump stefanzweifel/git-auto-commit-action from 5 to 6 in the gi…
dependabot[bot] Jun 16, 2025
600ecad
[ENH] Added RNN in networks (#2875)
lucifer4073 Jun 16, 2025
430783f
Update README.md (#2908)
MatthewMiddlehurst Jun 16, 2025
c9b8a44
[ENH] Add recursive and direct methods to forecasting base class (#2…
TonyBagnall Jun 18, 2025
fc99068
[ENH] remove horizon from ETS constructor, parametrize ETS tests (#2898)
TonyBagnall Jun 18, 2025
ccf5b44
[ENH] Refactor example dataset for unequal length univariate (#2859)
TonyBagnall Jun 18, 2025
8c8abe8
[ENH, REF]Refactored time-point based ROCKAD implementation (#2804)
pattplatt Jun 19, 2025
3dda595
[ENH] enhance naive forecaster with new strategies (#2869)
TinaJin0228 Jun 19, 2025
b834340
[ENH,REF] Unequal length collection transforms (#2903)
MatthewMiddlehurst Jun 20, 2025
8cc8751
Release v1.2.0 (#2912)
MatthewMiddlehurst Jun 23, 2025
4c57abf
Automated `pre-commit` hook update (#2914)
aeon-actions-bot[bot] Jun 23, 2025
2b6e32f
[MNT] Comments on numba caching and release CI fix (#2916)
MatthewMiddlehurst Jun 23, 2025
b9380c3
[ENH] Improves `create_multi_comparison_matrix` parameters and saving…
aryanpola Jun 24, 2025
098fdcd
[MNT] Prevents assignment on Restricted Labels (#2706)
kavya-r30 Jun 25, 2025
c7a23a5
[MNT] Update scikit-learn requirement from <1.7.0,>=1.0.0 to >=1.0.0,…
dependabot[bot] Jun 25, 2025
4ff6032
[MNT] issue-assign-bot - only users with write access should be able …
shinymack Jun 25, 2025
b5d4db9
[MNT] Created workflow for closing "AI Spam" pull requests (#2750)
Ramana-Raja Jun 25, 2025
fe90785
[ENH] Use `np.argpartition` for efficient top-k selection instead of …
Kaustbh Jun 26, 2025
801363d
[EHN] Allow exogenous variables in regression forecasters (#2915)
TinaJin0228 Jun 27, 2025
748fad0
Automated `pre-commit` hook update (#2922)
aeon-actions-bot[bot] Jun 30, 2025
8f64173
[MNT] Bump actions/create-github-app-token in the github-actions grou…
dependabot[bot] Jun 30, 2025
97135da
[ENH] Added RecurrentRegressor for time series regression (#2894)
lucifer4073 Jul 2, 2025
95258d2
[MNT] Add testing workflow for multithreading and make threaded estim…
MatthewMiddlehurst Jul 2, 2025
092b577
[DOC,MNT] Documentation configuration clean-up (#2911)
MatthewMiddlehurst Jul 3, 2025
18fc7ed
[DOC] fix incorrect references of classes in getting started page (#2…
inclinedadarsh Jul 3, 2025
0c70f47
Automated `pre-commit` hook update (#2932)
aeon-actions-bot[bot] Jul 7, 2025
edc972c
[DOC] Add RecurrentRegressor and RecurrentNetowork to api_reference (…
lucifer4073 Jul 7, 2025
c235108
[ENH] Refactor to set forecast_ in fit and to require y in predict (#…
TonyBagnall Jul 10, 2025
6d05596
[ENH] Clone estimator in direct forecast (#2936)
TonyBagnall Jul 10, 2025
c0c4efa
[ENH] Implement Time-Varying Parameter (TVP) regression forecaster us…
TonyBagnall Jul 10, 2025
73662ab
[MNT] Add codespell support (config, workflow to detect/not fix) and …
yarikoptic Jul 11, 2025
30cfd15
typo (#2944)
TonyBagnall Jul 12, 2025
681c69c
correct checkout (#2945)
MatthewMiddlehurst Jul 12, 2025
82905bd
DOC: fix typos in MatrixProfileSeriesTransformer (#2940) (#2941)
CodeFor2001 Jul 12, 2025
ec2b171
📝 Add CodeFor2001 as a contributor for doc (#2946)
allcontributors[bot] Jul 12, 2025
5aa0163
[ENH] Rework ETS Forecaster (#2939)
TonyBagnall Jul 16, 2025
a7521c7
[MNT] add n_jobs parameter for sax invertion (#2953)
baraline Jul 19, 2025
c7e74cb
Automated `pre-commit` hook update (#2949)
aeon-actions-bot[bot] Jul 23, 2025
ccee1b7
[DEP] Deprecate PLAID dataset (#2928)
TonyBagnall Jul 26, 2025
de241e0
[DOC] Classification notebook links (#2942)
TonyBagnall Jul 26, 2025
08cd443
[ENH] Added TemporalConvolutionalNetwork in aeon/networks (#2933)
lucifer4073 Jul 26, 2025
755154b
[BUG] Improve signature docs (#2929)
TonyBagnall Jul 27, 2025
ae57c1b
[MNT] Workflow maintenance (#2919)
MatthewMiddlehurst Jul 27, 2025
d9a5c7b
[ENH] Add Basic ARIMA model (#2860)
alexbanwell1 Jul 28, 2025
1e6e8c8
Automated `pre-commit` hook update (#2959)
aeon-actions-bot[bot] Jul 28, 2025
1b65310
clean space for swap CI to stop sporadic failue (#2965)
MatthewMiddlehurst Jul 28, 2025
a7c6723
[MNT] Bump crs-k/stale-branches in the github-actions group (#2950)
dependabot[bot] Jul 28, 2025
d29cead
[ENH] New experimental module: imbalance in collection transformers (…
TonyBagnall Jul 29, 2025
bb9da38
stop overwriting y (#2969)
TonyBagnall Jul 29, 2025
a7623de
[BUG] Fix redcomets bug when using only one sample (#2952)
baraline Jul 30, 2025
9096b3e
[DEP] Remove deprecated transforms (#2961)
MatthewMiddlehurst Jul 30, 2025
17a9a50
merge main
chrisholder Jul 30, 2025
50568eb
updated dtw gi
chrisholder Jul 30, 2025
b1094ee
debug
chrisholder Jul 30, 2025
f757c0f
debug
chrisholder Jul 30, 2025
828d0bf
debug
chrisholder Jul 30, 2025
280a9b1
debug
chrisholder Jul 30, 2025
3efcf61
fix
chrisholder Jul 30, 2025
72f28eb
merged distances
chrisholder Jul 31, 2025
0fce862
refactored regressor
chrisholder Aug 4, 2025
e408ee3
merge main
chrisholder Aug 7, 2025
4ea3b48
removed file
chrisholder Aug 7, 2025
e18a730
added test for knn regressor kneighbors
chrisholder Aug 7, 2025
28e9f72
fixed sklearn compatiability tests
chrisholder Aug 7, 2025
0c17ff8
cleaned up and commented kneighbors function
chrisholder Aug 8, 2025
0e1c1e9
fixed when list passed
chrisholder Aug 8, 2025
ce49955
added public and private methods for kneigbors and additionally expan…
chrisholder Aug 10, 2025
30577c3
removed threaded decorator and swapped to private method
chrisholder Aug 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
209 changes: 143 additions & 66 deletions aeon/classification/distance_based/_time_series_neighbors.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,18 @@
distances in aeon.distances.
"""

import numbers
from typing import Optional

__maintainer__ = []
__all__ = ["KNeighborsTimeSeriesClassifier"]

from typing import Callable, Optional, Union
from typing import Callable, Union

import numpy as np
from joblib import Parallel, delayed

from aeon.classification.base import BaseClassifier
from aeon.distances import get_distance_function
from aeon.distances import pairwise_distance
from aeon.utils.validation import check_n_jobs

WEIGHTS_SUPPORTED = ["uniform", "distance"]
Expand Down Expand Up @@ -47,21 +49,17 @@ class KNeighborsTimeSeriesClassifier(BaseClassifier):
n_timepoints)` as input and returns a ``float``.
distance_params : dict, default = None
Dictionary for metric parameters for the case that distance is a ``str``.
n_jobs : int, default = 1
The number of parallel jobs to run for neighbors search.
``None`` means 1 unless in a :obj:``joblib.parallel_backend`` context.
``-1`` means using all processors.
parallel_backend : str, ParallelBackendBase instance or None, default=None
Specify the parallelisation backend implementation in joblib, if None
a ‘prefer’ value of “threads” is used by default. Valid options are
“loky”, “multiprocessing”, “threading” or a custom backend.
See the joblib Parallel documentation for more details.
n_jobs : int, default=1
The number of jobs to run in parallel. If -1, then the number of jobs is set
to the number of CPU cores. If 1, then the function is executed in a single
thread. If greater than 1, then the function is executed in parallel.

Raises
------
ValueError
If ``weights`` is not among the supported values.
See the ``weights`` parameter description for valid options.
Dictionary for metric parameters for the case that distance is a str.

Examples
--------
Expand Down Expand Up @@ -90,13 +88,11 @@ def __init__(
n_neighbors: int = 1,
weights: Union[str, Callable] = "uniform",
n_jobs: int = 1,
parallel_backend: str = None,
) -> None:
self.distance = distance
self.distance_params = distance_params
self.n_neighbors = n_neighbors
self.n_jobs = n_jobs
self.parallel_backend = parallel_backend

self._distance_params = distance_params
if self._distance_params is None:
Expand Down Expand Up @@ -124,7 +120,6 @@ def _fit(self, X, y):
y : array-like, shape = (n_cases)
The class labels.
"""
self.metric_ = get_distance_function(method=self.distance)
self.X_ = X
_, self.y_ = np.unique(y, return_inverse=True)
self._n_jobs = check_n_jobs(self.n_jobs)
Expand All @@ -148,10 +143,26 @@ def _predict_proba(self, X):
The class probabilities of the input samples. Classes are ordered
by lexicographic order.
"""
preds = Parallel(n_jobs=self._n_jobs, backend=self.parallel_backend)(
delayed(self._proba_row)(x) for x in X
)
return np.array(preds)
preds = np.zeros((len(X), len(self.classes_)))
for i in range(len(X)):
neigh_dist, neigh_ind = self.kneighbors(X[i : i + 1])
neigh_dist = neigh_dist[0]
neigh_ind = neigh_ind[0]

if self.weights == "distance":
weights = 1 / (neigh_dist + np.finfo(float).eps)
elif self.weights == "uniform":
weights = np.repeat(1.0, len(neigh_ind))
else:
raise Exception(f"Invalid kNN weights: {self.weights}")

for id, w in zip(neigh_ind, weights):
predicted_class = self.y_[id]
preds[i, predicted_class] += w

preds[i] = preds[i] / np.sum(preds[i])

return preds

def _predict(self, X):
"""
Expand All @@ -170,70 +181,136 @@ def _predict(self, X):
y : array of shape (n_cases)
Class labels for each data sample.
"""
preds = Parallel(n_jobs=self._n_jobs, backend=self.parallel_backend)(
delayed(self._predict_row)(x) for x in X
self._check_is_fitted()

neigh_ind = self._kneighbors(
X, n_neighbors=1, return_distance=False, query_is_train=False
)
return np.array(preds, dtype=self.classes_.dtype)
indexes = neigh_ind[:, 0]
return self.classes_[self.y_[indexes]]

def _proba_row(self, x):
scores = self._predict_scores(x)
return scores / np.sum(scores)
def kneighbors(self, X=None, n_neighbors=None, return_distance=True):
"""Find the K-neighbors of a point.

def _predict_row(self, x):
scores = self._predict_scores(x)
return self.classes_[np.argmax(scores)]
Returns indices of and distances to the neighbors of each point.

def _predict_scores(self, x):
scores = np.zeros(len(self.classes_))
idx, weights = self._kneighbors(x)
for id, weight in zip(idx, weights):
predicted_class = self.y_[id]
scores[predicted_class] += weight
return scores
Parameters
----------
X : 3D np.ndarray of shape = (n_cases, n_channels, n_timepoints) or list of
shape [n_cases] of 2D arrays shape (n_channels,n_timepoints_i)
The query point or points.
If not provided, neighbors of each indexed point are returned.
In this case, the query point is not considered its own neighbor.
n_neighbors : int, default=None
Number of neighbors required for each sample. The default is the value
passed to the constructor.
return_distance : bool, default=True
Whether or not to return the distances.

def _kneighbors(self, X):
Returns
-------
neigh_dist : ndarray of shape (n_queries, n_neighbors)
Array representing the distances to points, only present if
return_distance=True.
neigh_ind : ndarray of shape (n_queries, n_neighbors)
Indices of the nearest points in the population matrix.
"""
Find the K-neighbors of a point.
self._check_is_fitted()

# Input validation
if n_neighbors is None:
n_neighbors = self.n_neighbors
elif not isinstance(n_neighbors, numbers.Integral):
raise TypeError(
f"n_neighbors does not take {type(n_neighbors)} value, enter integer "
f"value"
)
elif n_neighbors <= 0:
raise ValueError(f"Expected n_neighbors > 0. Got {n_neighbors}")

if not isinstance(return_distance, bool):
raise TypeError(
f"return_distance must be a boolean, got {type(return_distance)}"
)

# Preprocess X if provided
query_is_train = X is None
if query_is_train:
X = self.X_
else:
X = self._preprocess_collection(X, store_metadata=False)
self._check_shape(X)

# Validate n_neighbors against data size
n_samples_fit = len(self.X_)
if query_is_train:
if not (n_neighbors < n_samples_fit):
raise ValueError(
"Expected n_neighbors < n_samples_fit, but "
f"n_neighbors = {n_neighbors}, n_samples_fit = {n_samples_fit}, "
f"n_samples = {len(X)}"
)
else:
if not (n_neighbors <= n_samples_fit):
raise ValueError(
"Expected n_neighbors <= n_samples_fit, but "
f"n_neighbors = {n_neighbors}, n_samples_fit = {n_samples_fit}, "
f"n_samples = {len(X)}"
)

Returns indices and weights of each point.
return self._kneighbors(X, n_neighbors, return_distance, query_is_train)

def _kneighbors(self, X, n_neighbors, return_distance, query_is_train):
"""Find the K-neighbors of a point.

Returns indices of and distances to the neighbors of each point.

Parameters
----------
X : np.ndarray
A single time series instance if shape = ``(n_channels, n_timepoints)``
X : 3D np.ndarray of shape = (n_cases, n_channels, n_timepoints) or list of
shape [n_cases] of 2D arrays shape (n_channels,n_timepoints_i)
The query point or points.
n_neighbors : int
Number of neighbors required for each sample.
return_distance : bool
Whether or not to return the distances.
query_is_train : bool
Whether the query points are from the training set.

Returns
-------
ind : array
neigh_dist : ndarray of shape (n_queries, n_neighbors)
Array representing the distances to points, only present if
return_distance=True.
neigh_ind : ndarray of shape (n_queries, n_neighbors)
Indices of the nearest points in the population matrix.
ws : array
Array representing the weights of each neighbor.
"""
distances = np.array(
[
self.metric_(X, self.X_[j], **self._distance_params)
for j in range(len(self.X_))
]
distances = pairwise_distance(
X,
None if query_is_train else self.X_,
method=self.distance,
n_jobs=self.n_jobs,
**self._distance_params,
)

# Find indices of k nearest neighbors using partitioning:
# [0..k-1], [k], [k+1..n-1]
# They might not be ordered within themselves,
# but it is not necessary and partitioning is
# O(n) while sorting is O(nlogn)
closest_idx = np.argpartition(distances, self.n_neighbors)
closest_idx = closest_idx[: self.n_neighbors]

if self.weights == "distance":
ws = distances[closest_idx]
# Using epsilon ~= 0 to avoid division by zero
ws = 1 / (ws + np.finfo(float).eps)
elif self.weights == "uniform":
ws = np.repeat(1.0, self.n_neighbors)
else:
raise Exception(f"Invalid kNN weights: {self.weights}")

return closest_idx, ws
# If querying the training set, exclude self by setting diag to +inf
if query_is_train:
np.fill_diagonal(distances, np.inf)

k = n_neighbors
# 1) partial select smallest k
idx_part = np.argpartition(distances, kth=k - 1, axis=1)[:, :k]
# 2) sort those k by (distance, index)
row_idx = np.arange(distances.shape[0])[:, None]
part_d = distances[row_idx, idx_part]
# argsort by distance, then by index for ties (lexsort uses last key as primary)
order = np.lexsort((idx_part, part_d), axis=1)
neigh_ind = idx_part[row_idx, order]

if return_distance:
neigh_dist = distances[row_idx, neigh_ind]
return neigh_dist, neigh_ind
return neigh_ind

@classmethod
def _get_test_params(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Tests for KNeighborsTimeSeriesClassifier."""

import numpy as np
import pytest

from aeon.classification.distance_based import KNeighborsTimeSeriesClassifier
Expand Down Expand Up @@ -42,12 +43,9 @@
@pytest.mark.parametrize("distance_key", distance_functions)
def test_knn_on_unit_test(distance_key):
"""Test function for elastic knn, to be reinstated soon."""
# load arrowhead data for unit tests
X_train, y_train = load_unit_test(split="train")
X_test, y_test = load_unit_test(split="test")
knn = KNeighborsTimeSeriesClassifier(
distance=distance_key,
)
knn = KNeighborsTimeSeriesClassifier(distance=distance_key)
knn.fit(X_train, y_train)
pred = knn.predict(X_test)
correct = 0
Expand Down Expand Up @@ -77,3 +75,62 @@ def test_knn_bounding_matrix(distance_key):
if pred[j] == y_test[j]:
correct = correct + 1
assert correct == expected_correct_window[distance_key]


@pytest.mark.parametrize("distance_key", distance_functions)
def test_knn_kneighbors(distance_key):
"""Test knn kneighbors with comprehensive validation."""
X_train, y_train = load_unit_test(split="train")
X_test, y_test = load_unit_test(split="test")

knn = KNeighborsTimeSeriesClassifier(distance=distance_key)
knn.fit(X_train, y_train)

# Test basic kneighbors functionality
dists, ind = knn.kneighbors(X_test, n_neighbors=3)
assert isinstance(dists, np.ndarray)
assert isinstance(ind, np.ndarray)
assert dists.shape == (X_test.shape[0], 3)
assert ind.shape == (X_test.shape[0], 3)

# Test that distances are non-negative
assert np.all(dists >= 0)

# Test that indices are within valid range
assert np.all(ind >= 0)
assert np.all(ind < len(X_train))

# Test that distances are sorted (closest first)
assert np.all(dists[:, 0] <= dists[:, 1])
assert np.all(dists[:, 1] <= dists[:, 2])

# Test using kneighbors results to make predictions manually
# This validates that the kneighbors method returns correct neighbor indices
indexes = ind[:, 0]
classes, y = np.unique(y_train, return_inverse=True)
pred = classes[y[indexes]]
correct = 0
for j in range(0, len(pred)):
if pred[j] == y_test[j]:
correct = correct + 1
assert correct == expected_correct_window[distance_key]

# Test kneighbors with different n_neighbors values
dists_2, ind_2 = knn.kneighbors(X_test, n_neighbors=2)
assert dists_2.shape == (X_test.shape[0], 2)
assert ind_2.shape == (X_test.shape[0], 2)

# Test kneighbors without returning distances
ind_only = knn.kneighbors(X_test, n_neighbors=3, return_distance=False)
assert isinstance(ind_only, np.ndarray)
assert ind_only.shape == (X_test.shape[0], 3)
# Should return same indices as when return_distance=True
np.testing.assert_array_equal(ind_only, ind)

# Test kneighbors on training data (should exclude self)
train_dists, train_ind = knn.kneighbors(n_neighbors=2)
assert train_dists.shape == (len(X_train), 2)
assert train_ind.shape == (len(X_train), 2)
# Each point should not be its own neighbor (diagonal should be excluded)
for i in range(len(X_train)):
assert i not in train_ind[i]
Loading