Skip to content

Commit

Permalink
[ENH] purge todo (#995)
Browse files Browse the repository at this point in the history
* switch test example for pipeline

* switch test example for pipeline

* purge todo

* purge todo
  • Loading branch information
TonyBagnall authored Dec 18, 2023
1 parent 778678e commit 8d3daa7
Show file tree
Hide file tree
Showing 28 changed files with 14 additions and 137 deletions.
1 change: 0 additions & 1 deletion aeon/datatypes/_adapter/dask_to_pd.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,6 @@ def ret(valid, msg, metadata, return_metadata):
# check whether index is equally spaced or if there are any nans
# compute only if needed
if return_metadata:
# todo: logic for equal spacing
metadata["is_equally_spaced"] = True
metadata["has_nans"] = obj.isnull().values.any().compute()

Expand Down
1 change: 0 additions & 1 deletion aeon/datatypes/_panel/_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,6 @@ def is_nested_dataframe(obj, return_metadata=False, var_name="obj"):
metadata["has_nans"] = _nested_dataframe_has_nans(obj)
metadata["is_equal_length"] = not _nested_dataframe_has_unequal(obj)

# todo: this is temporary override, proper is_empty logic needs to be added
metadata["is_empty"] = False
metadata["is_equally_spaced"] = True
# end hacks
Expand Down
2 changes: 0 additions & 2 deletions aeon/datatypes/_proba/_convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ def convert_pred_interval_to_quantiles(y_pred, inplace=False):
var_names = idx.get_level_values(0)

# treat univariate default name
# todo: maybe not a good idea, remove this...
# here because it's in the current specification
var_names = ["Quantiles" if x == "Coverage" else x for x in var_names]

Expand Down Expand Up @@ -153,7 +152,6 @@ def convert_pred_quantiles_to_interval(y_pred, inplace=False):
var_names = idx.get_level_values(0)

# treat univariate default name
# todo: maybe not a good idea, remove this...
# here because it's in the current specification
var_names = ["Coverage" if x == "Quantiles" else x for x in var_names]

Expand Down
8 changes: 0 additions & 8 deletions aeon/datatypes/tests/test_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,6 @@ def test_check_positive(scitype, mtype, fixture_index):
"""
# retrieve fixture for checking
fixture = get_examples(mtype=mtype, as_scitype=scitype).get(fixture_index)

# todo: possibly remove this once all checks are defined
check_is_defined = (mtype, scitype) in check_dict.keys()

# check fixtures that exist against checks that exist
Expand Down Expand Up @@ -147,7 +145,6 @@ def test_check_metadata_inference(scitype, mtype, fixture_index):
mtype=mtype, as_scitype=scitype, return_metadata=True
).get(fixture_index)

# todo: possibly remove this once all checks are defined
check_is_defined = (mtype, scitype) in check_dict.keys()
# if the examples have no metadata to them, don't test
metadata_provided = expected_metadata is not None
Expand Down Expand Up @@ -203,7 +200,6 @@ def test_check_negative(scitype, mtype):
# retrieve fixture for checking
fixture_wrong_type = fixtures[wrong_mtype].get(i)

# todo: possibly remove this once all checks are defined
check_is_defined = (mtype, scitype) in check_dict.keys()

# check fixtures that exist against checks that exist
Expand Down Expand Up @@ -231,8 +227,6 @@ def test_mtype_infer(scitype, mtype, fixture_index):
"""
# retrieve fixture for checking
fixture = get_examples(mtype=mtype, as_scitype=scitype).get(fixture_index)

# todo: possibly remove this once all checks are defined
check_is_defined = (mtype, scitype) in check_dict.keys()

# check fixtures that exist against checks that exist
Expand Down Expand Up @@ -269,8 +263,6 @@ def test_scitype_infer(scitype, mtype, fixture_index):

# retrieve fixture for checking
fixture = get_examples(mtype=mtype, as_scitype=scitype).get(fixture_index)

# todo: possibly remove this once all checks are defined
check_is_defined = (mtype, scitype) in check_dict.keys()

# check fixtures that exist against checks that exist
Expand Down
3 changes: 0 additions & 3 deletions aeon/forecasting/ardl.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,6 @@ def check_param_validity(self, X):
)
return inner_order, inner_auto_ardl

# todo: implement this, mandatory
def _fit(self, y, X=None, fh=None):
"""Fit forecaster to training data.
Expand Down Expand Up @@ -468,8 +467,6 @@ def _update(self, y, X=None, update_params=True):
mtype_last_seen = self._y_mtype_last_seen
# refit with updated data, not only passed data
self.fit(y=self._y, X=self._X, fh=self._fh)
# todo: should probably be self._fit, not self.fit
# but looping to self.fit for now to avoid interface break
self._y_mtype_last_seen = mtype_last_seen

# if update_params=False, and there are no components, do nothing
Expand Down
9 changes: 0 additions & 9 deletions aeon/forecasting/base/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1421,18 +1421,13 @@ def _check_missing(metadata, obj_name):
if X is not None and y is not None:
if self.get_tag("X-y-must-have-same-index"):
# currently, check_equal_time_index only works for Series
# todo: fix this so the check is general, using get_time_index
if not self.get_tag("ignores-exogeneous-X") and X_scitype == "Series":
check_equal_time_index(X, y, mode="contains")

if y_scitype != X_scitype:
raise TypeError("X and y must have the same scitype")
# end compatibility checking X and y

# todo: add tests that :
# y_inner_scitype are same as X_inner_scitype
# y_inner_scitype always includes "less index" scitypes

# convert X & y to supported inner type, if necessary
#####################################################

Expand Down Expand Up @@ -1886,7 +1881,6 @@ def _update(self, y, X=None, update_params=True):
_converter_store_y = self._converter_store_y
# refit with updated data, not only passed data
self.fit(y=self._y, X=self._X, fh=self._fh)
# todo: should probably be self._fit, not self.fit
# but looping to self.fit for now to avoid interface break
self._y_mtype_last_seen = mtype_last_seen
self._converter_store_y = _converter_store_y
Expand Down Expand Up @@ -2125,7 +2119,6 @@ def _predict_var(self, fh=None, X=None, cov=False):
)

if implements_proba:
# todo: this works only univariate now, need to implement multivariate
pred_var = self._predict_proba(fh=fh, X=X)
pred_var = pd.DataFrame(pred_var)

Expand Down Expand Up @@ -2165,8 +2158,6 @@ def _predict_var(self, fh=None, X=None, cov=False):

return pred_var

# todo: does not work properly for multivariate or hierarchical
# still need to implement this - once interface is consolidated
def _predict_proba(self, fh, X, marginal=True):
"""Compute/return fully probabilistic forecasts.
Expand Down
19 changes: 1 addition & 18 deletions aeon/forecasting/base/_fh.py
Original file line number Diff line number Diff line change
Expand Up @@ -686,24 +686,7 @@ def _to_relative(fh: ForecastingHorizon, cutoff=None) -> ForecastingHorizon:
# time deltas
absolute = _coerce_to_period(absolute, freq=fh.freq)
cutoff = _coerce_to_period(cutoff, freq=fh.freq)

# TODO: Replace when we upgrade our lower pandas bound
# to a version where this is fixed
# Compute relative values
# The following line circumvents the bug in pandas
# periods = pd.period_range(start="2021-01-01", periods=3, freq="2H")
# periods - periods[0]
# Out: Index([<0 * Hours>, <4 * Hours>, <8 * Hours>], dtype = 'object')
# [v - periods[0] for v in periods]
# Out: Index([<0 * Hours>, <2 * Hours>, <4 * Hours>], dtype='object')
# TODO: 0.17.0: Check if this comment below can be removed,
# so check if pandas has released the fix to PyPI:
# This bug was reported: https://github.com/pandas-dev/pandas/issues/45999
# and fixed: https://github.com/pandas-dev/pandas/pull/46006
# Most likely it will be released with pandas 1.5
# Once the bug is fixed the line should simply be:
# relative = absolute - cutoff
relative = pd.Index([date - cutoff for date in absolute])
relative = absolute - cutoff

# Coerce durations (time deltas) into integer values for given frequency
if isinstance(absolute, (pd.PeriodIndex, pd.DatetimeIndex)):
Expand Down
2 changes: 0 additions & 2 deletions aeon/forecasting/compose/_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -1461,8 +1461,6 @@ def _predict_var(self, fh=None, X=None, cov=False):
y_pred = self.forecaster_y_.predict_var(fh=fh, X=X)
return y_pred

# todo: does not work properly for multivariate or hierarchical
# still need to implement this - once interface is consolidated
def _predict_proba(self, fh, X, marginal=True):
"""Compute/return fully probabilistic forecasts.
Expand Down
12 changes: 5 additions & 7 deletions aeon/forecasting/compose/_reduce.py
Original file line number Diff line number Diff line change
Expand Up @@ -973,7 +973,6 @@ def _fit(self, y, X=None, fh=None):
self : Estimator
An fitted instance of self.
"""
# todo: logic for X below is broken. Escape X until fixed.
if X is not None:
X = None

Expand Down Expand Up @@ -1033,7 +1032,7 @@ def _predict_last_window(
y_pred = pd.Series or pd.DataFrame
"""
# Exogenous variables are not yet support for the dirrec strategy.
# todo: implement this. For now, we escape.

if X is not None:
X = None

Expand Down Expand Up @@ -2144,21 +2143,20 @@ def _fit(self, y, X=None, fh=None):
Parameters
----------
y : pd.DataFrame
mtype is pd.DataFrame, pd-multiindex, or pd_multiindex_hier
pd.DataFrame, pd-multiindex, or pd_multiindex_hier
Time series to which to fit the forecaster.
fh : guaranteed to be ForecastingHorizon or None, optional (default=None)
The forecasting horizon with the steps ahead to to predict.
Required (non-optional) here if self.get_tag("requires-fh-in-fit")==True
Otherwise, if not passed in _fit, guaranteed to be passed in _predict
X : pd.DataFrame optional (default=None)
mtype is pd.DataFrame, pd-multiindex, or pd_multiindex_hier
pd.DataFrame, pd-multiindex, or pd_multiindex_hier
Exogeneous time series to fit to.
Returns
-------
self : reference to self
"""
# todo: very similar to _fit_concurrent of DirectReductionForecaster - refactor?
from aeon.transformations.impute import Imputer
from aeon.transformations.lag import Lag

Expand Down Expand Up @@ -2211,7 +2209,7 @@ def _predict(self, X=None, fh=None):
The forecasting horizon with the steps ahead to to predict.
If not passed in _fit, guaranteed to be passed here
X : pd.DataFrame, optional (default=None)
mtype is pd.DataFrame, pd-multiindex, or pd_multiindex_hier
pd.DataFrame, pd-multiindex, or pd_multiindex_hier
Exogeneous time series for the forecast
Returns
Expand Down Expand Up @@ -2378,7 +2376,7 @@ def get_test_params(cls, parameter_set="default"):
params1 = {
"estimator": est,
"window_length": 3,
"pooling": "global", # all internal mtypes are tested across scenarios
"pooling": "global",
}

return params1
5 changes: 0 additions & 5 deletions aeon/forecasting/model_selection/tests/test_split.py
Original file line number Diff line number Diff line change
Expand Up @@ -475,11 +475,6 @@ def test_split_by_fh(index_type, fh_type, is_relative, values):
"""Test temporal_train_test_split."""
if fh_type == "timedelta":
return None
# todo: ensure check_estimator works with pytest.skip like below
# pytest.skip(
# "ForecastingHorizon with timedelta values "
# "is currently experimental and not supported everywhere"
# )
y = _make_series(20, index_type=index_type)
cutoff = get_cutoff(y.iloc[:10], return_index=True)
fh = _make_fh(cutoff, values, fh_type, is_relative)
Expand Down
2 changes: 0 additions & 2 deletions aeon/forecasting/naive.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ def __init__(self, strategy="last", window_length=None, sp=1):
self.window_length = window_length

# Override tag for handling missing data
# todo: remove if GH1367 is fixed
if self.strategy in ("last", "mean"):
self.set_tags(**{"capability:missing_values": True})

Expand Down Expand Up @@ -335,7 +334,6 @@ def _predict(self, fh=None, X=None):
# test_predict_time_index_in_sample_full[ForecastingPipeline-0-int-int-True]
# causes a pd.DataFrame to appear as y_pred, which upsets the next lines
# reasons are unclear, this is coming from the _BaseWindowForecaster
# todo: investigate this
if isinstance(y_pred, pd.DataFrame):
y_pred = y_pred.iloc[:, 0]

Expand Down
1 change: 0 additions & 1 deletion aeon/forecasting/reconcile.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
"ciaran-g",
]

# todo: top down historical proportions? -> new _get_g_matrix_prop(self)

from warnings import warn

Expand Down
18 changes: 0 additions & 18 deletions aeon/forecasting/tests/test_all_forecasters.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@ def test_get_fitted_params(self, estimator_instance, scenario):
except NotImplementedError:
pass

# todo: should these not be checked in test_all_estimators?
def test_raises_not_fitted_error(self, estimator_instance):
"""Test that calling post-fit methods before fit raises error."""
# We here check extra method of the forecaster API: update and update_predict.
Expand Down Expand Up @@ -177,14 +176,12 @@ def test_y_multivariate_raises_error(self, estimator_instance):
# and "univariate" automatically vectorizes, behaves multivariate
pass

# todo: should these not be "negative scenarios", tested in test_all_estimators?
@pytest.mark.parametrize("y", INVALID_y_INPUT_TYPES)
def test_y_invalid_type_raises_error(self, estimator_instance, y):
"""Test that invalid y input types raise error."""
with pytest.raises(TypeError, match=r"type"):
estimator_instance.fit(y, fh=FH0)

# todo: should these not be "negative scenarios", tested in test_all_estimators?
@pytest.mark.parametrize("X", INVALID_X_INPUT_TYPES)
def test_X_invalid_type_raises_error(self, estimator_instance, n_columns, X):
"""Test that invalid X input types raise error."""
Expand All @@ -208,11 +205,6 @@ def test_predict_residuals(
if fh_type == "timedelta":
# workaround to ensure check_estimator without breaking e.g. debugging
return None
# todo: ensure check_estimator works with pytest.skip like below
# pytest.skip(
# "ForecastingHorizon with timedelta values "
# "is currently experimental and not supported everywhere"
# )
y_train = _make_series(
n_columns=n_columns, index_type=index_type, n_timepoints=50
)
Expand Down Expand Up @@ -244,11 +236,6 @@ def test_predict_time_index_with_X(
index_type, fh_type, is_relative = index_fh_comb
if fh_type == "timedelta":
return None
# todo: ensure check_estimator works with pytest.skip like below
# pytest.skip(
# "ForecastingHorizon with timedelta values "
# "is currently experimental and not supported everywhere"
# )
z, X = make_forecasting_problem(index_type=index_type, make_X=True)

# Some estimators may not support all time index types and fh types, hence we
Expand Down Expand Up @@ -278,11 +265,6 @@ def test_predict_time_index_in_sample_full(
index_type, fh_type, is_relative = index_fh_comb
if fh_type == "timedelta":
return None
# todo: ensure check_estimator works with pytest.skip like below
# pytest.skip(
# "ForecastingHorizon with timedelta values "
# "is currently experimental and not supported everywhere"
# )
y_train = _make_series(n_columns=n_columns, index_type=index_type)
cutoff = get_cutoff(y_train, return_index=True)
steps = -np.arange(len(y_train))
Expand Down
3 changes: 0 additions & 3 deletions aeon/forecasting/theta.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,6 @@ def _predict_quantiles(self, fh, X=None, alpha=None):
# we assume normal additive noise with sem variance
for a in alpha:
pred_quantiles[("Quantiles", a)] = y_pred + norm.ppf(a) * sem
# todo: should this not increase with the horizon?
# i.e., sth like norm.ppf(a) * sem * fh.to_absolute(cutoff) ?
# I've just refactored this so will leave it for now

return pred_quantiles

Expand Down
2 changes: 1 addition & 1 deletion aeon/performance_metrics/forecasting/_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ def _check_consistent_input(self, y_true, y_pred, multioutput, multilevel):
else:
y_pred_orig.columns = y_true.columns
# check multioutput arg
# todo: add this back when variance_weighted is supported
# add this back when variance_weighted is supported
# ("raw_values", "uniform_average", "variance_weighted")
allowed_multioutput_str = ("raw_values", "uniform_average")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
from aeon.datatypes import check_is_scitype, convert
from aeon.performance_metrics.forecasting._classes import BaseForecastingErrorMetric

# TODO: Rework tests now


class _BaseProbaForecastingErrorMetric(BaseForecastingErrorMetric):
"""Base class for probabilistic forecasting error metrics in aeon.
Expand Down Expand Up @@ -419,8 +417,6 @@ def _evaluate_by_index(self, y_true, y_pred, multioutput, **kwargs):
# if alpha was provided, check whether they are predicted
# if not all alpha are observed, raise a ValueError
if not np.isin(alpha, y_pred_alphas).all():
# todo: make error msg more informative
# which alphas are missing
msg = "not all quantile values in alpha are available in y_pred"
raise ValueError(msg)
else:
Expand Down
3 changes: 0 additions & 3 deletions aeon/tests/test_all_estimators.py
Original file line number Diff line number Diff line change
Expand Up @@ -629,8 +629,6 @@ def _check_None_str_or_list_of_str(obj, var_name="obj"):
raise ValueError(msg)
return obj

# todo: surely there is a pytest method that can be called instead of this?
# find and replace if it exists
@staticmethod
def _get_pytest_mark_args(fun):
"""Get args from pytest mark annotation of function.
Expand Down Expand Up @@ -1319,7 +1317,6 @@ def test_dl_constructor_initializes_deeply(self, estimator_class):
if vars(estimator._network).get(key) is not None:
assert vars(estimator._network)[key] == value

# todo: this needs to be diagnosed and fixed - temporary skip
@pytest.mark.skip(reason="hangs on mac and unix remote tests")
def test_multiprocessing_idempotent(
self, estimator_instance, scenario, method_nsc_arraylike
Expand Down
2 changes: 0 additions & 2 deletions aeon/tests/test_softdeps.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@
# for the reason that they are composites which have soft dependencies in examples
# but no soft dependencies themselves, so it's temporarily fine to raise this
# e.g., forecasting pipeline with an ARIMA estimator
# todo: long-term all example parameter settings should be soft dependency free
# strings of class names to avoid the imports
EXCEPTED_FROM_NO_DEP_CHECK = []


Expand Down
2 changes: 1 addition & 1 deletion aeon/transformations/boxcox.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@


# copy-pasted from scipy 1.7.3 since it moved in 1.8.0 and broke this estimator
# todo: find a suitable replacement
# find a suitable replacement
def _calc_uniform_order_statistic_medians(n):
"""Approximations of uniform order statistic medians.
Expand Down
Loading

0 comments on commit 8d3daa7

Please sign in to comment.