diff --git a/.all-contributorsrc b/.all-contributorsrc index 58c43169c2c..c7295bca34b 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1442,6 +1442,7 @@ "avatar_url": "https://avatars.githubusercontent.com/u/7654679?v=4", "profile": "https://github.com/rakshitha123", "contributions": [ + "code", "doc" ] }, @@ -1487,8 +1488,18 @@ "avatar_url": "https://avatars.githubusercontent.com/u/74055102?v=4", "profile": "https://github.com/Saransh-cpp", "contributions": [ - "doc" + "doc", + "infra" ] + }, + { + "login": "RishiKumarRay", + "name": "Rishi Kumar Ray", + "avatar_url": "https://avatars.githubusercontent.com/u/87641376?v=4", + "profile": "https://github.com/RishiKumarRay", + "contributions": [ + "infra" + ] } ], "projectName": "sktime", diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml index f7c860494b2..425dbbe7bd2 100644 --- a/.github/release-drafter.yml +++ b/.github/release-drafter.yml @@ -1,5 +1,22 @@ name-template: 'v$NEXT_PATCH_VERSION' tag-template: 'v$NEXT_PATCH_VERSION' +categories: + - title: '馃殌 Features' + labels: + - 'feature' + - 'enhancement' + - title: '馃悰 Bug Fixes' + labels: + - 'fix' + - 'bugfix' + - 'bug' + - title: '馃О Maintenance' + label: + - 'chore' + - 'maintenance' + - 'refactor' + - 'documentation' + template: | ## What's New diff --git a/.github/workflows/cancel.yml b/.github/workflows/cancel.yml new file mode 100644 index 00000000000..88880a5306a --- /dev/null +++ b/.github/workflows/cancel.yml @@ -0,0 +1,13 @@ +name: Cancel Workflows on Push +on: + workflow_run: + workflows: ["Install and test"] + types: + - requested +jobs: + cancel: + runs-on: ubuntu-latest + steps: + - uses: styfle/cancel-workflow-action@0.9.1 + with: + workflow_id: ${{ github.event.workflow.id }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0b45e3a3e42..73bcc9e3425 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -87,7 +87,7 @@ jobs: cp .coveragerc testdir/ cp setup.cfg testdir/ cd testdir/ - python -m pytest --showlocals --durations=10 --cov-report=xml --cov=sktime -v --pyargs sktime + python -m pytest --showlocals --durations=10 --cov-report=xml --cov=sktime -v -n 2 --pyargs sktime - name: Display coverage report run: ls -l ./testdir/ - name: Publish code coverage diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 3e68ad08032..6d3a95e0fef 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,3 +1,3 @@ # Code of Conduct -You can find our Code of Conduct on our [website](https://www.sktime.org/en/latest/code_of_conduct.html). +You can find our Code of Conduct on our [website](https://www.sktime.org/en/latest/get_involved/code_of_conduct.html). diff --git a/MANIFEST.in b/MANIFEST.in index 3cdf004003d..3ef62c0006b 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -4,5 +4,5 @@ include *.md recursive-include examples * recursive-include sktime *.py recursive-include sktime *.c *.h *.pyx *.pxd *.pxi *.tp -recursive-include sktime/datasets *.csv *.csv.gz *.arff *.arff.gz *.txt *.ts *.tsv +recursive-include sktime/datasets *.csv *.csv.gz *.arff *.arff.gz *.txt *.ts *.tsv *.tsf include LICENSE diff --git a/Makefile b/Makefile index 76b4b8f093d..f9318a3f9f4 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ test: ## Run unit tests mkdir -p ${TEST_DIR} cp .coveragerc ${TEST_DIR} cp setup.cfg ${TEST_DIR} - cd ${TEST_DIR}; python -m pytest --cov-report html --cov=sktime --showlocals --durations=20 --pyargs $(PACKAGE) + cd ${TEST_DIR}; python -m pytest --cov-report html --cov=sktime -v -n 2 --showlocals --durations=20 --pyargs $(PACKAGE) tests: test diff --git a/README.md b/README.md index 47ddfeadca3..0cc7e86c020 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ > A unified interface for machine learning with time series -:rocket: **Version 0.10.0 out now!** [Check out the release notes here](https://www.sktime.org/en/latest/changelog.html). +:rocket: **Version 0.10.1 out now!** [Check out the release notes here](https://www.sktime.org/en/latest/changelog.html). sktime is a library for time series analysis in Python. It provides a unified interface for multiple time series learning tasks. Currently, this includes time series classification, regression, clustering, annotation and forecasting. It comes with [time series algorithms](https://www.sktime.org/en/stable/estimator_overview.html) and [scikit-learn] compatible tools to build, tune and validate time series models. @@ -75,7 +75,7 @@ For **deep learning**, see our companion package: [sktime-dl](https://github.com | Module | Status | Links | |---|---|---| | **[Forecasting]** | stable | [Tutorial](https://www.sktime.org/en/latest/examples/01_forecasting.html) 路 [API Reference](https://www.sktime.org/en/latest/api_reference.html#sktime-forecasting-time-series-forecasting) 路 [Extension Template](https://github.com/alan-turing-institute/sktime/blob/main/extension_templates/forecasting.py) | -| **[Time Series Classification]** | stable | [Tutorial](https://github.com/alan-turing-institute/sktime/blob/main/examples/02_classification_univariate.ipynb) 路 [API Reference](https://www.sktime.org/en/latest/api_reference.html#sktime-classification-time-series-classification) 路 [Extension Template](https://github.com/alan-turing-institute/sktime/blob/main/extension_templates/classification.py) | +| **[Time Series Classification]** | stable | [Tutorial](https://github.com/alan-turing-institute/sktime/blob/main/examples/02_classification.ipynb) 路 [API Reference](https://www.sktime.org/en/latest/api_reference.html#sktime-classification-time-series-classification) 路 [Extension Template](https://github.com/alan-turing-institute/sktime/blob/main/extension_templates/classification.py) | | **[Time Series Regression]** | stable | [API Reference](https://www.sktime.org/en/latest/api_reference.html#sktime-classification-time-series-regression) | | **[Transformations]** | maturing | [API Reference](https://www.sktime.org/en/latest/api_reference.html#sktime-transformations-time-series-transformers) 路 [Extension Template](https://github.com/alan-turing-institute/sktime/blob/main/extension_templates/transformer.py) | | **[Time Series Clustering]** | experimental | [Extension Template](https://github.com/alan-turing-institute/sktime/blob/main/extension_templates/clustering.py) | diff --git a/docs/source/api_reference/forecasting.rst b/docs/source/api_reference/forecasting.rst index 63b423fbcb5..7f1f32ba4d9 100644 --- a/docs/source/api_reference/forecasting.rst +++ b/docs/source/api_reference/forecasting.rst @@ -44,6 +44,7 @@ Trend TrendForecaster PolynomialTrendForecaster + STLForecaster Exponential Smoothing --------------------- diff --git a/docs/source/api_reference/transformations.rst b/docs/source/api_reference/transformations.rst index 580e7af30e0..c7bda008360 100644 --- a/docs/source/api_reference/transformations.rst +++ b/docs/source/api_reference/transformations.rst @@ -293,6 +293,17 @@ Datetime feature generation DateTimeFeatures +Lagged Window Summarizer +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. currentmodule:: sktime.transformations.series.window_summarizer + +.. autosummary:: + :toctree: auto_generated/ + :template: class.rst + + WindowSummarizer + Outlier detection ~~~~~~~~~~~~~~~~~ diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst index c9952b805d9..0be844d142c 100644 --- a/docs/source/changelog.rst +++ b/docs/source/changelog.rst @@ -14,28 +14,123 @@ For upcoming changes and next releases, see our `milestones =1.21.0` and `statsmodels>=0.12.1` +* ``sktime`` now supports python 3.7-3.9. Python 3.6 is no longer supported, due to end of life. Last ``sktime`` version to support python 3.6 was 0.9.0. +* ``sktime`` now supports, and requires, ``numpy>=1.21.0`` and ``statsmodels>=0.12.1`` * overhaul of docs for installation and first-time developers (:pr:`1707`) :user:`amrith-shell` -* all probabilistic forecasters now provide `predict_interval` and `predict_quantiles` interfaces +* all probabilistic forecasters now provide ``predict_interval`` and ``predict_quantiles`` interfaces (:pr:`1842`, :pr:`1874`, :pr:`1879`, :pr:`1910`, :pr:`1961`) :user:`fkiraly` :user:`k1m190r` :user:`kejsitake` * new transformation based pipeline classifiers (:pr:`1721`) :user:`MatthewMiddlehurst` -* developer install for `sktime` no longer requires C compilers and `cython` (:pr:`1761`, :pr:`1847`, :pr:`1932`, :pr:`1927`) :user:`TonyBagnall` +* developer install for ``sktime`` no longer requires C compilers and ``cython`` (:pr:`1761`, :pr:`1847`, :pr:`1932`, :pr:`1927`) :user:`TonyBagnall` * CI/CD moved completely to GitHub actions (:pr:`1620`, :pr:`1920`) :user:`lmmentel` Dependency changes ~~~~~~~~~~~~~~~~~~ -* `sktime` now supports `python` 3.7-3.9 on windows, mac, and unix-based systems -* `sktime` now supports, and requires, `numpy>=1.21.0` and `statsmodels>=0.12.1` -* `sktime` `Prophet` interface now uses `prophet` instead of deprecated `fbprophet` -* developer install for `sktime` no longer requires C compilers and `cython` +* ``sktime`` now supports ``python`` 3.7-3.9 on windows, mac, and unix-based systems +* ``sktime`` now supports, and requires, ``numpy>=1.21.0`` and ``statsmodels>=0.12.1`` +* ``sktime`` ``Prophet`` interface now uses ``prophet`` instead of deprecated ``fbprophet`` +* developer install for ``sktime`` no longer requires C compilers and ``cython`` Core interface changes ~~~~~~~~~~~~~~~~~~~~~~ @@ -65,8 +160,8 @@ Base interface refactor rolled out to series transformers (:pr:`1790`, :pr:`1795 * ``fit``, ``transform``, ``fit_transform`` now accept both ``Series`` and ``Panel`` as argument * if ``Panel`` is passed to a series transformer, it is applied to all instances * all transformers now have signature ``transform(X, y=None)`` and ``inverse_transform(X, y=None)``. This is enforced by the new base interface. -* `Z` (former first argument) aliases `X` until 0.11.0 in series transformers, will then be removed -* `X` (former second argument) was not used in those transformers, was changed to `y` +* ``Z`` (former first argument) aliases ``X`` until 0.11.0 in series transformers, will then be removed +* ``X`` (former second argument) was not used in those transformers, was changed to ``y`` * see transformer base API and transformer extension template Deprecations and removals diff --git a/docs/source/developer_guide.rst b/docs/source/developer_guide.rst index 57503f13b71..e48f3113c64 100644 --- a/docs/source/developer_guide.rst +++ b/docs/source/developer_guide.rst @@ -18,8 +18,8 @@ New developers should: * install a development version of ``sktime``, see :ref:`installation` * set up CI tests locally and ensure they know how to check them remotely, see :ref:`continuous_integration` * get familiar with the git workflow (:ref:`git_workflow`) and coding standards (:ref:`coding_standards`) -* feel free, at any point in time, to post questions on Slack, or ask core developers for help -(see here for a `list of core developers `_) +* feel free, at any point in time, to post questions on Slack, or ask core developers for help (see here for a `list of core developers `_) + * feel free to join the collaborative coding sessions for pair programming or getting help on developer set-up Further special topics are listed below. diff --git a/docs/source/installation.rst b/docs/source/installation.rst index 763cad790c6..68dbbebebce 100644 --- a/docs/source/installation.rst +++ b/docs/source/installation.rst @@ -217,7 +217,7 @@ In the ``anaconda prompt`` terminal: 2. :code:`conda install -c conda-forge prophet` 3. :code:`conda install -c conda-forge scipy` - If you fail to satisfy all the requirements see the troubleshooting section. + If you fail to satisfy all the requirements see the `troubleshooting section `_. 5. Build an editable version of sktime :code:`pip install -e .[all_extras,dev]` 6. If everything has worked you should see message "successfully installed sktime" diff --git a/docs/source/related_software.rst b/docs/source/related_software.rst index 242d28846f0..01783025e5f 100644 --- a/docs/source/related_software.rst +++ b/docs/source/related_software.rst @@ -114,6 +114,8 @@ Libraries - Contains time series preprocessing, transformation as well as classification techniques * - `ruptures `_ - time series annotation: change point detection, segmentation + * - `salesforce-merlion `_ + - Library from salesforce for forecasting, anomaly detection, and change point detection * - `scikit-fda `_ - A Python library to perform Functional Data Analysis, compatible with scikit-learn, including representation, preprocessing, exploratory analysis and machine learning methods * - `scikit-multiflow `_ diff --git a/examples/01_forecasting.ipynb b/examples/01_forecasting.ipynb index f955ec19423..dc1ac7ae0ce 100644 --- a/examples/01_forecasting.ipynb +++ b/examples/01_forecasting.ipynb @@ -125,7 +125,7 @@ "source": [ "This section explains the basic forecasting workflows, and key interface points for it.\n", "\n", - "We cover the following three workflows:\n", + "We cover the following four workflows:\n", "\n", "* basic deployment workflow: batch fitting and forecasting\n", "* basic evaluation workflow: evaluating a batch of forecasts against ground truth observations\n", @@ -148,13 +148,8 @@ "\n", "The `Series.index` and `DataFrame.index` are used for representing the time series or sequence index. `sktime` supports pandas integer, period and timestamp indices.\n", "\n", - "NOTE: at current time (v0.6x), forecasting of multivariate time seres is not a stable functionality, this is a priority roadmap item. Multivariate exogeneous time series are part of stable functionality." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ + "NOTE: at current time (v0.9x), forecasting of multivariate time series is a stable functionality, but not covered in this tutorial. Contributions to extend the tutorial are welcome.\n", + "\n", "**Example:** as the running example in this tutorial, we use a textbook data set, the Box-Jenkins airline data set, which consists of the number of monthly totals of international airline passengers, from 1949 - 1960. Values are in thousands. See \"Makridakis, Wheelwright and Hyndman (1998) Forecasting: methods and applications\", exercises sections 2 and 3." ] }, @@ -1486,7 +1481,7 @@ "\n", "In general, forecast performances should be quantitatively tested against benchmark performances.\n", "\n", - "Currently (`sktime` v0.6x), this is a roadmap development item. Contributions are very welcome." + "Currently (`sktime` v0.9x), this is a roadmap development item. Contributions are very welcome." ] }, { @@ -2024,16 +2019,9 @@ "source": [ "### 2.1 exponential smoothing, theta forecaster, autoETS from `statsmodels`\n", "\n", - "`sktime` interfaces a number of statistical forecasting algorithms from `statsmodels`: exponential smoothing, theta, and aut-ETS." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For example, to use exponential smoothing with an additive trend component and multiplicative seasonality on the airline data set, we can write the following.\n", + "`sktime` interfaces a number of statistical forecasting algorithms from `statsmodels`: exponential smoothing, theta, and auto-ETS.\n", "\n", - "Note that since this is monthly data, a good choic for seasonal periodicity (sp) is 12 (= hypothesized periodicity of a year)." + "For example, to use exponential smoothing with an additive trend component and multiplicative seasonality on the airline data set, we can write the following. Note that since this is monthly data, a good choic for seasonal periodicity (sp) is 12 (= hypothesized periodicity of a year)." ] }, { @@ -2252,9 +2240,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The current interface does not support period indices, only pd.DatetimeIndex.\n", - "\n", - "Consider improving this by contributing the `sktime`." + "The current interface does not support period indices, only pd.DatetimeIndex. Consider improving this by contributing the `sktime`." ] }, { @@ -2298,7 +2284,7 @@ "source": [ "### 2.5 State Space Model (Structural Time Series)\n", "\n", - "We can also use the [`UobservedComponents`](https://www.statsmodels.org/stable/generated/statsmodels.tsa.statespace.structural.UnobservedComponents.html) class from [`statsmodels`](https://www.statsmodels.org/stable/index.html) to generate predictions using a state space model." + "We can also use the [`UnobservedComponents`](https://www.statsmodels.org/stable/generated/statsmodels.tsa.statespace.structural.UnobservedComponents.html) class from [`statsmodels`](https://www.statsmodels.org/stable/index.html) to generate predictions using a state space model." ] }, { @@ -2694,7 +2680,7 @@ "param_grid = {\"window_length\": [7, 12, 15]}\n", "\n", "# We fit the forecaster on an initial window which is 80% of the historical data\n", - "# then use temporal sliding window cross-validation to find the optimal hyper=parameters\n", + "# then use temporal sliding window cross-validation to find the optimal hyper-parameters\n", "cv = SlidingWindowSplitter(initial_window=int(len(y_train) * 0.8), window_length=20)\n", "gscv = ForecastingGridSearchCV(\n", " forecaster, strategy=\"refit\", cv=cv, param_grid=param_grid\n", @@ -3358,32 +3344,19 @@ "* For a good introduction to forecasting, see [Hyndman, Rob J., and George Athanasopoulos. Forecasting: principles and practice. OTexts, 2018](https://otexts.com/fpp2/).\n", "* For comparative benchmarking studies/forecasting competitions, see the [M4 competition](https://www.sciencedirect.com/science/article/pii/S0169207019301128) and the [M5 competition](https://www.kaggle.com/c/m5-forecasting-accuracy/overview)." ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { "celltoolbar": "Raw Cell Format", "hide_input": false, "interpreter": { - "hash": "fcc5fed35031463a248402718f3bbb1a61c709e60741a9777b2268658fc045fd" + "hash": "bc250fec99d1b72e5bb23d9fb06e1f1ac90e860438a1535c061277d2caf5ebfc" }, "kernelspec": { "display_name": "Python 3.8.12 64-bit", "name": "python3" }, "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", "name": "python", "version": "" }, diff --git a/examples/partition_based_clustering.ipynb b/examples/partition_based_clustering.ipynb index a56ba56548e..bb90fe07a8f 100644 --- a/examples/partition_based_clustering.ipynb +++ b/examples/partition_based_clustering.ipynb @@ -29,7 +29,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 6, "outputs": [], "source": [ "from sklearn.model_selection import train_test_split\n", @@ -57,7 +57,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 7, "outputs": [ { "name": "stdout", @@ -199,11 +199,11 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 8, "outputs": [ { "data": { - "text/plain": "
" + "text/plain": "
" }, "metadata": {}, "output_type": "display_data" @@ -211,7 +211,7 @@ { "data": { "text/plain": "
", - "image/png": "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L7yAn58fLi4ujBkzhujoaNP2hp5za4wfP56UlBSee+45hBCoeIC1bNmyhbCwMFxdXbnzzjtJT083bTtw4ACTJ0+me/fueHh4EBUVxaFDh0zbg4KCAJg5cyZCCNPvhjh58iTjxo3D0dGRIUOGsHPnTovtx48f56677sLV1ZUePXrwyCOPkN2I/TYvL4/58+fj5eWFs7Mzd911F6dP18Y3XLVqFZ6eno1eY2VlJc888wyenp5069aNl156iQULFjSoAYqOjubRRx+loKDAdD+XL1/erPLUpan7t3r1aoKCgvDw8OChhx7i8uXLpm1NvfPWKC8v56WXXsLf3x8HBwf69+/PP//5T6t5jc+qOe+//75FGaOjo4mMjMTFxQVPT09uvvlmUlJSWLVqFa+99hrx8fGme7Rq1Srg2t+RrogWnDQmcnNz2bx5M0899RQuLi71tl+PCeqpp56ivLycXbt2cezYMd555x1cXV3x9/dn7dq1ACQmJpKens5f/vIXAN566y0+++wz/v73v/PLL7/w3HPP8fDDD9dr1F9++WXefvttEhISGDp0aL1zFxUVERUVRVpaGhs2bCA+Pp7f/va3VFer4La7d+9m/vz5PPvss5w4cYKPPvqIVatW8eabb1oc57XXXuOBBx7g6NGjTJ06lXnz5pGbm9sq1zBv3jz69OnDgQMHiIuL4+WXX25Vk9GNiqurK66urqxfv57y8obj3c2ePZusrCw2bdpEXFwcERER3H777eTm1i7EfubMGdauXcu6desaNGMsXryYmJgYvvzyS44ePcrs2bO58847TZ1wQ8+5NdatW0efPn14/fXXSU9PtxAaSkpK+OMf/8jq1avZtWsXqampvPDCC6btly9fZsGCBfz888/s27ePkJAQpk6daurADxw4AMDKlStJT083/W6IF198keeff57Dhw8zduxYpk2bZtLY5efnM3HiREaMGMHBgwfZvHkzmZmZPPDAAw0eb+HChRw8eJANGzYQExODlJKpU6dy5cqVZl/jO++8w+eff87KlSvZs2cPhYWFrF+/vsFzjhs3jvfffx93d3fT/TQerznlMaex+3f27FnWr1/PDz/8wA8//MDOnTt5++3axSaa+86bM3/+fP71r3/x17/+lYSEBD766KNrDmVTWVnJjBkziIqK4ujRo8TExPDEE08ghODBBx/k+eefZ/Dg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\n" + "image/png": "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\n" }, "metadata": { "needs_background": "light" @@ -226,6 +226,7 @@ " max_iter=200, # Maximum number of iterations for refinement on training set\n", " metric=\"dtw\", # Distance metric to use\n", " averaging_method=\"mean\", # Averaging technique to use\n", + " random_state=1,\n", ")\n", "\n", "k_means.fit(X_train)\n", @@ -252,7 +253,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 9, "outputs": [ { "data": { @@ -264,7 +265,7 @@ { "data": { "text/plain": "
", - "image/png": "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\n" + "image/png": "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T0969erFiRPZPg8XLVpEpUqVCixjRkYG48ePp1KlSvj5+fHKK68wfPjwfDVAoaGhPPXUU1y+fNlWn9OnTy9UfnJzo/oLCQkhKCiIihUr8vjjj5OcnGwLu9H77oi0tDReeeUVateujbu7Ow0aNODzzz93GNfaVnPy3nvv2eUxNDSUtm3b4uXlRaVKlejYsSMxMTEsWrSIGTNmcPDgQVsdLVq0CLj5d6Q8YwQnQ6G4ePEi69evZ8yYMXh5eeUJ/yNTUGPGjCEtLY0tW7Zw6NAh5syZg7e3N7Vr12b58uUAHDt2jLNnz/L+++8DMHv2bJYsWcInn3zC4cOHmThxIk888USejv3VV1/lzTffJDIykhYtWuS5d0pKCp06dSI2NpbVq1dz8OBBXn75ZSwW7dx269atDBs2jOeff54jR44wf/58Fi1axKxZs+zSmTFjBo899hgRERH07t2boUOHcvHixWIpw9ChQ6lVqxZ79+4lPDycV199tVinjcoi3t7eeHt7s2rVKtLS8veBN3DgQM6fP8+6desIDw8nODiYbt26cfFi9ubsJ0+eZPny5axYsSLfaYyxY8eyc+dOli1bRkREBAMHDuShhx6yfYTza+OOWLFiBbVq1eKNN97g7NmzdkLD1atX+de//kVISAhbtmzh9OnTvPjii7bw5ORkhg8fzrZt29i1axcNGzakd+/etg/43r17AVi4cCFnz561/c6Pl156iUmTJrF//37at2/PI488YtPYXbp0ia5du9KqVSvCwsJYv349586d47HHHss3vREjRhAWFsbq1avZuXMnIkLv3r25fv16ocs4Z84cvvzySxYuXMj27dtJSkpi1apV+d6zQ4cOvPfee/j6+trq05peYfKTk4Lq79SpU6xatYo1a9awZs0afvnlF958M3tDicK+7zkZNmwY//3vf/nggw+IjIxk/vz5+babG5GRkUG/fv3o1KkTERER7Ny5k2effRalFIMGDWLSpEk0a9bMVkeDBg0Cbt07Uq4QEXPc5iMsLCw4LCxMrly5IjbCw0Xg9h/h4VIYdu/eLYCsWLHihnEBWblypYiIbN68WQBJTEy0he/fv18AiYqKEhGR5s2by/Tp0x2m5ej61NRU8fT0lB07dtjFfeaZZ2Tw4MF2161atarAvM6fP198fHwkISHBYXi3bt3kn//8p925kJAQCQgIsCvv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\n" }, "metadata": { "needs_background": "light" @@ -279,6 +280,7 @@ " max_iter=200, # Maximum number of iterations for refinement on training set\n", " verbose=False, # Verbose\n", " metric=\"dtw\", # Distance metric to use\n", + " random_state=1,\n", ")\n", "\n", "k_medoids.fit(X_train)\n", @@ -313,7 +315,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 10, "outputs": [ { "data": { @@ -325,7 +327,7 @@ { "data": { "text/plain": "
", - "image/png": "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\n" + "image/png": "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T0969erFiRPZPg8XLVpEpUqVCixjRkYG48ePp1KlSvj5+fHKK68wfPjwfDVAoaGhPPXUU1y+fNlWn9OnTy9UfnJzo/oLCQkhKCiIihUr8vjjj5OcnGwLu9H77oi0tDReeeUVateujbu7Ow0aNODzzz93GNfaVnPy3nvv2eUxNDSUtm3b4uXlRaVKlejYsSMxMTEsWrSIGTNmcPDgQVsdLVq0CLj5d6Q8YwQnQ6G4ePEi69evZ8yYMXh5eeUJ/yNTUGPGjCEtLY0tW7Zw6NAh5syZg7e3N7Vr12b58uUAHDt2jLNnz/L+++8DMHv2bJYsWcInn3zC4cOHmThxIk888USejv3VV1/lzTffJDIykhYtWuS5d0pKCp06dSI2NpbVq1dz8OBBXn75ZSwW7dx269atDBs2jOeff54jR44wf/58Fi1axKxZs+zSmTFjBo899hgRERH07t2boUOHcvHixWIpw9ChQ6lVqxZ79+4lPDycV199tVinjcoi3t7eeHt7s2rVKtLS8veBN3DgQM6fP8+6desIDw8nODiYbt26cfFi9ubsJ0+eZPny5axYsSLfaYyxY8eyc+dOli1bRkREBAMHDuShhx6yfYTza+OOWLFiBbVq1eKNN97g7NmzdkLD1atX+de//kVISAhbtmzh9OnTvPjii7bw5ORkhg8fzrZt29i1axcNGzakd+/etg/43r17AVi4cCFnz561/c6Pl156iUmTJrF//37at2/PI488YtPYXbp0ia5du9KqVSvCwsJYv349586d47HHHss3vREjRhAWFsbq1avZuXMnIkLv3r25fv16ocs4Z84cvvzySxYuXMj27dtJSkpi1apV+d6zQ4cOvPfee/j6+trq05peYfKTk4Lq79SpU6xatYo1a9awZs0afvnlF958M3tDicK+7zkZNmwY//3vf/nggw+IjIxk/vz5+babG5GRkUG/fv3o1KkTERER7Ny5k2effRalFIMGDWLSpEk0a9bMVkeDBg0Cbt07Uq4QEXPc5iMsLCw4LCxMrly5IjbCw0Xg9h/h4VIYdu/eLYCsWLHihnEBWblypYiIbN68WQBJTEy0he/fv18AiYqKEhGR5s2by/Tp0x2m5ej61NRU8fT0lB07dtjFfeaZZ2Tw4MF2161atarAvM6fP198fHwkISHBYXi3bt3kn//8p925kJAQCQgIsCvv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\n" }, "metadata": { "needs_background": "light" @@ -339,6 +341,7 @@ " init_algorithm=\"forgy\", # Center initialisation technique\n", " max_iter=200, # Maximum number of iterations for refinement on training set\n", " metric=\"dtw\", # Distance metric to use\n", + " random_state=1,\n", ")\n", "\n", "k_medoids.fit(X_train)\n", diff --git a/pyproject.toml b/pyproject.toml index 5055afb7524..837e6609609 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "sktime" -version = "0.10.0" +version = "0.10.1" description = "A unified framework for machine learning with time series" license = "BSD-3-Clause" authors = [ @@ -73,6 +73,7 @@ dev = [ "pre-commit", "pytest", "pytest-cov", + "pytest-xdist", "wheel", ] diff --git a/sktime/__init__.py b/sktime/__init__.py index 20a6741ddf9..0d8a5a0a696 100644 --- a/sktime/__init__.py +++ b/sktime/__init__.py @@ -2,7 +2,7 @@ """sktime.""" -__version__ = "0.10.0" +__version__ = "0.10.1" __all__ = ["show_versions"] diff --git a/sktime/classification/base.py b/sktime/classification/base.py index de04b5db809..59c4dc6b642 100644 --- a/sktime/classification/base.py +++ b/sktime/classification/base.py @@ -26,6 +26,7 @@ class name: BaseClassifier __author__ = ["mloning", "fkiraly", "TonyBagnall", "MatthewMiddlehurst"] import time +from abc import ABC, abstractmethod import numpy as np import pandas as pd @@ -35,13 +36,12 @@ class name: BaseClassifier from sktime.utils.validation import check_n_jobs -class BaseClassifier(BaseEstimator): +class BaseClassifier(BaseEstimator, ABC): """Abstract base class for time series classifiers. The base classifier specifies the methods and method signatures that all classifiers have to implement. Attributes with a underscore suffix are set in the method fit. - #TODO: Make _fit and _predict abstract Parameters ---------- @@ -241,6 +241,7 @@ def _check_convert_X_for_predict(self, X): return X + @abstractmethod def _fit(self, X, y): """Fit time series classifier to training data. @@ -267,10 +268,9 @@ def _fit(self, X, y): Changes state by creating a fitted model that updates attributes ending in "_" and sets is_fitted flag to True. """ - raise NotImplementedError( - "_fit is a protected abstract method, it must be implemented." - ) + ... + @abstractmethod def _predict(self, X) -> np.ndarray: """Predicts labels for sequences in X. @@ -291,9 +291,7 @@ def _predict(self, X) -> np.ndarray: y : 1D np.array of int, of shape [n_instances] - predicted class labels indices correspond to instance indices in X """ - raise NotImplementedError( - "_predict is a protected abstract method, it must be implemented." - ) + ... def _predict_proba(self, X) -> np.ndarray: """Predicts labels probabilities for sequences in X. diff --git a/sktime/classification/compose/_column_ensemble.py b/sktime/classification/compose/_column_ensemble.py index 5e3e31875d0..9ee94ce79a5 100644 --- a/sktime/classification/compose/_column_ensemble.py +++ b/sktime/classification/compose/_column_ensemble.py @@ -226,8 +226,8 @@ class ColumnEnsembleClassifier(BaseColumnEnsembleClassifier): >>> from sktime.datasets import load_basic_motions >>> X_train, y_train = load_basic_motions(split="train") >>> X_test, y_test = load_basic_motions(split="test") - >>> clf = DrCIF(n_estimators=10) - >>> estimators = [("DrCIF", clf, [0, 1, 2, 3, 4, 5])] + >>> clf = DrCIF(n_estimators=3) + >>> estimators = [("DrCIF", clf, [0, 1])] >>> col_ens = ColumnEnsembleClassifier(estimators=estimators) >>> col_ens.fit(X_train, y_train) ColumnEnsembleClassifier(...) diff --git a/sktime/classification/distance_based/_elastic_ensemble.py b/sktime/classification/distance_based/_elastic_ensemble.py index b479d078f2d..c746771069e 100644 --- a/sktime/classification/distance_based/_elastic_ensemble.py +++ b/sktime/classification/distance_based/_elastic_ensemble.py @@ -76,11 +76,13 @@ class ElasticEnsemble(BaseClassifier): -------- >>> from sktime.classification.distance_based import ElasticEnsemble >>> from sktime.datasets import load_unit_test - >>> X_train, y_train = load_unit_test(split="train", return_X_y=True) - >>> X_test, y_test = load_unit_test(split="test", return_X_y=True) + >>> X_train, y_train = load_unit_test(split="train") + >>> X_test, y_test = load_unit_test(split="test") >>> clf = ElasticEnsemble( ... proportion_of_param_options=0.1, ... proportion_train_for_test=0.1, + ... distance_measures = ["dtw","ddtw"], + ... majority_vote=True, ... ) >>> clf.fit(X_train, y_train) ElasticEnsemble(...) diff --git a/sktime/classification/distance_based/tests/test_elastic_ensemble.py b/sktime/classification/distance_based/tests/test_elastic_ensemble.py index 90f149cb68b..5b1a92147ae 100644 --- a/sktime/classification/distance_based/tests/test_elastic_ensemble.py +++ b/sktime/classification/distance_based/tests/test_elastic_ensemble.py @@ -19,8 +19,8 @@ def test_ee_on_unit_test_data(): proportion_of_param_options=0.1, proportion_train_for_test=0.1, random_state=0, - # majority_vote=True, - # distance_measures=["dtw"], + majority_vote=True, + distance_measures=["dtw", "ddtw"], ) ee.fit(X_train, y_train) @@ -31,14 +31,14 @@ def test_ee_on_unit_test_data(): ee_unit_test_probas = np.array( [ - [0.08130, 0.91870], + [0.00000, 1.00000], [1.00000, 0.00000], - [0.08130, 0.91870], + [0.00000, 1.00000], [1.00000, 0.00000], - [0.55285, 0.44715], + [0.50000, 0.50000], [1.00000, 0.00000], - [0.86179, 0.13821], - [0.08130, 0.91870], + [0.50000, 0.50000], + [0.00000, 1.00000], [1.00000, 0.00000], [1.00000, 0.00000], ] diff --git a/sktime/clustering/_base.py b/sktime/clustering/_base.py index 64cf8ae6179..f236c879aef 100644 --- a/sktime/clustering/_base.py +++ b/sktime/clustering/_base.py @@ -19,7 +19,13 @@ class BaseClusterer(BaseEstimator, ABC): - """Abstract base class for time series clusterer.""" + """Abstract base class for time series clusterer. + + Parameters + ---------- + n_clusters: int, defaults = None + Number of clusters for model. + """ _tags = { "X_inner_mtype": "numpy3D", # which type do _fit/_predict accept, usually @@ -31,10 +37,11 @@ class BaseClusterer(BaseEstimator, ABC): "capability:multithreading": False, } - def __init__(self): + def __init__(self, n_clusters: int = None): self.fit_time_ = 0 self._class_dictionary = {} self._threads_to_use = 1 + self.n_clusters = n_clusters super(BaseClusterer, self).__init__() def fit(self, X: TimeSeriesInstances, y=None) -> BaseEstimator: @@ -132,6 +139,7 @@ def predict_proba(self, X): for list of other mtypes, see datatypes.SCITYPE_REGISTER for specifications, see examples/AA_datatypes_and_datasets.ipynb + Returns ------- y : 2D array of shape [n_instances, n_classes] - predicted class probabilities @@ -143,6 +151,28 @@ def predict_proba(self, X): X = self._check_clusterer_input(X) return self._predict_proba(X) + def score(self, X, y=None) -> float: + """Score the quality of the clusterer. + + Parameters + ---------- + X : np.ndarray (2d or 3d array of shape (n_instances, series_length) or shape + (n_instances, n_dimensions, series_length)) or pd.DataFrame (where each + column is a dimension, each cell is a pd.Series (any number of dimensions, + equal or unequal length series)). + Time series instances to train clusterer and then have indexes each belong + to return. + y: ignored, exists for API consistency reasons. + + Returns + ------- + score : float + Score of the clusterer. + """ + self.check_is_fitted() + X = self._check_clusterer_input(X) + return self._score(X, y) + def _predict_proba(self, X): """Predicts labels probabilities for sequences in X. @@ -168,12 +198,18 @@ def _predict_proba(self, X): (i, j)-th entry is predictive probability that i-th instance is of class j """ preds = self._predict(X) - n_clusters = max(preds) + 1 # This isn't always correct but best we can do + n_clusters = self.n_clusters + if n_clusters is None: + n_clusters = max(preds) + 1 dists = np.zeros((X.shape[0], n_clusters)) for i in range(X.shape[0]): dists[i, preds[i]] = 1 return dists + @abstractmethod + def _score(self, X, y=None): + ... + @abstractmethod def _predict(self, X: TimeSeriesInstances, y=None) -> np.ndarray: """Predict the closest cluster each sample in X belongs to. diff --git a/sktime/clustering/_k_means.py b/sktime/clustering/_k_means.py index ec90b06dc53..da8e2c66439 100644 --- a/sktime/clustering/_k_means.py +++ b/sktime/clustering/_k_means.py @@ -44,6 +44,8 @@ class TimeSeriesKMeans(TimeSeriesLloyds): Averaging method to compute the average of a cluster. Any of the following strings are valid: ['mean']. If a Callable is provided must take the form Callable[[np.ndarray], np.ndarray]. + distance_params: dict, defaults = None + Dictonary containing kwargs for the distance metric being used. Attributes ---------- @@ -71,6 +73,7 @@ def __init__( verbose: bool = False, random_state: Union[int, RandomState] = None, averaging_method: Union[str, Callable[[np.ndarray], np.ndarray]] = "mean", + distance_params: dict = None, ): self.averaging_method = averaging_method self._averaging_method = resolve_average_callable(averaging_method) @@ -84,6 +87,7 @@ def __init__( tol, verbose, random_state, + distance_params, ) def _compute_new_cluster_centers( @@ -106,7 +110,9 @@ def _compute_new_cluster_centers( new_centers = np.zeros((self.n_clusters, X.shape[1], X.shape[2])) for i in range(self.n_clusters): curr_indexes = np.where(assignment_indexes == i)[0] - new_centers[i, :] = self._averaging_method(X[curr_indexes]) + result = self._averaging_method(X[curr_indexes]) + if result.shape[0] > 0: + new_centers[i, :] = result return new_centers @classmethod @@ -122,7 +128,7 @@ def get_test_params(cls): `create_test_instance` uses the first (or only) dictionary in `params` """ params = { - "n_clusters": 8, + "n_clusters": 2, "metric": "euclidean", "n_init": 1, "max_iter": 10, diff --git a/sktime/clustering/_k_medoids.py b/sktime/clustering/_k_medoids.py index c5551893344..14ac51e00c6 100644 --- a/sktime/clustering/_k_medoids.py +++ b/sktime/clustering/_k_medoids.py @@ -41,6 +41,8 @@ class TimeSeriesKMedoids(TimeSeriesLloyds): Verbosity mode. random_state: int or np.random.RandomState instance or None, defaults = None Determines random number generation for centroid initialization. + distance_params: dict, defaults = None + Dictonary containing kwargs for the distance metric being used. Attributes ---------- @@ -67,6 +69,7 @@ def __init__( tol: float = 1e-6, verbose: bool = False, random_state: Union[int, RandomState] = None, + distance_params: dict = None, ): self._precomputed_pairwise = None @@ -79,6 +82,7 @@ def __init__( tol, verbose, random_state, + distance_params, ) def _fit(self, X: np.ndarray, y=None) -> np.ndarray: @@ -126,7 +130,9 @@ def _compute_new_cluster_centers( for j in range(len(curr_indexes)): for k in range(len(curr_indexes)): distance_matrix[j, k] = self._precomputed_pairwise[j, k] - new_centers[i, :] = medoids(X[curr_indexes], self._precomputed_pairwise) + result = medoids(X[curr_indexes], self._precomputed_pairwise) + if result.shape[0] > 0: + new_centers[i, :] = result return new_centers @classmethod diff --git a/sktime/clustering/metrics/averaging/_averaging.py b/sktime/clustering/metrics/averaging/_averaging.py index f8e4887b8a2..71b66569455 100644 --- a/sktime/clustering/metrics/averaging/_averaging.py +++ b/sktime/clustering/metrics/averaging/_averaging.py @@ -19,6 +19,8 @@ def mean_average(X: np.ndarray) -> np.ndarray: np.ndarray (2d array of shape (n_dimensions, series_length) The time series that is the mean. """ + if X.shape[0] <= 1: + return X return X.mean(axis=0) diff --git a/sktime/clustering/metrics/medoids.py b/sktime/clustering/metrics/medoids.py index db320b4d167..201a68f91f4 100644 --- a/sktime/clustering/metrics/medoids.py +++ b/sktime/clustering/metrics/medoids.py @@ -29,6 +29,9 @@ def medoids( np.ndarray (2d array of shape (n_dimensions, series_length) The time series that is the medoids. """ + if X.shape[0] < 1: + return X + if precomputed_pairwise_distance is None: precomputed_pairwise_distance = pairwise_distance(X, metric=distance_metric) diff --git a/sktime/clustering/partitioning/_lloyds.py b/sktime/clustering/partitioning/_lloyds.py index 6853b2afdc3..e889df46e3e 100644 --- a/sktime/clustering/partitioning/_lloyds.py +++ b/sktime/clustering/partitioning/_lloyds.py @@ -15,7 +15,7 @@ def _forgy_center_initializer( - X: np.ndarray, n_clusters: int, random_state: np.random.RandomState + X: np.ndarray, n_clusters: int, random_state: np.random.RandomState, **kwargs ) -> np.ndarray: """Compute the initial centers using forgy method. @@ -38,7 +38,7 @@ def _forgy_center_initializer( def _random_center_initializer( - X: np.ndarray, n_clusters: int, random_state: np.random.RandomState + X: np.ndarray, n_clusters: int, random_state: np.random.RandomState, **kwargs ) -> np.ndarray: """Compute initial centroids using random method. @@ -64,7 +64,9 @@ def _random_center_initializer( selected = random_state.choice(n_clusters, X.shape[0], replace=True) for i in range(n_clusters): curr_indexes = np.where(selected == i)[0] - new_centers[i, :] = mean_average(X[curr_indexes]) + result = mean_average(X[curr_indexes]) + if result.shape[0] > 0: + new_centers[i, :] = result return new_centers @@ -75,6 +77,7 @@ def _kmeans_plus_plus( distance_metric: str = "euclidean", n_local_trials: int = None, distance_params: dict = None, + **kwargs, ): """Compute initial centroids using kmeans++ method. @@ -124,10 +127,7 @@ def _kmeans_plus_plus( center_id = random_state.randint(n_samples) centers[0] = X[center_id] closest_dist_sq = ( - pairwise_distance( - centers[0, np.newaxis], X, metric=distance_metric, **distance_params - ) - ** 2 + pairwise_distance(centers[0, np.newaxis], X, metric=distance_metric) ** 2 ) current_pot = closest_dist_sq.sum() @@ -137,10 +137,7 @@ def _kmeans_plus_plus( np.clip(candidate_ids, None, closest_dist_sq.size - 1, out=candidate_ids) distance_to_candidates = ( - pairwise_distance( - X[candidate_ids], X, metric=distance_metric, **distance_params - ) - ** 2 + pairwise_distance(X[candidate_ids], X, metric=distance_metric) ** 2 ) np.minimum(closest_dist_sq, distance_to_candidates, out=distance_to_candidates) @@ -226,7 +223,6 @@ def __init__( random_state: Union[int, RandomState] = None, distance_params: dict = None, ): - self.n_clusters = n_clusters self.init_algorithm = init_algorithm self.metric = metric self.n_init = n_init @@ -242,8 +238,13 @@ def __init__( self.n_iter_ = 0 self._random_state = None + self._init_algorithm = None + + self._distance_params = distance_params + if distance_params is None: + self._distance_params = {} - super(TimeSeriesLloyds, self).__init__() + super(TimeSeriesLloyds, self).__init__(n_clusters=n_clusters) def _check_params(self, X: np.ndarray) -> None: """Check parameters are valid and initialized. @@ -261,7 +262,9 @@ def _check_params(self, X: np.ndarray) -> None: """ self._random_state = check_random_state(self.random_state) - self._distance_metric = distance_factory(X[0], X[1], metric=self.metric) + self._distance_metric = distance_factory( + X[0], X[1], metric=self.metric, **self._distance_params + ) if isinstance(self.init_algorithm, str): self._init_algorithm = self._init_algorithms.get(self.init_algorithm) @@ -280,7 +283,7 @@ def _check_params(self, X: np.ndarray) -> None: else: self._distance_params = self.distance_params - def _fit(self, X: np.ndarray, y=None) -> np.ndarray: + def _fit(self, X: np.ndarray, y=None): """Fit time series clusterer to training data. Parameters @@ -313,6 +316,7 @@ def _fit(self, X: np.ndarray, y=None) -> np.ndarray: self.inertia_ = best_inertia self.cluster_centers_ = best_centers self.n_iter_ = best_iters + return self def _predict(self, X: np.ndarray, y=None) -> np.ndarray: """Predict the closest cluster each sample in X belongs to. @@ -357,7 +361,12 @@ def _fit_one_init(self, X) -> Tuple[np.ndarray, np.ndarray, float, int]: Sum of squared distances of samples to their closest cluster center, weighted by the sample weights if provided. """ - cluster_centers = self._init_algorithm(X, self.n_clusters, self._random_state) + cluster_centers = self._init_algorithm( + X, + self.n_clusters, + self._random_state, + distance_metric=self._distance_metric, + ) old_inertia = np.inf old_labels = None @@ -380,7 +389,7 @@ def _fit_one_init(self, X) -> Tuple[np.ndarray, np.ndarray, float, int]: elif old_labels is not None: # No strict convergence, check for tol based convergence. center_shift = pairwise_distance( - labels, old_labels, metric=self.metric, **self._distance_params + labels, old_labels, metric=self._distance_metric ).sum() if center_shift <= self.tol: if self.verbose: @@ -431,6 +440,9 @@ def _assign_clusters( ) return pairwise.argmin(axis=1), pairwise.min(axis=1).sum() + def _score(self, X, y=None): + return -self.inertia_ + @abstractmethod def _compute_new_cluster_centers( self, X: np.ndarray, assignment_indexes: np.ndarray diff --git a/sktime/clustering/tests/test_k_means.py b/sktime/clustering/tests/test_k_means.py index dda67b97030..467a568c3c6 100644 --- a/sktime/clustering/tests/test_k_means.py +++ b/sktime/clustering/tests/test_k_means.py @@ -114,7 +114,7 @@ def test_kmeans(): n_init=2, n_clusters=4, init_algorithm="kmeans++", - metric="dtw", + metric="euclidean", ) train_predict = kmeans.fit_predict(X_train) train_mean_score = metrics.rand_score(y_train, train_predict) diff --git a/sktime/clustering/tests/test_k_medoids.py b/sktime/clustering/tests/test_k_medoids.py index 5bbe42b684a..dd8f8f3db9d 100644 --- a/sktime/clustering/tests/test_k_medoids.py +++ b/sktime/clustering/tests/test_k_medoids.py @@ -55,7 +55,7 @@ train_expected_score = {"medoids": 0.4858974358974359} -expected_inertia = {"medoids": 291267.56256896566} +expected_inertia = {"medoids": 2387.3342740600688} expected_iters = {"medoids": 5} @@ -111,7 +111,11 @@ def test_kmedoids(): X_test, y_test = load_basic_motions(split="test") kmedoids = TimeSeriesKMedoids( - random_state=1, n_init=2, max_iter=5, init_algorithm="kmeans++", metric="dtw" + random_state=1, + n_init=2, + max_iter=5, + init_algorithm="kmeans++", + metric="euclidean", ) train_predict = kmedoids.fit_predict(X_train) train_score = metrics.rand_score(y_train, train_predict) @@ -126,7 +130,7 @@ def test_kmedoids(): assert kmedoids.n_iter_ == expected_iters["medoids"] assert np.array_equal(kmedoids.labels_, expected_labels["medoids"]) assert isinstance(kmedoids.cluster_centers_, np.ndarray) - assert proba.shape == (40, 6) + assert proba.shape == (40, 8) for val in proba: assert np.count_nonzero(val == 1.0) == 1 diff --git a/sktime/datasets/__init__.py b/sktime/datasets/__init__.py index 621349b1d0a..83f712ea2bd 100644 --- a/sktime/datasets/__init__.py +++ b/sktime/datasets/__init__.py @@ -33,6 +33,8 @@ "write_ndarray_to_tsfile", "write_results_to_uea_format", "write_tabular_transformation_to_arff", + "load_tsf_to_dataframe", + "load_unit_test_tsf", ] from sktime.datasets._data_io import ( @@ -42,6 +44,7 @@ load_from_tsfile, load_from_tsfile_to_dataframe, load_from_ucr_tsv_to_dataframe, + load_tsf_to_dataframe, make_multi_index_dataframe, write_dataframe_to_tsfile, write_ndarray_to_tsfile, @@ -67,5 +70,6 @@ load_shampoo_sales, load_UCR_UEA_dataset, load_unit_test, + load_unit_test_tsf, load_uschange, ) diff --git a/sktime/datasets/_data_io.py b/sktime/datasets/_data_io.py index 3c222f3142b..b8b3d6ac098 100644 --- a/sktime/datasets/_data_io.py +++ b/sktime/datasets/_data_io.py @@ -27,6 +27,8 @@ import tempfile import textwrap import zipfile +from datetime import datetime +from distutils.util import strtobool from urllib.request import urlretrieve import numpy as np @@ -1676,3 +1678,189 @@ def write_ndarray_to_tsfile( file.write(f"{a}{missing_values}") file.write("\n") # open a new line file.close() + + +def load_tsf_to_dataframe( + full_file_path_and_name, + replace_missing_vals_with="NaN", + value_column_name="series_value", +): + """ + Convert the contents in a .tsf file into a dataframe. + + This code was extracted from + https://github.com/rakshitha123/TSForecasting/blob + /master/utils/data_loader.py. + + Parameters + ---------- + full_file_path_and_name: str + The full path to the .tsf file. + replace_missing_vals_with: str, default="NAN" + A term to indicate the missing values in series in the returning dataframe. + value_column_name: str, default="series_value" + Any name that is preferred to have as the name of the column containing series + values in the returning dataframe. + + Returns + ------- + loaded_data: pd.DataFrame + The converted dataframe containing the time series. + frequency: str + The frequency of the dataset. + forecast_horizon: int + The expected forecast horizon of the dataset. + contain_missing_values: bool + Whether the dataset contains missing values or not. + contain_equal_length: bool + Whether the series have equal lengths or not. + """ + col_names = [] + col_types = [] + all_data = {} + line_count = 0 + frequency = None + forecast_horizon = None + contain_missing_values = None + contain_equal_length = None + found_data_tag = False + found_data_section = False + started_reading_data_section = False + + with open(full_file_path_and_name, "r", encoding="cp1252") as file: + for line in file: + # Strip white space from start/end of line + line = line.strip() + + if line: + if line.startswith("@"): # Read meta-data + if not line.startswith("@data"): + line_content = line.split(" ") + if line.startswith("@attribute"): + if ( + len(line_content) != 3 + ): # Attributes have both name and type + raise Exception("Invalid meta-data specification.") + + col_names.append(line_content[1]) + col_types.append(line_content[2]) + else: + if ( + len(line_content) != 2 + ): # Other meta-data have only values + raise Exception("Invalid meta-data specification.") + + if line.startswith("@frequency"): + frequency = line_content[1] + elif line.startswith("@horizon"): + forecast_horizon = int(line_content[1]) + elif line.startswith("@missing"): + contain_missing_values = bool( + strtobool(line_content[1]) + ) + elif line.startswith("@equallength"): + contain_equal_length = bool(strtobool(line_content[1])) + + else: + if len(col_names) == 0: + raise Exception( + "Missing attribute section. " + "Attribute section must come before data." + ) + + found_data_tag = True + elif not line.startswith("#"): + if len(col_names) == 0: + raise Exception( + "Missing attribute section. " + "Attribute section must come before data." + ) + elif not found_data_tag: + raise Exception("Missing @data tag.") + else: + if not started_reading_data_section: + started_reading_data_section = True + found_data_section = True + all_series = [] + + for col in col_names: + all_data[col] = [] + + full_info = line.split(":") + + if len(full_info) != (len(col_names) + 1): + raise Exception("Missing attributes/values in series.") + + series = full_info[len(full_info) - 1] + series = series.split(",") + + if len(series) == 0: + raise Exception( + "A given series should contains a set " + "of comma separated numeric values." + "At least one numeric value should be there " + "in a series. " + "Missing values should be indicated with ? symbol" + ) + + numeric_series = [] + + for val in series: + if val == "?": + numeric_series.append(replace_missing_vals_with) + else: + numeric_series.append(float(val)) + + if numeric_series.count(replace_missing_vals_with) == len( + numeric_series + ): + raise Exception( + "All series values are missing. " + "A given series should contains a set " + "of comma separated numeric values." + "At least one numeric value should be there " + "in a series." + ) + + all_series.append(pd.Series(numeric_series).array) + + for i in range(len(col_names)): + att_val = None + if col_types[i] == "numeric": + att_val = int(full_info[i]) + elif col_types[i] == "string": + att_val = str(full_info[i]) + elif col_types[i] == "date": + att_val = datetime.strptime( + full_info[i], "%Y-%m-%d %H-%M-%S" + ) + else: + # Currently, the code supports only + # numeric, string and date types. + # Extend this as required. + raise Exception("Invalid attribute type.") + + if att_val is None: + raise Exception("Invalid attribute value.") + else: + all_data[col_names[i]].append(att_val) + + line_count = line_count + 1 + + if line_count == 0: + raise Exception("Empty file.") + if len(col_names) == 0: + raise Exception("Missing attribute section.") + if not found_data_section: + raise Exception("Missing series information under data section.") + + all_data[value_column_name] = all_series + loaded_data = pd.DataFrame(all_data) + + return ( + loaded_data, + frequency, + forecast_horizon, + contain_missing_values, + contain_equal_length, + ) diff --git a/sktime/datasets/_single_problem_loaders.py b/sktime/datasets/_single_problem_loaders.py index 0913eacb8d5..17b1a545c15 100644 --- a/sktime/datasets/_single_problem_loaders.py +++ b/sktime/datasets/_single_problem_loaders.py @@ -34,6 +34,7 @@ "load_gun_point_segmentation", "load_electric_devices_segmentation", "load_macroeconomic", + "load_unit_test_tsf", ] import os @@ -42,7 +43,11 @@ import pandas as pd import statsmodels.api as sm -from sktime.datasets._data_io import _load_dataset, _load_provided_dataset +from sktime.datasets._data_io import ( + _load_dataset, + _load_provided_dataset, + load_tsf_to_dataframe, +) DIRNAME = "data" MODULE = os.path.dirname(__file__) @@ -847,12 +852,12 @@ def load_macroeconomic(): References ---------- - ..[1] Wrapped via statsmodels: + .. [1] Wrapped via statsmodels: https://www.statsmodels.org/dev/datasets/generated/macrodata.html - ..[2] Data Source: FRED, Federal Reserve Economic Data, Federal Reserve + .. [2] Data Source: FRED, Federal Reserve Economic Data, Federal Reserve Bank of St. Louis; http://research.stlouisfed.org/fred2/; accessed December 15, 2009. - ..[3] Data Source: Bureau of Labor Statistics, U.S. Department of Labor; + .. [3] Data Source: Bureau of Labor Statistics, U.S. Department of Labor; http://www.bls.gov/data/; accessed December 15, 2009. """ y = sm.datasets.macrodata.load_pandas().data @@ -863,3 +868,38 @@ def load_macroeconomic(): y = y.drop(columns=["year", "quarter", "time"]) y.name = "US Macroeconomic Data" return y + + +def load_unit_test_tsf(): + """ + Load tsf UnitTest dataset. + + Returns + ------- + loaded_data: pd.DataFrame + The converted dataframe containing the time series. + frequency: str + The frequency of the dataset. + forecast_horizon: int + The expected forecast horizon of the dataset. + contain_missing_values: bool + Whether the dataset contains missing values or not. + contain_equal_length: bool + Whether the series have equal lengths or not. + """ + path = os.path.join(MODULE, DIRNAME, "UnitTest", "UnitTest_Tsf_Loader.tsf") + ( + loaded_data, + frequency, + forecast_horizon, + contain_missing_values, + contain_equal_length, + ) = load_tsf_to_dataframe(path) + + return ( + loaded_data, + frequency, + forecast_horizon, + contain_missing_values, + contain_equal_length, + ) diff --git a/sktime/datasets/tests/test_data_io.py b/sktime/datasets/tests/test_data_io.py index 8a0b47f8851..7fd22e8549d 100644 --- a/sktime/datasets/tests/test_data_io.py +++ b/sktime/datasets/tests/test_data_io.py @@ -24,6 +24,7 @@ load_from_long_to_dataframe, load_from_tsfile, load_from_tsfile_to_dataframe, + load_tsf_to_dataframe, load_uschange, write_dataframe_to_tsfile, ) @@ -1080,3 +1081,45 @@ def test_write_dataframe_to_ts_fail(tmp_path): path=str(tmp_path), problem_name="GunPoint", ) + + +def test_load_tsf_to_dataframe(): + """Test function for loading tsf format.""" + data_path = os.path.join( + os.path.dirname(sktime.__file__), + "datasets/data/UnitTest/UnitTest_Tsf_Loader.tsf", + ) + + df, frequency, horizon, missing_values, equal_length = load_tsf_to_dataframe( + data_path + ) + + test_df = pd.DataFrame( + { + "series_name": ["T1", "T2", "T3"], + "start_timestamp": [ + pd.Timestamp(year=1979, month=1, day=1), + pd.Timestamp(year=1979, month=1, day=1), + pd.Timestamp(year=1973, month=1, day=1), + ], + "series_value": [ + [ + 25092.2284, + 24271.5134, + 25828.9883, + 27697.5047, + 27956.2276, + 29924.4321, + 30216.8321, + ], + [887896.51, 887068.98, 971549.04], + [227921, 230995, 183635, 238605, 254186], + ], + } + ) + + assert_frame_equal(df, test_df) + assert frequency == "yearly" + assert horizon == 4 + assert missing_values is False + assert equal_length is False diff --git a/sktime/datatypes/_alignment/_check.py b/sktime/datatypes/_alignment/_check.py index f87cac27ca3..c1b52431488 100644 --- a/sktime/datatypes/_alignment/_check.py +++ b/sktime/datatypes/_alignment/_check.py @@ -104,7 +104,7 @@ def check_align(align_df, name="align_df", index="iloc"): return True, "" -def check_alignment_Alignment(obj, return_metadata=False, var_name="obj"): +def check_alignment_alignment(obj, return_metadata=False, var_name="obj"): """Check whether object has mtype `alignment` for scitype `Alignment`.""" valid, msg = check_align(obj, name=var_name, index="iloc") @@ -114,10 +114,10 @@ def check_alignment_Alignment(obj, return_metadata=False, var_name="obj"): return valid -check_dict[("alignment", "Alignment")] = check_alignment_Alignment +check_dict[("alignment", "Alignment")] = check_alignment_alignment -def check_alignment_loc_Alignment(obj, return_metadata=False, var_name="obj"): +def check_alignment_loc_alignment(obj, return_metadata=False, var_name="obj"): """Check whether object has mtype `alignment_loc` for scitype `Alignment`.""" valid, msg = check_align(obj, name=var_name, index="loc") @@ -127,4 +127,4 @@ def check_alignment_loc_Alignment(obj, return_metadata=False, var_name="obj"): return valid -check_dict[("alignment_loc", "Alignment")] = check_alignment_loc_Alignment +check_dict[("alignment_loc", "Alignment")] = check_alignment_loc_alignment diff --git a/sktime/datatypes/_convert.py b/sktime/datatypes/_convert.py index ad11c146238..01db283b924 100644 --- a/sktime/datatypes/_convert.py +++ b/sktime/datatypes/_convert.py @@ -185,6 +185,7 @@ def convert_to( to_type : str - the type to convert "obj" to, a valid mtype string or list - admissible types for conversion to as_scitype : str, optional - name of scitype the object "obj" is considered as + pre-specifying the scitype reduces the number of checks done in type inference default = inferred from mtype of obj, which is in turn inferred internally store : reference of storage for lossy conversions, default=None (no store) is updated by side effect if not None and store_behaviour="reset" or "update" @@ -196,44 +197,61 @@ def convert_to( Returns ------- - converted_obj : to_type - object obj converted to to_type, if to_type is str - if to_type is list, converted to to_type[0], - unless from_type in to_type, in this case converted_obj=obj - if obj was None, returns None + converted_obj : to_type - object obj, or obj converted to target mtype as follows: + case 1: mtype of obj is equal to to_type, or a list element of to_type + no conversion happens, converted_obj = obj + case 2: to_type is a str, and not equal to mtype of obj + converted_obj is obj converted to to_type + case 3: to_type is list of str, and mtype of obj is not in that list + converted_obj is converted to the first mtype in to_type + that is of same scitype as obj + case 4: if obj was None, converted_obj is also None Raises ------ TypeError if machine type of input "obj" is not recognized - KeyError if conversion is not implemented + TypeError if to_type contains no mtype compatible with mtype of obj + KeyError if conversion that would be conducted is not implemented TypeError or ValueError if inputs do not match specification """ if obj is None: return None - if isinstance(to_type, list): - if not np.all(isinstance(x, str) for x in to_type): - raise TypeError("to_type must be a str or list of str") - elif not isinstance(to_type, str): - raise TypeError("to_type must be a str or list of str") + # input checks on to_type, as_scitype; coerce to_type, as_scitype to lists + to_type = _check_str_or_list_of_str(to_type, obj_name="to_type") - if as_scitype is None: - if isinstance(to_type, str): - as_scitype = mtype_to_scitype(to_type) - else: - as_scitype = mtype_to_scitype(to_type[0]) - elif not isinstance(as_scitype, str): - raise TypeError("as_scitype must be a str or None") + # sub-set a preliminary set of as_scitype from to_type, as_scitype + if as_scitype is not None: + # if not None, subset to types compatible between to_type and as_scitype + as_scitype = _check_str_or_list_of_str(as_scitype, obj_name="as_scitype") + potential_scitypes = mtype_to_scitype(to_type) + as_scitype = list(set(potential_scitypes).intersection(as_scitype)) + else: + # if None, infer from to_type + as_scitype = mtype_to_scitype(to_type) + # now further narrow down as_scitype by inference from the obj from_type = infer_mtype(obj=obj, as_scitype=as_scitype) + as_scitype = mtype_to_scitype(from_type) - # if to_type is a list: + # if to_type is a list, we do the following: + # if on the list, then don't do a conversion (convert to from_type) + # if not on the list, we find and convert to first mtype that has same scitype if isinstance(to_type, list): # no conversion of from_type is in the list if from_type in to_type: to_type = from_type - # otherwise convert to first element + # otherwise convert to first element of same scitype else: - to_type = to_type[0] + same_scitype_mtypes = [ + mtype for mtype in to_type if mtype_to_scitype(mtype) == as_scitype + ] + if len(same_scitype_mtypes) == 0: + raise TypeError( + "to_type contains no mtype compatible with the scitype of obj," + f"which is {as_scitype}" + ) + to_type = same_scitype_mtypes[0] converted_obj = convert( obj=obj, @@ -275,3 +293,16 @@ def _conversions_defined(scitype: str): conv_df = pd.DataFrame(mat, index=cols, columns=cols) return conv_df + + +def _check_str_or_list_of_str(obj, obj_name="obj"): + """Check whether obj is str or list of str; coerces to list of str.""" + if isinstance(obj, list): + if not np.all(isinstance(x, str) for x in obj): + raise TypeError(f"{obj} must be a str or list of str") + else: + return obj + elif not isinstance(obj, str): + raise TypeError(f"{obj} must be a str or list of str") + else: + return [obj] diff --git a/sktime/datatypes/_hierarchical/_check.py b/sktime/datatypes/_hierarchical/_check.py index 2be9b1e7944..3ff8333b1c0 100644 --- a/sktime/datatypes/_hierarchical/_check.py +++ b/sktime/datatypes/_hierarchical/_check.py @@ -45,7 +45,7 @@ import numpy as np import pandas as pd -from sktime.datatypes._series._check import check_pdDataFrame_Series +from sktime.datatypes._series._check import check_pddataframe_series VALID_INDEX_TYPES = (pd.Int64Index, pd.RangeIndex, pd.PeriodIndex, pd.DatetimeIndex) VALID_MULTIINDEX_TYPES = (pd.Int64Index, pd.RangeIndex) @@ -97,7 +97,7 @@ def check_pdmultiindex_hierarchical(obj, return_metadata=False, var_name="obj"): panel_inds = inst_inds.droplevel(-1).unique() check_res = [ - check_pdDataFrame_Series(obj.loc[i], return_metadata=True) for i in inst_inds + check_pddataframe_series(obj.loc[i], return_metadata=True) for i in inst_inds ] bad_inds = [i[1] for i in enumerate(inst_inds) if not check_res[i[0]][0]] diff --git a/sktime/datatypes/_panel/_check.py b/sktime/datatypes/_panel/_check.py index d65ab4c2275..c1575adae95 100644 --- a/sktime/datatypes/_panel/_check.py +++ b/sktime/datatypes/_panel/_check.py @@ -43,7 +43,7 @@ import numpy as np import pandas as pd -from sktime.datatypes._series._check import check_pdDataFrame_Series +from sktime.datatypes._series._check import check_pddataframe_series VALID_INDEX_TYPES = (pd.Int64Index, pd.RangeIndex, pd.PeriodIndex, pd.DatetimeIndex) VALID_MULTIINDEX_TYPES = (pd.Int64Index, pd.RangeIndex) @@ -69,7 +69,7 @@ def _list_all_equal(obj): check_dict = dict() -def check_dflist_Panel(obj, return_metadata=False, var_name="obj"): +def check_dflist_panel(obj, return_metadata=False, var_name="obj"): def ret(valid, msg, metadata, return_metadata): if return_metadata: return valid, msg, metadata @@ -88,7 +88,7 @@ def ret(valid, msg, metadata, return_metadata): msg = f"{var_name}[i] must pd.DataFrame, but found other types at i={bad_inds}" return ret(False, msg, None, return_metadata) - check_res = [check_pdDataFrame_Series(s, return_metadata=True) for s in obj] + check_res = [check_pddataframe_series(s, return_metadata=True) for s in obj] bad_inds = [i for i in range(n) if not check_res[i][0]] if len(bad_inds) > 0: @@ -109,10 +109,10 @@ def ret(valid, msg, metadata, return_metadata): return ret(True, None, metadata, return_metadata) -check_dict[("df-list", "Panel")] = check_dflist_Panel +check_dict[("df-list", "Panel")] = check_dflist_panel -def check_numpy3D_Panel(obj, return_metadata=False, var_name="obj"): +def check_numpy3d_panel(obj, return_metadata=False, var_name="obj"): def ret(valid, msg, metadata, return_metadata): if return_metadata: return valid, msg, metadata @@ -145,10 +145,10 @@ def ret(valid, msg, metadata, return_metadata): return ret(True, None, metadata, return_metadata) -check_dict[("numpy3D", "Panel")] = check_numpy3D_Panel +check_dict[("numpy3D", "Panel")] = check_numpy3d_panel -def check_pdmultiindex_Panel(obj, return_metadata=False, var_name="obj"): +def check_pdmultiindex_panel(obj, return_metadata=False, var_name="obj"): def ret(valid, msg, metadata, return_metadata): if return_metadata: return valid, msg, metadata @@ -186,9 +186,9 @@ def ret(valid, msg, metadata, return_metadata): inst_inds = np.unique(obj.index.get_level_values(0)) check_res = [ - check_pdDataFrame_Series(obj.loc[i], return_metadata=True) for i in inst_inds + check_pddataframe_series(obj.loc[i], return_metadata=True) for i in inst_inds ] - bad_inds = [i for i in inst_inds if not check_res[i][0]] + bad_inds = [i for i in range(len(inst_inds)) if not check_res[i][0]] if len(bad_inds) > 0: msg = ( @@ -211,7 +211,7 @@ def ret(valid, msg, metadata, return_metadata): return ret(True, None, metadata, return_metadata) -check_dict[("pd-multiindex", "Panel")] = check_pdmultiindex_Panel +check_dict[("pd-multiindex", "Panel")] = check_pdmultiindex_panel def _cell_is_series_or_array(cell): diff --git a/sktime/datatypes/_panel/_convert.py b/sktime/datatypes/_panel/_convert.py index e3ff3ee6979..61827763e1a 100644 --- a/sktime/datatypes/_panel/_convert.py +++ b/sktime/datatypes/_panel/_convert.py @@ -827,20 +827,12 @@ def from_nested_to_multi_index(X, instance_index=None, time_index=None): instances = [] for instance_idx in instance_idxs: iidx = instance_idx - instance = [ - pd.DataFrame(i[1], columns=[i[0]]) - for i in X.loc[iidx, :].iteritems() # noqa - ] - # instance = [ - # _val if isinstance(_val, (pd.Series) else pd.Series(_val, name=_lab) - # for _lab, _val in X.loc[instance_idx, :].iteritems() # noqa - # ] - # instance = [ - # X.loc[instance_idx, _label] - # if isinstance(X.loc[instance_idx, _label], pd.Series) - # else pd.Series(X.loc[instance_idx, _label], name=_label) - # for _label in X.columns ] + series = [i[1] for i in X.loc[iidx, :].iteritems()] + colnames = [i[0] for i in X.loc[iidx, :].iteritems()] + for x in series: + x.name = None + instance = [pd.DataFrame(s, columns=[c]) for s, c in zip(series, colnames)] instance = pd.concat(instance, axis=1) # For primitive (non-nested column) assume the same # primitive value applies to every timepoint of the instance diff --git a/sktime/datatypes/_registry.py b/sktime/datatypes/_registry.py index 30a30448060..ef561fdd6b0 100644 --- a/sktime/datatypes/_registry.py +++ b/sktime/datatypes/_registry.py @@ -72,7 +72,7 @@ ] -def mtype_to_scitype(mtype: str, return_unique=False): +def mtype_to_scitype(mtype: str, return_unique=False, coerce_to_list=False): """Infer scitype belonging to mtype. Parameters @@ -88,7 +88,9 @@ def mtype_to_scitype(mtype: str, return_unique=False): if nested list/str object, replaces mtype str by scitype str if None, returns None return_unique : bool, default=False - if True, makes + if True, makes return unique + coerce_to_list : bool, default=Fakse + if True, coerces rerturn to list, even if one-element Raises ------ @@ -121,4 +123,7 @@ def mtype_to_scitype(mtype: str, return_unique=False): if len(scitype) < 1: raise ValueError(f"{mtype} is not a supported mtype") - return scitype[0] + if coerce_to_list: + return [scitype[0]] + else: + return scitype[0] diff --git a/sktime/datatypes/_series/_check.py b/sktime/datatypes/_series/_check.py index 48c6de6ffd6..0961fff4c86 100644 --- a/sktime/datatypes/_series/_check.py +++ b/sktime/datatypes/_series/_check.py @@ -49,7 +49,7 @@ check_dict = dict() -def check_pdDataFrame_Series(obj, return_metadata=False, var_name="obj"): +def check_pddataframe_series(obj, return_metadata=False, var_name="obj"): metadata = dict() @@ -103,10 +103,10 @@ def ret(valid, msg, metadata, return_metadata): return ret(True, None, metadata, return_metadata) -check_dict[("pd.DataFrame", "Series")] = check_pdDataFrame_Series +check_dict[("pd.DataFrame", "Series")] = check_pddataframe_series -def check_pdSeries_Series(obj, return_metadata=False, var_name="obj"): +def check_pdseries_series(obj, return_metadata=False, var_name="obj"): metadata = dict() @@ -160,10 +160,10 @@ def ret(valid, msg, metadata, return_metadata): return ret(True, None, metadata, return_metadata) -check_dict[("pd.Series", "Series")] = check_pdSeries_Series +check_dict[("pd.Series", "Series")] = check_pdseries_series -def check_numpy_Series(obj, return_metadata=False, var_name="obj"): +def check_numpy_series(obj, return_metadata=False, var_name="obj"): metadata = dict() @@ -199,7 +199,7 @@ def ret(valid, msg, metadata, return_metadata): return ret(True, None, metadata, return_metadata) -check_dict[("np.ndarray", "Series")] = check_numpy_Series +check_dict[("np.ndarray", "Series")] = check_numpy_series def _index_equally_spaced(index): diff --git a/sktime/datatypes/_table/_check.py b/sktime/datatypes/_table/_check.py index 718b6c1653b..69cbeecc5cb 100644 --- a/sktime/datatypes/_table/_check.py +++ b/sktime/datatypes/_table/_check.py @@ -42,6 +42,9 @@ check_dict = dict() +PRIMITIVE_TYPES = (float, int, str) + + def _ret(valid, msg, metadata, return_metadata): if return_metadata: return valid, msg, metadata @@ -49,7 +52,7 @@ def _ret(valid, msg, metadata, return_metadata): return valid -def check_pdDataFrame_Table(obj, return_metadata=False, var_name="obj"): +def check_pddataframe_table(obj, return_metadata=False, var_name="obj"): metadata = dict() @@ -75,10 +78,39 @@ def check_pdDataFrame_Table(obj, return_metadata=False, var_name="obj"): return _ret(True, None, metadata, return_metadata) -check_dict[("pd_DataFrame_Table", "Table")] = check_pdDataFrame_Table +check_dict[("pd_DataFrame_Table", "Table")] = check_pddataframe_table -def check_numpy1D_Table(obj, return_metadata=False, var_name="obj"): +def check_pdseries_table(obj, return_metadata=False, var_name="obj"): + + metadata = dict() + + if not isinstance(obj, pd.Series): + msg = f"{var_name} must be a pandas.Series, found {type(obj)}" + return _ret(False, msg, None, return_metadata) + + # we now know obj is a pd.Series + index = obj.index + metadata["is_empty"] = len(index) < 1 + metadata["is_univariate"] = True + + # check that dtype is not object + if "object" == obj.dtypes: + msg = f"{var_name} should not be of 'object' dtype" + return _ret(False, msg, None, return_metadata) + + # check whether index is equally spaced or if there are any nans + # compute only if needed + if return_metadata: + metadata["has_nans"] = obj.isna().values.any() + + return _ret(True, None, metadata, return_metadata) + + +check_dict[("pd_Series_Table", "Table")] = check_pdseries_table + + +def check_numpy1d_table(obj, return_metadata=False, var_name="obj"): metadata = dict() @@ -101,10 +133,10 @@ def check_numpy1D_Table(obj, return_metadata=False, var_name="obj"): return _ret(True, None, metadata, return_metadata) -check_dict[("numpy1D", "Table")] = check_numpy1D_Table +check_dict[("numpy1D", "Table")] = check_numpy1d_table -def check_numpy2D_Table(obj, return_metadata=False, var_name="obj"): +def check_numpy2d_table(obj, return_metadata=False, var_name="obj"): metadata = dict() @@ -126,4 +158,49 @@ def check_numpy2D_Table(obj, return_metadata=False, var_name="obj"): return _ret(True, None, metadata, return_metadata) -check_dict[("numpy2D", "Table")] = check_numpy2D_Table +check_dict[("numpy2D", "Table")] = check_numpy2d_table + + +def check_list_of_dict_table(obj, return_metadata=False, var_name="obj"): + + metadata = dict() + + if not isinstance(obj, list): + msg = f"{var_name} must be a list of dict, found {type(obj)}" + return _ret(False, msg, None, return_metadata) + + if not np.all(isinstance(x, dict) for x in obj): + msg = ( + f"{var_name} must be a list of dict, but elements at following " + f"indices are not dict: {np.where(not isinstance(x, dict) for x in obj)}" + ) + return _ret(False, msg, None, return_metadata) + + for i, d in enumerate(obj): + for key in d.keys(): + if not isinstance(d[key], PRIMITIVE_TYPES): + msg = ( + "all entries must be of primitive type (str, int, float), but " + f"found {type(d[key])} at index {i}, key {key}" + ) + + # we now know obj is a list of dict + # check whether there any nans; compute only if requested + if return_metadata: + multivariate_because_one_row = np.any([len(x) > 1 for x in obj]) + if not multivariate_because_one_row: + all_keys = np.unique([key for d in obj for key in d.keys()]) + multivariate_because_keys_different = len(all_keys) > 1 + multivariate = multivariate_because_keys_different + else: + multivariate = multivariate_because_one_row + metadata["is_univariate"] = not multivariate + metadata["has_nans"] = np.any( + [np.isnan(d[key]) for d in obj for key in d.keys()] + ) + metadata["is_empty"] = len(obj) < 1 or np.all([len(x) < 1 for x in obj]) + + return _ret(True, None, metadata, return_metadata) + + +check_dict[("list_of_dict", "Table")] = check_list_of_dict_table diff --git a/sktime/datatypes/_table/_convert.py b/sktime/datatypes/_table/_convert.py index d73e9796e95..15ce3ed570a 100644 --- a/sktime/datatypes/_table/_convert.py +++ b/sktime/datatypes/_table/_convert.py @@ -34,6 +34,8 @@ import numpy as np import pandas as pd +from sktime.datatypes._table._registry import MTYPE_LIST_TABLE + ############################################################## # methods to convert one machine type to another machine type ############################################################## @@ -47,7 +49,7 @@ def convert_identity(obj, store=None): # assign identity function to type conversion to self -for tp in ["numpy1D", "numpy2D", "pd_DataFrame_Table"]: +for tp in MTYPE_LIST_TABLE: convert_dict[(tp, tp, "Table")] = convert_identity @@ -148,3 +150,124 @@ def convert_1Dnp_to_df_as_Table(obj: np.ndarray, store=None) -> pd.DataFrame: convert_dict[("numpy1D", "pd_DataFrame_Table", "Table")] = convert_1Dnp_to_df_as_Table + + +def convert_s_to_df_as_table(obj: pd.Series, store=None) -> pd.DataFrame: + + if not isinstance(obj, pd.Series): + raise TypeError("input must be a pd.Series") + + if ( + isinstance(store, dict) + and "columns" in store.keys() + and len(store["columns"]) == 1 + ): + res = pd.DataFrame(obj, columns=store["columns"]) + else: + res = pd.DataFrame(obj) + + return res + + +convert_dict[ + ("pd_Series_Table", "pd_DataFrame_Table", "Table") +] = convert_s_to_df_as_table + + +def convert_df_to_s_as_table(obj: pd.DataFrame, store=None) -> pd.Series: + + if not isinstance(obj, pd.DataFrame): + raise TypeError("input is not a pd.DataFrame") + + if len(obj.columns) != 1: + raise ValueError("input must be univariate pd.DataFrame, with one column") + + if isinstance(store, dict): + store["columns"] = obj.columns[[0]] + + y = obj[obj.columns[0]] + y.name = None + + return y + + +convert_dict[ + ("pd_DataFrame_Table", "pd_Series_Table", "Table") +] = convert_df_to_s_as_table + + +def convert_list_of_dict_to_df_as_table(obj: list, store=None) -> pd.DataFrame: + + if not isinstance(obj, list): + raise TypeError("input must be a list of dict") + + if not np.all([isinstance(x, dict) for x in obj]): + raise TypeError("input must be a list of dict") + + res = pd.DataFrame(obj) + + if ( + isinstance(store, dict) + and "index" in store.keys() + and len(store["index"]) == len(res) + ): + res.index = store["index"] + + return res + + +convert_dict[ + ("list_of_dict", "pd_DataFrame_Table", "Table") +] = convert_list_of_dict_to_df_as_table + + +def convert_df_to_list_of_dict_as_table(obj: pd.DataFrame, store=None) -> list: + + if not isinstance(obj, pd.DataFrame): + raise TypeError("input is not a pd.DataFrame") + + ret_dict = [obj.loc[i].to_dict() for i in obj.index] + + if isinstance(store, dict): + store["index"] = obj.index + + return ret_dict + + +convert_dict[ + ("pd_DataFrame_Table", "list_of_dict", "Table") +] = convert_df_to_list_of_dict_as_table + + +# obtain other conversions from/to numpyflat via concatenation to DataFrame +def _concat(fun1, fun2): + def concat_fun(obj, store=None): + obj1 = fun1(obj, store=store) + obj2 = fun2(obj1, store=store) + return obj2 + + return concat_fun + + +def _extend_conversions(mtype, anchor_mtype, convert_dict, mtype_list=None): + + keys = convert_dict.keys() + scitype = list(keys)[0][2] + if mtype_list is None: + mtype_list = [key[0] for key in keys] + + for tp in set(MTYPE_LIST_TABLE).difference([mtype, anchor_mtype]): + if (anchor_mtype, tp, scitype) in convert_dict.keys(): + convert_dict[(mtype, tp, scitype)] = _concat( + convert_dict[(mtype, anchor_mtype, scitype)], + convert_dict[(anchor_mtype, tp, scitype)], + ) + if (tp, anchor_mtype, scitype) in convert_dict.keys(): + convert_dict[(tp, mtype, scitype)] = _concat( + convert_dict[(tp, anchor_mtype, scitype)], + convert_dict[(anchor_mtype, mtype, scitype)], + ) + + +_extend_conversions("pd_Series_Table", "pd_DataFrame_Table", convert_dict) +_extend_conversions("list_of_dict", "pd_DataFrame_Table", convert_dict) diff --git a/sktime/datatypes/_table/_examples.py b/sktime/datatypes/_table/_examples.py index bfa78ccfeac..9210e3cf5b5 100644 --- a/sktime/datatypes/_table/_examples.py +++ b/sktime/datatypes/_table/_examples.py @@ -47,6 +47,17 @@ example_dict[("numpy1D", "Table", 0)] = arr example_dict_lossy[("numpy1D", "Table", 0)] = True +series = pd.Series([1, 4, 0.5, -3]) + +example_dict[("pd_Series_Table", "Table", 0)] = series +example_dict_lossy[("pd_Series_Table", "Table", 0)] = True + +list_of_dict = [{"a": 1.0}, {"a": 4.0}, {"a": 0.5}, {"a": -3.0}] + +example_dict[("list_of_dict", "Table", 0)] = list_of_dict +example_dict_lossy[("list_of_dict", "Table", 0)] = False + + example_dict_metadata[("Table", 0)] = { "is_univariate": True, "is_empty": False, @@ -69,6 +80,19 @@ example_dict[("numpy2D", "Table", 1)] = arr example_dict_lossy[("numpy2D", "Table", 1)] = True +example_dict[("pd_Series_Table", "Table", 1)] = None +example_dict_lossy[("pd_Series_Table", "Table", 1)] = None + +list_of_dict = [ + {"a": 1.0, "b": 3.0}, + {"a": 4.0, "b": 7.0}, + {"a": 0.5, "b": 2.0}, + {"a": -3.0, "b": -3 / 7}, +] + +example_dict[("list_of_dict", "Table", 1)] = list_of_dict +example_dict_lossy[("list_of_dict", "Table", 1)] = False + example_dict_metadata[("Table", 1)] = { "is_univariate": False, "is_empty": False, diff --git a/sktime/datatypes/_table/_registry.py b/sktime/datatypes/_table/_registry.py index c029e7f78d3..6cc79534bc6 100644 --- a/sktime/datatypes/_table/_registry.py +++ b/sktime/datatypes/_table/_registry.py @@ -12,6 +12,8 @@ ("pd_DataFrame_Table", "Table", "pd.DataFrame representation of a data table"), ("numpy1D", "Table", "1D np.narray representation of a univariate table"), ("numpy2D", "Table", "2D np.narray representation of a univariate table"), + ("pd_Series_Table", "Table", "pd.Series representation of a data table"), + ("list_of_dict", "Table", "list of dictionaries with primitive entries"), ] MTYPE_LIST_TABLE = pd.DataFrame(MTYPE_REGISTER_TABLE)[0].values diff --git a/sktime/datatypes/tests/test_convert_to.py b/sktime/datatypes/tests/test_convert_to.py new file mode 100644 index 00000000000..eea561168fe --- /dev/null +++ b/sktime/datatypes/tests/test_convert_to.py @@ -0,0 +1,110 @@ +# -*- coding: utf-8 -*- +"""Testing machine type converters for scitypes - covert_to utility.""" + +__author__ = ["fkiraly"] + +from sktime.datatypes._convert import convert_to +from sktime.datatypes._examples import get_examples +from sktime.utils._testing.deep_equals import deep_equals + +# hard-coded scitypes/mtypes to use in test_convert_to +# easy to change in case the strings change +SCITYPES = ["Series", "Panel"] +MTYPES_SERIES = ["pd.Series", "np.ndarray", "pd.DataFrame"] +MTYPES_PANEL = ["pd-multiindex", "df-list", "numpy3D"] + + +def test_convert_to_simple(): + """Testing convert_to basic call works.""" + scitype = SCITYPES[0] + + from_fixt = get_examples(mtype=MTYPES_SERIES[1], as_scitype=scitype).get(0) + # expectation is that the conversion is to mtype MTYPES_SERIES[0] + exp_fixt = get_examples(mtype=MTYPES_SERIES[0], as_scitype=scitype).get(0) + + # carry out the conversion using convert_to + converted = convert_to(from_fixt, to_type=MTYPES_SERIES[0], as_scitype=scitype) + + # compare expected output with actual output of convert_to + msg = "convert_to basic call does not seem to work." + assert deep_equals(converted, exp_fixt), msg + + +def test_convert_to_without_scitype(): + """Testing convert_to call without scitype specification.""" + scitype = SCITYPES[0] + + from_fixt = get_examples(mtype=MTYPES_SERIES[1], as_scitype=scitype).get(0) + # convert_to should recognize the correct scitype, otherwise same as above + exp_fixt = get_examples(mtype=MTYPES_SERIES[0], as_scitype=scitype).get(0) + + # carry out the conversion using convert_to + converted = convert_to(from_fixt, to_type=MTYPES_SERIES[0]) + + # compare expected output with actual output of convert_to + msg = "convert_to call without scitype does not seem to work." + assert deep_equals(converted, exp_fixt), msg + + +def test_convert_to_mtype_list(): + """Testing convert_to call to_type being a list, of same scitype.""" + # convert_to list + target_list = MTYPES_SERIES[:2] + scitype = SCITYPES[0] + + # example that is on the list + from_fixt_on = get_examples(mtype=MTYPES_SERIES[1], as_scitype=scitype).get(0) + # example that is not on the list + from_fixt_off = get_examples(mtype=MTYPES_SERIES[2], as_scitype=scitype).get(0) + + # if on the list, result should be equal to input + exp_fixt_on = get_examples(mtype=MTYPES_SERIES[1], as_scitype=scitype).get(0) + # if off the list, result should be converted to mtype that is first on the list + exp_fixt_off = get_examples(mtype=MTYPES_SERIES[0], as_scitype=scitype).get(0) + + # carry out the conversion using convert_to + converted_on = convert_to(from_fixt_on, to_type=target_list) + converted_off = convert_to(from_fixt_off, to_type=target_list) + + # compare expected output with actual output of convert_to + msg = "convert_to call does not work with list for to_type." + assert deep_equals(converted_on, exp_fixt_on), msg + assert deep_equals(converted_off, exp_fixt_off), msg + + +def test_convert_to_mtype_list_different_scitype(): + """Testing convert_to call to_type being a list, of different scitypes.""" + # convert_to list + target_list = MTYPES_SERIES[:2] + MTYPES_PANEL[:2] + scitype0 = SCITYPES[0] + scitype1 = SCITYPES[1] + + # example that is on the list and of scitype0 + from_fixt_on_0 = get_examples(mtype=MTYPES_SERIES[1], as_scitype=scitype0).get(0) + # example that is not on the list and of scitype0 + from_fixt_off_0 = get_examples(mtype=MTYPES_SERIES[2], as_scitype=scitype0).get(0) + # example that is on the list and of scitype1 + from_fixt_on_1 = get_examples(mtype=MTYPES_PANEL[1], as_scitype=scitype1).get(0) + # example that is not on the list and of scitype1 + from_fixt_off_1 = get_examples(mtype=MTYPES_PANEL[2], as_scitype=scitype1).get(0) + + # if on the list, result should be equal to input + exp_fixt_on_0 = get_examples(mtype=MTYPES_SERIES[1], as_scitype=scitype0).get(0) + exp_fixt_on_1 = get_examples(mtype=MTYPES_PANEL[1], as_scitype=scitype1).get(0) + # if off the list, result should be converted to mtype + # of the same scitype that appears earliest on the list + exp_fixt_off_0 = get_examples(mtype=MTYPES_SERIES[0], as_scitype=scitype0).get(0) + exp_fixt_off_1 = get_examples(mtype=MTYPES_PANEL[0], as_scitype=scitype1).get(0) + + # carry out the conversion using convert_to + converted_on_0 = convert_to(from_fixt_on_0, to_type=target_list) + converted_off_0 = convert_to(from_fixt_off_0, to_type=target_list) + converted_on_1 = convert_to(from_fixt_on_1, to_type=target_list) + converted_off_1 = convert_to(from_fixt_off_1, to_type=target_list) + + # compare expected output with actual output of convert_to + msg = "convert_to call does not work with list for to_type of different scitypes." + assert deep_equals(converted_on_0, exp_fixt_on_0), msg + assert deep_equals(converted_off_0, exp_fixt_off_0), msg + assert deep_equals(converted_on_1, exp_fixt_on_1), msg + assert deep_equals(converted_off_1, exp_fixt_off_1), msg diff --git a/sktime/distances/_ddtw.py b/sktime/distances/_ddtw.py index 1997ec151af..dc3bed6fa58 100644 --- a/sktime/distances/_ddtw.py +++ b/sktime/distances/_ddtw.py @@ -25,14 +25,11 @@ def _average_of_slope(q: np.ndarray): Computes the average of the slope of the line through the point in question and its left neighbour, and the slope of the line through the left neighbour and the - right neighbour. - - Mathematically this is defined at: - + right neighbour This is defined at: .. math:: - D_{x}[q] = \frac{{}(q_{i} - q_{i-1} + ((q_{i+1} - q_{i-1}/2)}{2} + D_(q) = \frac{{}(q_{i} - q_{i-1} + ((q_{i+1} - q_{i-1}/2)}{2} - Where q is the original timeseries and d_q is the derived timeseries. + Where q is the original timeseries and d_q is the derived time series. Parameters ---------- @@ -44,9 +41,7 @@ def _average_of_slope(q: np.ndarray): np.ndarray (2d array of shape nxm where n is len(q.shape[0]-2) and m is len(q.shape[1])) Array containing the derivative of q. - """ - # Taken from https://github.com/tslearn-team/tslearn/issues/180 return 0.25 * q[2:] + 0.5 * q[1:-1] - 0.75 * q[:-2] diff --git a/sktime/distances/_edr.py b/sktime/distances/_edr.py index b6559d3d2ef..3bacccc5094 100644 --- a/sktime/distances/_edr.py +++ b/sktime/distances/_edr.py @@ -17,7 +17,7 @@ class _EdrDistance(NumbaDistance): - """Edit distance for real sequences (edr) between two timeseries.""" + """Edit distance for real sequences (edr) between two time series.""" def _distance_factory( self, diff --git a/sktime/distances/_lcss.py b/sktime/distances/_lcss.py index af911677c53..fd9f30d7a4f 100644 --- a/sktime/distances/_lcss.py +++ b/sktime/distances/_lcss.py @@ -17,43 +17,67 @@ class _LcssDistance(NumbaDistance): - """Longest common subsequence (Lcss) between two timeseries.""" + r"""Longest common subsequence (Lcss) between two time series. + + The Longest Common Subsequence (LCSS) distance is based on the solution to the + longest common subsequence problem in pattern matching [1]. The typical problem + is to + find the longest subsequence that is common to two discrete series based on the + edit distance. This approach can be extended to consider real-valued time series + by using a distance threshold epsilon, which defines the maximum difference + between a pair of values that is allowed for them to be considered a match. + LCSS finds the optimal alignment between two series by find the greatest number + of matching pairs. The LCSS distance uses a matrix L that records the sequence of + matches over valid warpings. for two series a = a_1,... a_m and b = b_1, + ... b_m, L is found by iterating over all valid windows (i.e. + where |i-j| DistanceCallable: """Create a no_python compiled lcss distance callable. Parameters ---------- - x: np.ndarray (2d array) - First timeseries. - y: np.ndarray (2d array) - Second timeseries. - window: float, defaults = None - Float that is the radius of the sakoe chiba window (if using Sakoe-Chiba - lower bounding). Must be between 0 and 1. - itakura_max_slope: float, defaults = None - Gradient of the slope for itakura parallelogram (if using Itakura - Parallelogram lower bounding). Must be between 0 and 1. - bounding_matrix: np.ndarray (2d of size mxn where m is len(x) and n is len(y)), - defaults = None - Custom bounding matrix to use. If defined then other lower_bounding params - are ignored. The matrix should be structure so that indexes considered in - bound should be the value 0. and indexes outside the bounding matrix should - be infinity. - epsilon : float, defaults = 1. + x: np.ndarray (2d array), First time series. + y: np.ndarray (2d array), Second time series. + epsilon : float, default = 1. Matching threshold to determine if two subsequences are considered close enough to be considered 'common'. - kwargs: Any - Extra kwargs. + window: float, default = None, radius of the bounding window (if using + Sakoe-Chiba lower bounding). Must be between 0 and 1. + itakura_max_slope: float, defaults = None, gradient of the slope for bounding + parallelogram (if using Itakura parallelogram lower bounding). Must be + between 0 and 1. + bounding_matrix: np.ndarray (2d of size mxn where m is len(x) and n is len( + y)), defaults = None, Custom bounding matrix to use. If defined then other + lower_bounding params are ignored. The matrix should be structure so that + indexes considered in bound should be the value 0. and indexes outside the + bounding matrix should be infinity. + kwargs: Any Extra kwargs. Returns ------- @@ -63,8 +87,8 @@ def _distance_factory( Raises ------ ValueError - If the input timeseries is not a numpy array. - If the input timeseries doesn't have exactly 2 dimensions. + If the input time series is not a numpy array. + If the input time series doesn't have exactly 2 dimensions. If the sakoe_chiba_window_radius is not an integer. If the itakura_max_slope is not a float or int. If epsilon is not a float. @@ -100,10 +124,8 @@ def _sequence_cost_matrix( Parameters ---------- - x: np.ndarray (2d array) - First timeseries. - y: np.ndarray (2d array) - Second timeseries. + x: np.ndarray (2d array), first time series. + y: np.ndarray (2d array), second time series. bounding_matrix: np.ndarray (2d of size mxn where m is len(x) and n is len(y)) Bounding matrix where the values in bound are marked by finite values and outside bound points are infinite values. diff --git a/sktime/forecasting/arima.py b/sktime/forecasting/arima.py index 0ec2b26790c..db00a840f3b 100644 --- a/sktime/forecasting/arima.py +++ b/sktime/forecasting/arima.py @@ -355,6 +355,23 @@ def _instantiate_model(self): **self.model_kwargs ) + @classmethod + def get_test_params(cls): + """Return testing parameter settings for the estimator. + + Returns + ------- + params : dict or list of dict + """ + params = { + "d": 0, + "suppress_warnings": True, + "max_p": 2, + "max_q": 2, + "seasonal": False, + } + return params + class ARIMA(_PmdArimaAdapter): """An ARIMA estimator. diff --git a/sktime/forecasting/base/_fh.py b/sktime/forecasting/base/_fh.py index 2a81600f172..85d9f19ac83 100644 --- a/sktime/forecasting/base/_fh.py +++ b/sktime/forecasting/base/_fh.py @@ -7,15 +7,22 @@ __all__ = ["ForecastingHorizon"] from functools import lru_cache -from typing import Union +from typing import Optional, Union import numpy as np import pandas as pd from sktime.utils.datetime import _coerce_duration_to_int, _get_freq +from sktime.utils.validation import ( + array_is_int, + array_is_timedelta_or_date_offset, + is_array, + is_int, + is_timedelta_or_date_offset, +) from sktime.utils.validation.series import VALID_INDEX_TYPES -RELATIVE_TYPES = (pd.Int64Index, pd.RangeIndex) +RELATIVE_TYPES = (pd.Int64Index, pd.RangeIndex, pd.TimedeltaIndex) ABSOLUTE_TYPES = (pd.Int64Index, pd.RangeIndex, pd.DatetimeIndex, pd.PeriodIndex) assert set(RELATIVE_TYPES).issubset(VALID_INDEX_TYPES) assert set(ABSOLUTE_TYPES).issubset(VALID_INDEX_TYPES) @@ -92,13 +99,19 @@ def _check_values(values: Union[VALID_FORECASTING_HORIZON_TYPES]) -> pd.Index: pass # convert single integer to pandas index, no further checks needed - elif isinstance(values, (int, np.integer)): + elif is_int(values): return pd.Int64Index([values], dtype=int) + elif is_timedelta_or_date_offset(values): + return pd.Index([values]) + # convert np.array or list to pandas index - elif isinstance(values, (list, np.ndarray)): + elif is_array(values) and array_is_int(values): values = pd.Int64Index(values, dtype=int) + elif is_array(values) and array_is_timedelta_or_date_offset(values): + values = pd.Index(values) + # otherwise, raise type error else: valid_types = ( @@ -158,7 +171,7 @@ def __new__( def __init__( self, values: Union[VALID_FORECASTING_HORIZON_TYPES] = None, - is_relative: bool = True, + is_relative: Optional[bool] = True, ): if is_relative is not None and not isinstance(is_relative, bool): raise TypeError("`is_relative` must be a boolean or None") @@ -166,16 +179,14 @@ def __init__( # check types, note that isinstance() does not work here because index # types inherit from each other, hence we check for type equality - error_msg = ( - f"`values` type is not compatible with `is_relative=" f"{is_relative}`." - ) + error_msg = f"`values` type is not compatible with `is_relative={is_relative}`." if is_relative is None: if type(values) in RELATIVE_TYPES: is_relative = True elif type(values) in ABSOLUTE_TYPES: is_relative = False else: - raise TypeError(type(values) + "is not a supported fh index type") + raise TypeError(f"{type(values)} is not a supported fh index type") if is_relative: if not type(values) in RELATIVE_TYPES: raise TypeError(error_msg) @@ -284,6 +295,8 @@ def to_relative(self, cutoff=None): absolute = _coerce_to_period(absolute, freq) cutoff = _coerce_to_period(cutoff, freq) + # TODO: Replace the following line if the bug in pandas is fixed + # and its version is restricted in sktime dependencies # Compute relative values # The following line circumvents the bug in pandas # periods = pd.period_range(start="2021-01-01", periods=3, freq="2H") @@ -291,6 +304,13 @@ def to_relative(self, cutoff=None): # 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: v0.12.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]) # Coerce durations (time deltas) into integer values for given frequency diff --git a/sktime/forecasting/base/tests/test_fh.py b/sktime/forecasting/base/tests/test_fh.py index c28f3917693..8f301975134 100644 --- a/sktime/forecasting/base/tests/test_fh.py +++ b/sktime/forecasting/base/tests/test_fh.py @@ -28,6 +28,7 @@ _coerce_duration_to_int, _get_duration, _get_freq, + _get_intervals_count_and_unit, _shift, ) from sktime.utils.validation.series import VALID_INDEX_TYPES @@ -137,7 +138,7 @@ def test_check_fh_values_duplicate_input_values(arg): ForecastingHorizon(arg) -GOOD_INPUT_ARGS = ( +GOOD_ABSOLUTE_INPUT_ARGS = ( pd.Int64Index([1, 2, 3]), pd.period_range("2000-01-01", periods=3, freq="D"), pd.date_range("2000-01-01", periods=3, freq="M"), @@ -147,13 +148,25 @@ def test_check_fh_values_duplicate_input_values(arg): ) -@pytest.mark.parametrize("arg", GOOD_INPUT_ARGS) -def test_check_fh_values_input_conversion_to_pandas_index(arg): - """Test conversion to pandas index.""" +@pytest.mark.parametrize("arg", GOOD_ABSOLUTE_INPUT_ARGS) +def test_check_fh_absolute_values_input_conversion_to_pandas_index(arg): + """Test conversion of absolute horizons to pandas index.""" output = ForecastingHorizon(arg, is_relative=False).to_pandas() assert type(output) in VALID_INDEX_TYPES +GOOD_RELATIVE_INPUT_ARGS = [ + pd.timedelta_range(pd.to_timedelta(1, unit="D"), periods=3, freq="D") +] + + +@pytest.mark.parametrize("arg", GOOD_RELATIVE_INPUT_ARGS) +def test_check_fh_relative_values_input_conversion_to_pandas_index(arg): + """Test conversion of relative horizons to pandas index.""" + output = ForecastingHorizon(arg, is_relative=True).to_pandas() + assert type(output) in VALID_INDEX_TYPES + + TIMEPOINTS = [ pd.Period("2000", freq="M"), pd.Timestamp("2000-01-01", freq="D"), @@ -233,7 +246,9 @@ def test_get_duration(n_timepoints, index_type): assert duration == n_timepoints - 1 -FREQUENCY_STRINGS = ["10T", "H", "D", "2D", "W-WED", "W-SUN", "W-SAT", "M"] +FIXED_FREQUENCY_STRINGS = ["10T", "H", "D", "2D"] +NON_FIXED_FREQUENCY_STRINGS = ["W-WED", "W-SUN", "W-SAT", "M"] +FREQUENCY_STRINGS = [*FIXED_FREQUENCY_STRINGS, *NON_FIXED_FREQUENCY_STRINGS] @pytest.mark.parametrize("freqstr", FREQUENCY_STRINGS) @@ -246,8 +261,8 @@ def test_to_absolute_freq(freqstr): @pytest.mark.parametrize("freqstr", FREQUENCY_STRINGS) -def test_absolute_to_absolute(freqstr): - """Test converting between absolute and relative.""" +def test_absolute_to_absolute_with_integer_horizon(freqstr): + """Test converting between absolute and relative with integer horizon.""" # Converts from absolute to relative and back to absolute train = pd.Series(1, index=pd.date_range("2021-10-06", freq=freqstr, periods=3)) fh = ForecastingHorizon([1, 2, 3]) @@ -258,9 +273,25 @@ def test_absolute_to_absolute(freqstr): assert converted_abs_fh._values.freqstr == freqstr +@pytest.mark.parametrize("freqstr", FIXED_FREQUENCY_STRINGS) +def test_absolute_to_absolute_with_timedelta_horizon(freqstr): + """Test converting between absolute and relative.""" + # Converts from absolute to relative and back to absolute + train = pd.Series(1, index=pd.date_range("2021-10-06", freq=freqstr, periods=3)) + count, unit = _get_intervals_count_and_unit(freq=freqstr) + fh = ForecastingHorizon( + pd.timedelta_range(pd.to_timedelta(count, unit=unit), freq=freqstr, periods=3) + ) + abs_fh = fh.to_absolute(train.index[-1]) + + converted_abs_fh = abs_fh.to_relative(train.index[-1]).to_absolute(train.index[-1]) + assert_array_equal(abs_fh, converted_abs_fh) + assert converted_abs_fh._values.freqstr == freqstr + + @pytest.mark.parametrize("freqstr", FREQUENCY_STRINGS) -def test_relative_to_relative(freqstr): - """Test converting between relative and absolute.""" +def test_relative_to_relative_with_integer_horizon(freqstr): + """Test converting between relative and absolute with integer horizons.""" # Converts from relative to absolute and back to relative train = pd.Series(1, index=pd.date_range("2021-10-06", freq=freqstr, periods=3)) fh = ForecastingHorizon([1, 2, 3]) @@ -270,6 +301,21 @@ def test_relative_to_relative(freqstr): assert_array_equal(fh, converted_rel_fh) +@pytest.mark.parametrize("freqstr", FIXED_FREQUENCY_STRINGS) +def test_relative_to_relative_with_timedelta_horizon(freqstr): + """Test converting between relative and absolute with timedelta horizons.""" + # Converts from relative to absolute and back to relative + train = pd.Series(1, index=pd.date_range("2021-10-06", freq=freqstr, periods=3)) + count, unit = _get_intervals_count_and_unit(freq=freqstr) + fh = ForecastingHorizon( + pd.timedelta_range(pd.to_timedelta(count, unit=unit), freq=freqstr, periods=3) + ) + abs_fh = fh.to_absolute(train.index[-1]) + + converted_rel_fh = abs_fh.to_relative(train.index[-1]) + assert_array_equal(converted_rel_fh, np.arange(1, 4)) + + @pytest.mark.parametrize("freq", FREQUENCY_STRINGS) def test_to_relative(freq: str): """Test conversion to relative. diff --git a/sktime/forecasting/bats.py b/sktime/forecasting/bats.py index e66cd3db374..30b60569384 100644 --- a/sktime/forecasting/bats.py +++ b/sktime/forecasting/bats.py @@ -118,3 +118,21 @@ class BATS(_TbatsAdapter): from tbats import BATS as _BATS _ModelClass = _BATS + + @classmethod + def get_test_params(cls): + """Return testing parameter settings for the estimator. + + Returns + ------- + params : dict or list of dict + """ + params = { + "use_box_cox": False, + "use_trend": False, + "use_damped_trend": False, + "sp": [], + "use_arma_errors": False, + "n_jobs": 1, + } + return params diff --git a/sktime/forecasting/compose/_column_ensemble.py b/sktime/forecasting/compose/_column_ensemble.py index f85d29bff11..99afdb45cd6 100644 --- a/sktime/forecasting/compose/_column_ensemble.py +++ b/sktime/forecasting/compose/_column_ensemble.py @@ -32,9 +32,8 @@ class ColumnEnsembleForecaster(_HeterogenousEnsembleForecaster): >>> from sktime.forecasting.compose import ColumnEnsembleForecaster >>> from sktime.forecasting.exp_smoothing import ExponentialSmoothing >>> from sktime.forecasting.trend import PolynomialTrendForecaster - >>> from sktime.datasets import load_longley - >>> _, y = load_longley() - >>> y = y.drop(columns=["UNEMP", "ARMED", "POP"]) + >>> from sktime.datasets import load_macroeconomic + >>> y = load_macroeconomic()[["realgdp", "realcons"]] >>> forecasters = [ ... ("trend", PolynomialTrendForecaster(), 0), ... ("ses", ExponentialSmoothing(trend='add'), 1), @@ -148,7 +147,7 @@ def _predict(self, fh=None, X=None, return_pred_int=False, alpha=DEFAULT_ALPHA): y_pred = np.zeros((len(fh), len(self.forecasters_))) for (_, forecaster, index) in self.forecasters_: - y_pred[:, index] = forecaster.predict(fh) + y_pred[:, index] = forecaster.predict(fh=fh, X=X) y_pred = pd.DataFrame(data=y_pred, columns=self.y_columns) y_pred.index = self.fh.to_absolute(self.cutoff) diff --git a/sktime/forecasting/compose/_ensemble.py b/sktime/forecasting/compose/_ensemble.py index 9561a513e22..b019472f788 100644 --- a/sktime/forecasting/compose/_ensemble.py +++ b/sktime/forecasting/compose/_ensemble.py @@ -222,6 +222,20 @@ def _predict(self, fh, X=None, return_pred_int=False, alpha=DEFAULT_ALPHA): y_pred = y_pred_df.apply(lambda x: np.average(x, weights=self.weights_), axis=1) return y_pred + @classmethod + def get_test_params(cls): + """Return testing parameter settings for the estimator. + + Returns + ------- + params : dict or list of dict + """ + from sktime.forecasting.naive import NaiveForecaster + + FORECASTER = NaiveForecaster() + params = {"forecasters": [("f1", FORECASTER), ("f2", FORECASTER)]} + return params + def _get_weights(regressor): # tree-based models from sklearn which have feature importance values @@ -336,6 +350,20 @@ def _predict(self, fh, X=None, return_pred_int=False, alpha=DEFAULT_ALPHA): return y_pred + @classmethod + def get_test_params(cls): + """Return testing parameter settings for the estimator. + + Returns + ------- + params : dict or list of dict + """ + from sktime.forecasting.naive import NaiveForecaster + + FORECASTER = NaiveForecaster() + params = {"forecasters": [("f1", FORECASTER), ("f2", FORECASTER)]} + return params + def _aggregate(y, aggfunc, weights): """Apply aggregation function by row. diff --git a/sktime/forecasting/compose/_multiplexer.py b/sktime/forecasting/compose/_multiplexer.py index 27f4881efeb..5114bf660ea 100644 --- a/sktime/forecasting/compose/_multiplexer.py +++ b/sktime/forecasting/compose/_multiplexer.py @@ -197,3 +197,23 @@ def _update(self, y, X=None, update_params=True): """ self.forecaster_.update(y, X, update_params=update_params) return self + + @classmethod + def get_test_params(cls): + """Return testing parameter settings for the estimator. + + Returns + ------- + params : dict or list of dict + """ + from sktime.forecasting.naive import NaiveForecaster + + params = { + "forecasters": [ + ("Naive_mean", NaiveForecaster(strategy="mean")), + ("Naive_last", NaiveForecaster(strategy="last")), + ("Naive_drift", NaiveForecaster(strategy="drift")), + ], + "selected_forecaster": "Naive_mean", + } + return params diff --git a/sktime/forecasting/compose/_stack.py b/sktime/forecasting/compose/_stack.py index bea7879c2a5..8fb8c734347 100644 --- a/sktime/forecasting/compose/_stack.py +++ b/sktime/forecasting/compose/_stack.py @@ -163,3 +163,17 @@ def _predict(self, fh=None, X=None, return_pred_int=False, alpha=DEFAULT_ALPHA): # index = y_preds.index index = self.fh.to_absolute(self.cutoff) return pd.Series(y_pred, index=index) + + @classmethod + def get_test_params(cls): + """Return testing parameter settings for the estimator. + + Returns + ------- + params : dict or list of dict + """ + from sktime.forecasting.naive import NaiveForecaster + + FORECASTER = NaiveForecaster() + params = {"forecasters": [("f1", FORECASTER), ("f2", FORECASTER)]} + return params diff --git a/sktime/forecasting/fbprophet.py b/sktime/forecasting/fbprophet.py index b20f0bc1036..5ec9d59a60e 100644 --- a/sktime/forecasting/fbprophet.py +++ b/sktime/forecasting/fbprophet.py @@ -193,3 +193,21 @@ def _instantiate_model(self): stan_backend=self.stan_backend, ) return self + + @classmethod + def get_test_params(cls): + """Return testing parameter settings for the estimator. + + Returns + ------- + params : dict or list of dict + """ + params = { + "n_changepoints": 0, + "yearly_seasonality": False, + "weekly_seasonality": False, + "daily_seasonality": False, + "uncertainty_samples": 1000, + "verbose": False, + } + return params diff --git a/sktime/forecasting/hcrystalball.py b/sktime/forecasting/hcrystalball.py index 1c199c15aa1..94ecc4cfe8a 100644 --- a/sktime/forecasting/hcrystalball.py +++ b/sktime/forecasting/hcrystalball.py @@ -6,8 +6,8 @@ import pandas as pd from sklearn.base import clone -from sktime.forecasting.base._base import DEFAULT_ALPHA from sktime.forecasting.base import BaseForecaster +from sktime.forecasting.base._base import DEFAULT_ALPHA from sktime.utils.validation._dependencies import _check_soft_dependencies _check_soft_dependencies("hcrystalball") @@ -168,3 +168,16 @@ def get_fitted_params(self): def _compute_pred_err(self, alphas): raise NotImplementedError() + + @classmethod + def get_test_params(cls): + """Return testing parameter settings for the estimator. + + Returns + ------- + params : dict or list of dict + """ + from hcrystalball.wrappers import HoltSmoothingWrapper + + params = {"model": HoltSmoothingWrapper()} + return params diff --git a/sktime/forecasting/model_selection/_split.py b/sktime/forecasting/model_selection/_split.py index a58a8d3f0b7..f52fcc2a1e9 100644 --- a/sktime/forecasting/model_selection/_split.py +++ b/sktime/forecasting/model_selection/_split.py @@ -29,10 +29,17 @@ from sktime.utils.validation import ( ACCEPTED_WINDOW_LENGTH_TYPES, NON_FLOAT_WINDOW_LENGTH_TYPES, + array_is_datetime64, + array_is_int, + array_is_timedelta_or_date_offset, check_window_length, + is_datetime, + is_int, + is_timedelta, is_timedelta_or_date_offset, ) from sktime.utils.validation.forecasting import ( + VALID_CUTOFF_TYPES, check_cutoffs, check_fh, check_step_length, @@ -157,7 +164,19 @@ def _check_fh(fh: VALID_FORECASTING_HORIZON_TYPES) -> ForecastingHorizon: def _get_end(y: ACCEPTED_Y_TYPES, fh: ForecastingHorizon) -> int: - """Compute the end of the last training window for a forecasting horizon.""" + """Compute the end of the last training window for a forecasting horizon. + + Parameters + ---------- + y : pd.Series, pd.DataFrame, np.ndarray, or pd.Index + coerced and checked version of input y + fh : int, timedelta, list or np.array of ints or timedeltas + + Returns + ------- + end : int + end of the training window + """ # `fh` is assumed to be ordered and checked by `_check_fh` and `window_length` by # `check_window_length`. n_timepoints = y.shape[0] @@ -181,6 +200,25 @@ def _check_window_lengths( window_length: NON_FLOAT_WINDOW_LENGTH_TYPES, initial_window: NON_FLOAT_WINDOW_LENGTH_TYPES, ) -> None: + """Check that combination of inputs is compatible. + + Parameters + ---------- + y : pd.Series, pd.DataFrame, np.ndarray, or pd.Index + coerced and checked version of input y + fh : int, timedelta, list or np.array of ints or timedeltas + window_length : int or timedelta or pd.DateOffset + initial_window : int or timedelta or pd.DateOffset + Window length of first window + + Raises + ------ + ValueError + if window length plus max horizon is above the last observation in `y`, + or if initial window plus max horizon is above the last observation in `y` + TypeError + if type of the input is not supported + """ n_timepoints = y.shape[0] fh_max = fh[-1] @@ -214,12 +252,144 @@ def _check_window_lengths( if y.get_loc(min(y[-1], y[0] + initial_window)) + fh_max > n_timepoints: raise ValueError(error_msg_for_incompatible_initial_window) if not is_timedelta_or_date_offset(x=window_length): - raise ValueError(error_msg_for_incompatible_types) + raise TypeError(error_msg_for_incompatible_types) else: if initial_window + fh_max > n_timepoints: raise ValueError(error_msg_for_incompatible_initial_window) if is_timedelta_or_date_offset(x=window_length): - raise ValueError(error_msg_for_incompatible_types) + raise TypeError(error_msg_for_incompatible_types) + + +def _cutoffs_fh_window_length_types_are_supported( + cutoffs: VALID_CUTOFF_TYPES, + fh: FORECASTING_HORIZON_TYPES, + window_length: ACCEPTED_WINDOW_LENGTH_TYPES, +) -> bool: + """Check that combination of inputs is supported. + + Currently, only two cases are allowed: + either all inputs are integers, or they are all datetime or timedelta + + Parameters + ---------- + cutoffs : np.array or pd.Index + cutoff points, positive and integer- or datetime-index like + fh : int, timedelta, list or np.array of ints or timedeltas + window_length : int or timedelta or pd.DateOffset + + Returns + ------- + True if all inputs are compatible, False otherwise + """ + all_int = array_is_int(cutoffs) and array_is_int(fh) and is_int(window_length) + all_dates = ( + array_is_datetime64(cutoffs) + and array_is_timedelta_or_date_offset(fh) + and is_timedelta_or_date_offset(window_length) + ) + if all_int or all_dates: + return True + else: + return False + + +def _check_cutoffs_fh_window_length( + cutoffs: VALID_CUTOFF_TYPES, + fh: FORECASTING_HORIZON_TYPES, + window_length: ACCEPTED_WINDOW_LENGTH_TYPES, +) -> None: + """Check that combination of inputs is supported. + + Currently, only two cases are allowed: + either all inputs are integers, or they are all datetime or timedelta + + Parameters + ---------- + cutoffs : np.array or pd.Index + cutoff points, positive and integer- or datetime-index like + fh : int, timedelta, list or np.array of ints or timedeltas + window_length : int or timedelta or pd.DateOffset + + Raises + ------ + TypeError + if combination of inputs is not supported + """ + if not _cutoffs_fh_window_length_types_are_supported( + cutoffs=cutoffs, fh=fh, window_length=window_length + ): + raise TypeError("Unsupported combination of types") + + +def _check_cutoffs_and_y(cutoffs: VALID_CUTOFF_TYPES, y: ACCEPTED_Y_TYPES) -> None: + """Check that combination of inputs is compatible. + + Parameters + ---------- + cutoffs : np.array or pd.Index + cutoff points, positive and integer- or datetime-index like + y : pd.Series, pd.DataFrame, np.ndarray, or pd.Index + coerced and checked version of input y + + Raises + ------ + ValueError + if max cutoff is above the last observation in `y` + TypeError + if `cutoffs` type is not supported + """ + max_cutoff = np.max(cutoffs) + msg = ( + "`cutoffs` are incompatible with given `y`. " + "Maximum cutoff is not smaller than the " + ) + if array_is_int(cutoffs): + if max_cutoff >= y.shape[0]: + raise ValueError(msg + "number of observations.") + elif array_is_datetime64(cutoffs): + if max_cutoff >= np.max(y): + raise ValueError(msg + "maximum index value of `y`.") + else: + raise TypeError("Unsupported type of `cutoffs`") + + +def _check_cutoffs_fh_y( + cutoffs: VALID_CUTOFF_TYPES, fh: FORECASTING_HORIZON_TYPES, y: ACCEPTED_Y_TYPES +) -> None: + """Check that combination of inputs is compatible. + + Currently, only two cases are allowed: + either both `cutoffs` and `fh` are integers, or they are datetime or timedelta. + + Parameters + ---------- + cutoffs : np.array or pd.Index + Cutoff points, positive and integer- or datetime-index like. + Type should match the type of `fh` input. + fh : int, timedelta, list or np.array of ints or timedeltas + Type should match the type of `cutoffs` input. + y : pd.Series, pd.DataFrame, np.ndarray, or pd.Index + coerced and checked version of input y + + Raises + ------ + ValueError + if max cutoff plus max `fh` is above the last observation in `y` + TypeError + if `cutoffs` and `fh` type combination is not supported + """ + max_cutoff = np.max(cutoffs) + max_fh = fh.max() + + msg = "`fh` is incompatible with given `cutoffs` and `y`." + if is_int(x=max_cutoff) and is_int(x=max_fh): + if max_cutoff + max_fh > y.shape[0]: + raise ValueError(msg) + elif is_datetime(x=max_cutoff) and is_timedelta(x=max_fh): + if max_cutoff + max_fh > y.max(): + raise ValueError(msg) + else: + raise TypeError("Unsupported type of `cutoffs` and `fh`") class BaseSplitter: @@ -379,24 +549,30 @@ class CutoffSplitter(BaseSplitter): Here the user is expected to provide a set of cutoffs (train set endpoints), which using the notation provided in :class:`BaseSplitter`, - can be written as :math:`\{t(k_1),\ldots,t(k_n)\}`. + can be written as :math:`\{k_1,\ldots,k_n\}` for integer based indexing, + or :math:`\{t(k_1),\ldots,t(k_n)\}` for datetime based indexing. + Training window's last point is equal to the cutoff, + while test window starts from the next observation in `y`. + The number of splits returned by `.get_n_splits` is then trivially equal to :math:`n`. + The sorted array of cutoffs returned by `.get_cutoffs` is then equal to :math:`\{t(k_1),\ldots,t(k_n)\}` with :math:`k_i None: @@ -404,23 +580,43 @@ def __init__( super(CutoffSplitter, self).__init__(fh, window_length) def _split(self, y: ACCEPTED_Y_TYPES) -> SPLIT_GENERATOR_TYPE: - cutoffs = check_cutoffs(self.cutoffs) - if np.max(cutoffs) >= y.shape[0]: - raise ValueError("`cutoffs` are incompatible with given `y`.") - - fh = _check_fh(self.fh) n_timepoints = y.shape[0] + cutoffs = check_cutoffs(cutoffs=self.cutoffs) + fh = _check_fh(fh=self.fh) + window_length = check_window_length( + window_length=self.window_length, n_timepoints=n_timepoints + ) + _check_cutoffs_fh_window_length( + cutoffs=cutoffs, fh=fh, window_length=window_length + ) + _check_cutoffs_and_y(cutoffs=cutoffs, y=y) + _check_cutoffs_fh_y(cutoffs=cutoffs, fh=fh, y=y) + max_fh = fh.max() + max_cutoff = np.max(cutoffs) - if np.max(cutoffs) + np.max(fh) > y.shape[0]: - raise ValueError("`fh` is incompatible with given `cutoffs` and `y`.") - window_length = check_window_length(self.window_length, n_timepoints) for cutoff in cutoffs: - if is_timedelta_or_date_offset(x=window_length): - train_start = y.get_loc(max(y[0], y[cutoff] - window_length)) - else: + if is_int(x=window_length) and is_int(x=cutoff): train_start = cutoff - window_length - training_window = np.arange(train_start, cutoff) + 1 - test_window = cutoff + fh + elif is_timedelta_or_date_offset(x=window_length) and is_datetime(x=cutoff): + train_start = y.get_loc(max(y[0], cutoff - window_length)) + else: + raise TypeError( + f"Unsupported combination of types: " + f"`window_length`: {type(window_length)}, " + f"`cutoff`: {type(cutoff)}" + ) + + if is_int(x=cutoff): + training_window = np.arange(train_start, cutoff) + 1 + else: + training_window = np.arange(train_start, y.get_loc(cutoff)) + 1 + + test_window = cutoff + fh.to_numpy() + if is_datetime(x=max_cutoff) and is_timedelta(x=max_fh): + test_window = test_window[test_window >= y.min()] + test_window = np.array( + [y.get_loc(timestamp) for timestamp in test_window] + ) yield training_window, test_window def get_n_splits(self, y: Optional[ACCEPTED_Y_TYPES] = None) -> int: diff --git a/sktime/forecasting/model_selection/_tune.py b/sktime/forecasting/model_selection/_tune.py index c5e061acb4b..af6b4721aa3 100644 --- a/sktime/forecasting/model_selection/_tune.py +++ b/sktime/forecasting/model_selection/_tune.py @@ -458,6 +458,26 @@ def _run_search(self, evaluate_candidates): _check_param_grid(self.param_grid) return evaluate_candidates(ParameterGrid(self.param_grid)) + @classmethod + def get_test_params(cls): + """Return testing parameter settings for the estimator. + + Returns + ------- + params : dict or list of dict + """ + from sktime.forecasting.model_selection._split import SingleWindowSplitter + from sktime.forecasting.naive import NaiveForecaster + from sktime.performance_metrics.forecasting import MeanAbsolutePercentageError + + params = { + "forecaster": NaiveForecaster(strategy="mean"), + "cv": SingleWindowSplitter(fh=1), + "param_grid": {"window_length": [2, 5]}, + "scoring": MeanAbsolutePercentageError(symmetric=True), + } + return params + class ForecastingRandomizedSearchCV(BaseGridSearch): """Perform randomized-search cross-validation to find optimal model parameters. @@ -567,3 +587,23 @@ def _run_search(self, evaluate_candidates): self.param_distributions, self.n_iter, random_state=self.random_state ) ) + + @classmethod + def get_test_params(cls): + """Return testing parameter settings for the estimator. + + Returns + ------- + params : dict or list of dict + """ + from sktime.forecasting.model_selection._split import SingleWindowSplitter + from sktime.forecasting.naive import NaiveForecaster + from sktime.performance_metrics.forecasting import MeanAbsolutePercentageError + + params = { + "forecaster": NaiveForecaster(strategy="mean"), + "cv": SingleWindowSplitter(fh=1), + "param_distributions": {"window_length": [2, 5]}, + "scoring": MeanAbsolutePercentageError(symmetric=True), + } + return params diff --git a/sktime/forecasting/model_selection/tests/test_split.py b/sktime/forecasting/model_selection/tests/test_split.py index 4245c94f43a..d191984f6f6 100644 --- a/sktime/forecasting/model_selection/tests/test_split.py +++ b/sktime/forecasting/model_selection/tests/test_split.py @@ -18,8 +18,13 @@ SlidingWindowSplitter, temporal_train_test_split, ) +from sktime.forecasting.model_selection._split import ( + _cutoffs_fh_window_length_types_are_supported, +) from sktime.forecasting.tests._config import ( + TEST_CUTOFFS, TEST_FHS, + TEST_FHS_TIMEDELTA, TEST_INITIAL_WINDOW, TEST_OOS_FHS, TEST_STEP_LENGTHS, @@ -30,11 +35,16 @@ from sktime.utils._testing.forecasting import _make_fh from sktime.utils._testing.series import _make_series from sktime.utils.datetime import _coerce_duration_to_int -from sktime.utils.validation import is_int, is_timedelta_or_date_offset +from sktime.utils.validation import ( + array_is_datetime64, + array_is_int, + array_is_timedelta_or_date_offset, + is_int, + is_timedelta_or_date_offset, +) from sktime.utils.validation.forecasting import check_fh N_TIMEPOINTS = 30 -CUTOFFS = [np.array([21, 22]), np.array([3, 7, 10])] def _get_windows(cv, y): @@ -63,7 +73,7 @@ def _check_windows(windows, allow_empty_window=False): def _check_cutoffs(cutoffs): assert isinstance(cutoffs, np.ndarray) - assert np.issubdtype(cutoffs.dtype, np.integer) + assert array_is_int(cutoffs) or array_is_datetime64(cutoffs) assert cutoffs.ndim == 1 assert len(cutoffs) > 0 @@ -73,23 +83,48 @@ def _check_n_splits(n_splits): assert n_splits > 0 -def _check_cutoffs_against_test_windows(cutoffs, windows, fh): +def _check_cutoffs_against_test_windows(cutoffs, windows, fh, y): # We check for the last value. Some windows may be incomplete, with no first # value, whereas the last value will always be there. fh = check_fh(fh) - expected = np.array([window[-1] - fh[-1] for window in windows]) + if is_int(fh[-1]): + expected = np.array([window[-1] - fh[-1] for window in windows]) + elif array_is_timedelta_or_date_offset(fh): + expected = np.array( + [(y.index[window[-1]] - fh[-1]).to_datetime64() for window in windows] + ) + else: + raise ValueError(f"Provided `fh` type is not supported: {type(fh[-1])}") np.testing.assert_array_equal(cutoffs, expected) -def _check_cutoffs_against_train_windows(cutoffs, windows): +def _check_cutoffs_against_train_windows(cutoffs, windows, y): # Cutoffs should always be the last values of the train windows. - actual = np.array([window[-1] for window in windows[1:]]) + if array_is_int(cutoffs): + actual = np.array([window[-1] for window in windows[1:]]) + elif array_is_datetime64(cutoffs): + actual = np.array( + [y.index[window[-1]].to_datetime64() for window in windows[1:]] + ) + else: + raise ValueError( + f"Provided `cutoffs` type is not supported: {type(cutoffs[0])}" + ) np.testing.assert_array_equal(actual, cutoffs[1:]) # We treat the first window separately, since it may be empty when setting # `start_with_window=False`. if len(windows[0]) > 0: - np.testing.assert_array_equal(windows[0][-1], cutoffs[0]) + if array_is_int(cutoffs): + np.testing.assert_array_equal(windows[0][-1], cutoffs[0]) + elif array_is_datetime64(cutoffs): + np.testing.assert_array_equal( + y.index[windows[0][-1]].to_datetime64(), cutoffs[0] + ) + else: + raise ValueError( + f"Provided `cutoffs` type is not supported: {type(cutoffs[0])}" + ) def _check_cv(cv, y, allow_empty_window=False): @@ -99,8 +134,8 @@ def _check_cv(cv, y, allow_empty_window=False): cutoffs = cv.get_cutoffs(y) _check_cutoffs(cutoffs) - _check_cutoffs_against_test_windows(cutoffs, test_windows, cv.fh) - _check_cutoffs_against_train_windows(cutoffs, train_windows) + _check_cutoffs_against_test_windows(cutoffs, test_windows, cv.fh, y) + _check_cutoffs_against_train_windows(cutoffs, train_windows, y) n_splits = cv.get_n_splits(y) _check_n_splits(n_splits) @@ -151,14 +186,21 @@ def test_single_window_splitter_default_window_length(y, fh): @pytest.mark.parametrize("y", TEST_YS) -@pytest.mark.parametrize("cutoffs", CUTOFFS) -@pytest.mark.parametrize("fh", TEST_FHS) +@pytest.mark.parametrize("cutoffs", TEST_CUTOFFS) +@pytest.mark.parametrize("fh", [*TEST_FHS, *TEST_FHS_TIMEDELTA]) @pytest.mark.parametrize("window_length", TEST_WINDOW_LENGTHS) def test_cutoff_window_splitter(y, cutoffs, fh, window_length): """Test CutoffSplitter.""" cv = CutoffSplitter(cutoffs, fh=fh, window_length=window_length) - train_windows, test_windows, cutoffs, n_splits = _check_cv(cv, y) - np.testing.assert_array_equal(cutoffs, cv.get_cutoffs(y)) + if _cutoffs_fh_window_length_types_are_supported( + cutoffs=cutoffs, fh=ForecastingHorizon(fh), window_length=window_length + ): + train_windows, test_windows, cutoffs, n_splits = _check_cv(cv, y) + np.testing.assert_array_equal(cutoffs, cv.get_cutoffs(y)) + else: + match = "Unsupported combination of types" + with pytest.raises(TypeError, match=match): + _check_cv(cv, y) @pytest.mark.parametrize("y", TEST_YS) @@ -247,7 +289,7 @@ def test_sliding_window_splitter_with_incompatible_initial_window_and_window_len start_with_window=True, ) match = "The `initial_window` and `window_length` types are incompatible" - with pytest.raises(ValueError, match=match): + with pytest.raises(TypeError, match=match): _check_cv(cv, y) diff --git a/sktime/forecasting/naive.py b/sktime/forecasting/naive.py index 843bbb370d5..906ca43ec5c 100644 --- a/sktime/forecasting/naive.py +++ b/sktime/forecasting/naive.py @@ -197,6 +197,9 @@ def _reshape_last_window_for_sp(self, last_window): pad_width = self.sp_ - remainder else: pad_width = 0 + + pad_width += self.window_length_ - len(last_window) + last_window = np.hstack([np.full(pad_width, np.nan), last_window]) # reshape last window, one column per season diff --git a/sktime/forecasting/online_learning/_online_ensemble.py b/sktime/forecasting/online_learning/_online_ensemble.py index 93389b8e8dc..a58164e048a 100644 --- a/sktime/forecasting/online_learning/_online_ensemble.py +++ b/sktime/forecasting/online_learning/_online_ensemble.py @@ -109,3 +109,17 @@ def _predict(self, fh=None, X=None, return_pred_int=False, alpha=DEFAULT_ALPHA): return (pd.concat(self._predict_forecasters(fh, X), axis=1) * self.weights).sum( axis=1 ) + + @classmethod + def get_test_params(cls): + """Return testing parameter settings for the estimator. + + Returns + ------- + params : dict or list of dict + """ + from sktime.forecasting.naive import NaiveForecaster + + FORECASTER = NaiveForecaster() + params = {"forecasters": [("f1", FORECASTER), ("f2", FORECASTER)]} + return params diff --git a/sktime/forecasting/tbats.py b/sktime/forecasting/tbats.py index c3d36f83d12..8e5f277ac4a 100644 --- a/sktime/forecasting/tbats.py +++ b/sktime/forecasting/tbats.py @@ -120,3 +120,21 @@ class TBATS(_TbatsAdapter): from tbats import TBATS as _TBATS _ModelClass = _TBATS + + @classmethod + def get_test_params(cls): + """Return testing parameter settings for the estimator. + + Returns + ------- + params : dict or list of dict + """ + params = { + "use_box_cox": False, + "use_trend": False, + "use_damped_trend": False, + "sp": [], + "use_arma_errors": False, + "n_jobs": 1, + } + return params diff --git a/sktime/forecasting/tests/_config.py b/sktime/forecasting/tests/_config.py index 9ea2d8cebdd..54860590e30 100644 --- a/sktime/forecasting/tests/_config.py +++ b/sktime/forecasting/tests/_config.py @@ -27,6 +27,15 @@ from sktime.utils._testing.series import _make_series # We here define the parameter values for unit testing. +TEST_CUTOFFS_INT = [np.array([21, 22]), np.array([3, 7, 10])] +# The following timestamps correspond +# to the above integers for `_make_series(all_positive=True)` +TEST_CUTOFFS_TIMESTAMP = [ + pd.to_datetime(["2000-01-22", "2000-01-23"]), + pd.to_datetime(["2000-01-04", "2000-01-08", "2000-01-11"]), +] +TEST_CUTOFFS = [*TEST_CUTOFFS_INT, *TEST_CUTOFFS_TIMESTAMP] + TEST_WINDOW_LENGTHS_INT = [1, 5] TEST_WINDOW_LENGTHS_TIMEDELTA = [pd.Timedelta(1, unit="D"), pd.Timedelta(5, unit="D")] TEST_WINDOW_LENGTHS_DATEOFFSET = [pd.offsets.Day(1), pd.offsets.Day(5)] @@ -61,7 +70,23 @@ 0, # last training point np.array([-3, 2]), # mixed in-sample and out-of-sample ] -TEST_FHS = TEST_OOS_FHS + TEST_INS_FHS +TEST_FHS = [*TEST_OOS_FHS, *TEST_INS_FHS] + +TEST_OOS_FHS_TIMEDELTA = [ + [pd.Timedelta(1, unit="D")], + [pd.Timedelta(2, unit="D"), pd.Timedelta(5, unit="D")], +] # out-of-sample +TEST_INS_FHS_TIMEDELTA = [ + pd.Timedelta(-3, unit="D"), # single in-sample + [pd.Timedelta(-2, unit="D"), pd.Timedelta(-5, unit="D")], # multiple in-sample + pd.Timedelta(0, unit="D"), # last training point + [ + pd.Timedelta(-3, unit="D"), + pd.Timedelta(2, unit="D"), + ], # mixed in-sample and out-of-sample +] +TEST_FHS_TIMEDELTA = [*TEST_OOS_FHS_TIMEDELTA, *TEST_INS_FHS_TIMEDELTA] + TEST_SPS = [3, 12] TEST_ALPHAS = [0.05, 0.1] TEST_YS = [_make_series(all_positive=True)] diff --git a/sktime/forecasting/tests/test_all_forecasters.py b/sktime/forecasting/tests/test_all_forecasters.py index 501ea6c280d..902cb0f01a4 100644 --- a/sktime/forecasting/tests/test_all_forecasters.py +++ b/sktime/forecasting/tests/test_all_forecasters.py @@ -4,23 +4,7 @@ # copyright: sktime developers, BSD-3-Clause License (see LICENSE file) """ -__author__ = ["mloning", "kejsitake"] -__all__ = [ - "test_raises_not_fitted_error", - "test_score", - "test_predict_time_index", - "test_predict_quantiles", - "test_update_predict_predicted_index", - "test_update_predict_predicted_index_update_params", - "test_y_multivariate_raises_error", - "test_get_fitted_params", - "test_predict_time_index_in_sample_full", - "test_predict_interval", - "test_update_predict_single", - "test_y_invalid_type_raises_error", - "test_predict_time_index_with_X", - "test_X_invalid_type_raises_error", -] +__author__ = ["mloning", "kejsitake", "fkiraly"] import numpy as np import pandas as pd @@ -40,7 +24,7 @@ VALID_INDEX_FH_COMBINATIONS, ) from sktime.performance_metrics.forecasting import mean_absolute_percentage_error -from sktime.registry import all_estimators +from sktime.tests.test_all_estimators import BaseFixtureGenerator, QuickTester from sktime.utils._testing.forecasting import ( _assert_correct_pred_time_index, _get_expected_index_for_update_predict, @@ -52,7 +36,6 @@ from sktime.utils.validation.forecasting import check_fh # get all forecasters -FORECASTERS = all_estimators(estimator_types="forecaster", return_names=False) FH0 = 1 INVALID_X_INPUT_TYPES = [list(), tuple()] INVALID_y_INPUT_TYPES = [list(), tuple()] @@ -61,471 +44,489 @@ y = make_forecasting_problem() y_train, y_test = temporal_train_test_split(y, train_size=0.75) +# names for index/fh combinations to display in tests +index_fh_comb_names = [f"{x[0]}-{x[1]}-{x[2]}" for x in VALID_INDEX_FH_COMBINATIONS] -@pytest.mark.parametrize("Forecaster", FORECASTERS) -def test_get_fitted_params(Forecaster): - """Test get_fitted_params.""" - f = Forecaster.create_test_instance() - columns = _get_n_columns(f.get_tag("scitype:y")) - for n_columns in columns: - f = Forecaster.create_test_instance() - y_train = _make_series(n_columns=n_columns) - f.fit(y_train, fh=FH0) - try: - params = f.get_fitted_params() - assert isinstance(params, dict) - - except NotImplementedError: - pass +class ForecasterFixtureGenerator(BaseFixtureGenerator): + """Fixture generator for forecasting tests. -@pytest.mark.parametrize("Forecaster", FORECASTERS) -def test_raises_not_fitted_error(Forecaster): - """Test that calling post-fit methods before fit raises error.""" - # We here check extra method of the forecaster API: update and update_predict. - f = Forecaster.create_test_instance() + Fixtures parameterized + ---------------------- + estimator_class: estimator inheriting from BaseObject + ranges over all estimator classes not excluded by EXCLUDED_TESTS + estimator_instance: instance of estimator inheriting from BaseObject + ranges over all estimator classes not excluded by EXCLUDED_TESTS + instances are generated by create_test_instance class method + scenario: instance of TestScenario + ranges over all scenarios returned by retrieve_scenarios + """ - # predict is check in test suite for all estimators - with pytest.raises(NotFittedError): - f.update(y_test, update_params=False) + # note: this should be separate from TestAllForecasters + # additional fixtures, parameters, etc should be added here + # TestAllForecasters should contain the tests only + + estimator_type_filter = "forecaster" + + fixture_sequence = [ + "estimator_class", + "estimator_instance", + "n_columns", + "scenario", + # "fh", + "update_params", + "step_length", + ] + + def _generate_n_columns(self, test_name, **kwargs): + """Return number of columns for series generation in positive test cases. + + Fixtures parameterized + ---------------------- + n_columns: int + 1 for univariate forecasters, 2 for multivariate forecasters + ranges over 1 and 2 for forecasters which are both uni/multivariate + """ + if "estimator_class" in kwargs.keys(): + scitype_tag = kwargs["estimator_class"].get_class_tag("scitype:y") + elif "estimator_instance" in kwargs.keys(): + scitype_tag = kwargs["estimator_instance"].get_tag("scitype:y") + else: + return [] - with pytest.raises(NotFittedError): - cv = SlidingWindowSplitter(fh=1, window_length=1, start_with_window=False) - f.update_predict(y_test, cv=cv) + n_columns_list = _get_n_columns(scitype_tag) + if len(n_columns_list) == 1: + n_columns_names = ["" for x in n_columns_list] + else: + n_columns_names = [f"y:{x}cols" for x in n_columns_list] + + return n_columns_list, n_columns_names + + def _generate_update_params(self, test_name, **kwargs): + """Return update_params for update calls. + + Fixtures parameterized + ---------------------- + update_params: bool + whether to update parameters in update; ranges over True, False + """ + return [True, False], ["update_params=True", "update_params=False"] + + def _generate_step_length(self, test_name, **kwargs): + """Return step length for window. + + Fixtures parameterized + ---------------------- + step_length: int + 1 if update_params=True; TEST_STEP_LENGTH_INT if update_params=False + """ + update_params = kwargs["update_params"] + if update_params: + return [1], [""] + else: + return TEST_STEP_LENGTHS_INT, [f"step={a}" for a in TEST_STEP_LENGTHS_INT] - try: - with pytest.raises(NotFittedError): - f.get_fitted_params() - except NotImplementedError: - pass +class TestAllForecasters(ForecasterFixtureGenerator, QuickTester): + """Module level tests for all sktime forecasters.""" -@pytest.mark.parametrize("Forecaster", FORECASTERS) -def test_y_multivariate_raises_error(Forecaster): - """Test that wrong y scitype raises error (uni/multivariate if not supported).""" - f = Forecaster.create_test_instance() + def test_get_fitted_params(self, estimator_instance, scenario): + """Test get_fitted_params.""" + scenario.run(estimator_instance, method_sequence=["fit"]) + try: + params = estimator_instance.get_fitted_params() + assert isinstance(params, dict) - if f.get_tag("scitype:y") == "univariate": - y = _make_series(n_columns=2) - with pytest.raises(ValueError, match=r"univariate"): - f.fit(y, fh=FH0) + except NotImplementedError: + pass - if f.get_tag("scitype:y") == "multivariate": - y = _make_series(n_columns=1) - with pytest.raises(ValueError, match=r"2 or more variables"): - f.fit(y, fh=FH0) + # 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. + with pytest.raises(NotFittedError): + estimator_instance.update(y_test, update_params=False) - if f.get_tag("scitype:y") == "both": - pass + with pytest.raises(NotFittedError): + cv = SlidingWindowSplitter(fh=1, window_length=1, start_with_window=False) + estimator_instance.update_predict(y_test, cv=cv) + try: + with pytest.raises(NotFittedError): + estimator_instance.get_fitted_params() + except NotImplementedError: + pass -@pytest.mark.parametrize("Forecaster", FORECASTERS) -@pytest.mark.parametrize("y", INVALID_y_INPUT_TYPES) -def test_y_invalid_type_raises_error(Forecaster, y): - """Test that invalid y input types raise error.""" - f = Forecaster.create_test_instance() - with pytest.raises(TypeError, match=r"type"): - f.fit(y, fh=FH0) + def test_y_multivariate_raises_error(self, estimator_instance): + """Test that wrong y scitype raises error (uni/multivariate not supported).""" + if estimator_instance.get_tag("scitype:y") == "univariate": + y = _make_series(n_columns=2) + with pytest.raises(ValueError, match=r"univariate"): + estimator_instance.fit(y, fh=FH0) + if estimator_instance.get_tag("scitype:y") == "multivariate": + y = _make_series(n_columns=1) + with pytest.raises(ValueError, match=r"2 or more variables"): + estimator_instance.fit(y, fh=FH0) -@pytest.mark.parametrize("Forecaster", FORECASTERS) -@pytest.mark.parametrize("X", INVALID_X_INPUT_TYPES) -def test_X_invalid_type_raises_error(Forecaster, X): - """Test that invalid X input types raise error.""" - f = Forecaster.create_test_instance() - n_columns_list = _get_n_columns(f.get_tag("scitype:y")) + if estimator_instance.get_tag("scitype:y") == "both": + pass - for n_columns in n_columns_list: - f = Forecaster.create_test_instance() + # 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.""" y_train = _make_series(n_columns=n_columns) try: with pytest.raises(TypeError, match=r"type"): - f.fit(y_train, X, fh=FH0) + estimator_instance.fit(y_train, X, fh=FH0) except NotImplementedError as e: msg = str(e).lower() assert "exogenous" in msg - -@pytest.mark.parametrize("Forecaster", FORECASTERS) -@pytest.mark.parametrize( - "index_type, fh_type, is_relative", VALID_INDEX_FH_COMBINATIONS -) -@pytest.mark.parametrize("steps", TEST_FHS) # fh steps -def test_predict_time_index(Forecaster, index_type, fh_type, is_relative, steps): - """Check that predicted time index matches forecasting horizon.""" - f = Forecaster.create_test_instance() - n_columns_list = _get_n_columns(f.get_tag("scitype:y")) - - for n_columns in n_columns_list: - f = Forecaster.create_test_instance() + # todo: refactor with scenarios. Need to override fh and scenario args for this. + @pytest.mark.parametrize( + "index_fh_comb", VALID_INDEX_FH_COMBINATIONS, ids=index_fh_comb_names + ) + @pytest.mark.parametrize("fh_int", TEST_FHS, ids=[f"fh={fh}" for fh in TEST_FHS]) + def test_predict_time_index( + self, estimator_instance, n_columns, index_fh_comb, fh_int + ): + """Check that predicted time index matches forecasting horizon.""" + index_type, fh_type, is_relative = index_fh_comb y_train = _make_series( n_columns=n_columns, index_type=index_type, n_timepoints=50 ) cutoff = y_train.index[-1] - fh = _make_fh(cutoff, steps, fh_type, is_relative) + fh = _make_fh(cutoff, fh_int, fh_type, is_relative) try: - f.fit(y_train, fh=fh) - y_pred = f.predict() - _assert_correct_pred_time_index(y_pred.index, y_train.index[-1], fh=fh) + estimator_instance.fit(y_train, fh=fh) + y_pred = estimator_instance.predict() + _assert_correct_pred_time_index(y_pred.index, y_train.index[-1], fh=fh_int) except NotImplementedError: pass + @pytest.mark.parametrize( + "index_fh_comb", VALID_INDEX_FH_COMBINATIONS, ids=index_fh_comb_names + ) + @pytest.mark.parametrize("fh_int", TEST_FHS, ids=[f"fh={fh}" for fh in TEST_FHS]) + def test_predict_residuals( + self, estimator_instance, n_columns, index_fh_comb, fh_int + ): + """Check that predict_residuals method works as expected.""" + index_type, fh_type, is_relative = index_fh_comb -@pytest.mark.parametrize("Forecaster", FORECASTERS) -@pytest.mark.parametrize( - "index_type, fh_type, is_relative", VALID_INDEX_FH_COMBINATIONS -) -@pytest.mark.parametrize("steps", TEST_FHS) # fh steps -def test_predict_residuals(Forecaster, index_type, fh_type, is_relative, steps): - """Check that predict_residuals method works as expected.""" - f = Forecaster.create_test_instance() - n_columns_list = _get_n_columns(f.get_tag("scitype:y")) - - for n_columns in n_columns_list: - f = Forecaster.create_test_instance() y_train = _make_series( n_columns=n_columns, index_type=index_type, n_timepoints=50 ) cutoff = y_train.index[-1] - fh = _make_fh(cutoff, steps, fh_type, is_relative) + fh = _make_fh(cutoff, fh_int, fh_type, is_relative) try: - f.fit(y_train, fh=fh) - y_pred = f.predict() + estimator_instance.fit(y_train, fh=fh) + y_pred = estimator_instance.predict() y_test = _make_series( n_columns=n_columns, index_type=index_type, n_timepoints=len(y_pred) ) y_test.index = y_pred.index - y_res = f.predict_residuals(y_test) + y_res = estimator_instance.predict_residuals(y_test) _assert_correct_pred_time_index(y_res.index, y_train.index[-1], fh=fh) except NotImplementedError: pass - -@pytest.mark.parametrize("Forecaster", FORECASTERS) -@pytest.mark.parametrize( - "index_type, fh_type, is_relative", VALID_INDEX_FH_COMBINATIONS -) -@pytest.mark.parametrize("steps", TEST_OOS_FHS) # fh steps -def test_predict_time_index_with_X(Forecaster, index_type, fh_type, is_relative, steps): - """Check that predicted time index matches forecasting horizon.""" - f = Forecaster.create_test_instance() - n_columns_list = _get_n_columns(f.get_tag("scitype:y")) - - 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 - # need to catch NotImplementedErrors. - for n_columns in n_columns_list: - f = Forecaster.create_test_instance() + @pytest.mark.parametrize( + "index_fh_comb", VALID_INDEX_FH_COMBINATIONS, ids=index_fh_comb_names + ) + @pytest.mark.parametrize( + "fh_int_oos", TEST_OOS_FHS, ids=[f"fh={fh}" for fh in TEST_OOS_FHS] + ) + def test_predict_time_index_with_X( + self, + estimator_instance, + n_columns, + index_fh_comb, + fh_int_oos, + ): + """Check that predicted time index matches forecasting horizon.""" + index_type, fh_type, is_relative = index_fh_comb + + 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 + # need to catch NotImplementedErrors. y = _make_series(n_columns=n_columns, index_type=index_type) cutoff = y.index[len(y) // 2] - fh = _make_fh(cutoff, steps, fh_type, is_relative) + fh = _make_fh(cutoff, fh_int_oos, fh_type, is_relative) - y_train, y_test, X_train, X_test = temporal_train_test_split(y, X, fh=fh) + y_train, _, X_train, X_test = temporal_train_test_split(y, X, fh=fh) try: - f.fit(y_train, X_train, fh=fh) - y_pred = f.predict(X=X_test) + estimator_instance.fit(y_train, X_train, fh=fh) + y_pred = estimator_instance.predict(X=X_test) _assert_correct_pred_time_index(y_pred.index, y_train.index[-1], fh) except NotImplementedError: pass - -@pytest.mark.parametrize("Forecaster", FORECASTERS) -@pytest.mark.parametrize( - "index_type, fh_type, is_relative", VALID_INDEX_FH_COMBINATIONS -) -def test_predict_time_index_in_sample_full( - Forecaster, index_type, fh_type, is_relative -): - """Check that predicted time index equals fh for full in-sample predictions.""" - f = Forecaster.create_test_instance() - n_columns_list = _get_n_columns(f.get_tag("scitype:y")) - - for n_columns in n_columns_list: - f = Forecaster.create_test_instance() + @pytest.mark.parametrize( + "index_fh_comb", VALID_INDEX_FH_COMBINATIONS, ids=index_fh_comb_names + ) + def test_predict_time_index_in_sample_full( + self, estimator_instance, n_columns, index_fh_comb + ): + """Check that predicted time index equals fh for full in-sample predictions.""" + index_type, fh_type, is_relative = index_fh_comb y_train = _make_series(n_columns=n_columns, index_type=index_type) cutoff = y_train.index[-1] steps = -np.arange(len(y_train)) fh = _make_fh(cutoff, steps, fh_type, is_relative) try: - f.fit(y_train, fh=fh) - y_pred = f.predict() + estimator_instance.fit(y_train, fh=fh) + y_pred = estimator_instance.predict() _assert_correct_pred_time_index(y_pred.index, y_train.index[-1], fh) except NotImplementedError: pass - -def _check_pred_ints( - pred_ints: pd.DataFrame, y_train: pd.Series, y_pred: pd.Series, fh -): - # make iterable - if isinstance(pred_ints, pd.DataFrame): - pred_ints = [pred_ints] - - for pred_int in pred_ints: - # check column naming convention - assert list(pred_int.columns) == ["lower", "upper"] - - # check time index - _assert_correct_pred_time_index(pred_int.index, y_train.index[-1], fh) - # check values - assert np.all(pred_int["upper"] >= pred_int["lower"]) - - # check if errors are weakly monotonically increasing - # pred_errors = y_pred - pred_int["lower"] - # # assert pred_errors.is_mononotic_increasing - # assert np.all( - # pred_errors.values[1:].round(4) >= pred_errors.values[:-1].round(4) - # ) - - -@pytest.mark.parametrize("Forecaster", FORECASTERS) -@pytest.mark.parametrize("fh", TEST_OOS_FHS) -@pytest.mark.parametrize("alpha", TEST_ALPHAS) -def test_predict_interval(Forecaster, fh, alpha): - """Check prediction intervals returned by predict. - - Arguments - --------- - Forecaster: BaseEstimator class descendant, forecaster to test - fh: ForecastingHorizon, fh at which to test prediction - alpha: float, coverage at which to make prediction intervals - - Raises - ------ - AssertionError - if Forecaster test instance has "capability:pred_int" - and pred. int are not returned correctly when asking predict for them - AssertionError - if Forecaster test instance does not have "capability:pred_int" - and no NotImplementedError is raised when asking predict for pred.int - """ - f = Forecaster.create_test_instance() - n_columns_list = _get_n_columns(f.get_tag("scitype:y")) - - for n_columns in n_columns_list: - f = Forecaster.create_test_instance() + def _check_pred_ints( + self, pred_ints: pd.DataFrame, y_train: pd.Series, y_pred: pd.Series, fh_int + ): + # make iterable + if isinstance(pred_ints, pd.DataFrame): + pred_ints = [pred_ints] + + for pred_int in pred_ints: + # check column naming convention + assert list(pred_int.columns) == ["lower", "upper"] + + # check time index + _assert_correct_pred_time_index(pred_int.index, y_train.index[-1], fh_int) + # check values + assert np.all(pred_int["upper"] >= pred_int["lower"]) + + # check if errors are weakly monotonically increasing + # pred_errors = y_pred - pred_int["lower"] + # # assert pred_errors.is_mononotic_increasing + # assert np.all( + # pred_errors.values[1:].round(4) >= pred_errors.values[:-1].round(4) + # ) + + @pytest.mark.parametrize( + "alpha", TEST_ALPHAS, ids=[f"alpha={a}" for a in TEST_ALPHAS] + ) + @pytest.mark.parametrize( + "fh_int_oos", TEST_OOS_FHS, ids=[f"fh={fh}" for fh in TEST_OOS_FHS] + ) + def test_predict_interval(self, estimator_instance, n_columns, fh_int_oos, alpha): + """Check prediction intervals returned by predict. + + Arguments + --------- + Forecaster: BaseEstimator class descendant, forecaster to test + fh: ForecastingHorizon, fh at which to test prediction + alpha: float, coverage at which to make prediction intervals + + Raises + ------ + AssertionError - if Forecaster test instance has "capability:pred_int" + and pred. int are not returned correctly when asking predict for them + AssertionError - if Forecaster test instance does not have "capability:pred_int" + and no NotImplementedError is raised when asking predict for pred.int + """ y_train = _make_series(n_columns=n_columns) - f.fit(y_train, fh=fh) - if f.get_tag("capability:pred_int"): - if f._has_predict_quantiles_been_refactored(): - y_pred = f.predict() - pred_ints = f.predict_interval(fh, coverage=alpha) - - pred_ints = f._convert_new_to_old_pred_int(pred_ints, alpha) + estimator_instance.fit(y_train, fh=fh_int_oos) + if estimator_instance.get_tag("capability:pred_int"): + if estimator_instance._has_predict_quantiles_been_refactored(): + y_pred = estimator_instance.predict() + pred_ints = estimator_instance.predict_interval( + fh_int_oos, coverage=alpha + ) + + pred_ints = estimator_instance._convert_new_to_old_pred_int( + pred_ints, alpha + ) else: - y_pred, pred_ints = f.predict(return_pred_int=True, alpha=alpha) - _check_pred_ints(pred_ints, y_train, y_pred, fh) + y_pred, pred_ints = estimator_instance.predict( + return_pred_int=True, alpha=alpha + ) + self._check_pred_ints(pred_ints, y_train, y_pred, fh_int_oos) else: with pytest.raises(NotImplementedError, match="prediction intervals"): - f.predict(return_pred_int=True, alpha=alpha) - - -def _check_predict_quantiles( - pred_quantiles: pd.DataFrame, y_train: pd.Series, fh, alpha -): - # check if the input is a dataframe - assert isinstance(pred_quantiles, pd.DataFrame) - # check time index (also checks forecasting horizon is more than one element) - _assert_correct_pred_time_index(pred_quantiles.index, y_train.index[-1], fh) - # Forecasters where name of variables do not exist - # In this cases y_train is series - the upper level in dataframe == 'Quantiles' - if isinstance(y_train, pd.Series): - expected = pd.MultiIndex.from_product([["Quantiles"], [alpha]]) - else: - # multiply variables with all alpha values - expected = pd.MultiIndex.from_product([y_train.columns, [alpha]]) - assert all(expected == pred_quantiles.columns.to_flat_index()) - - if isinstance(alpha, list): - # sorts the columns that correspond to alpha values - pred_quantiles = pred_quantiles.reindex( - columns=pred_quantiles.columns.reindex(sorted(alpha), level=1)[0] - ) + estimator_instance.predict(return_pred_int=True, alpha=alpha) + + def _check_predict_quantiles( + self, pred_quantiles: pd.DataFrame, y_train: pd.Series, fh, alpha + ): + # check if the input is a dataframe + assert isinstance(pred_quantiles, pd.DataFrame) + # check time index (also checks forecasting horizon is more than one element) + _assert_correct_pred_time_index(pred_quantiles.index, y_train.index[-1], fh) + # Forecasters where name of variables do not exist + # In this cases y_train is series - the upper level in dataframe == 'Quantiles' + if isinstance(y_train, pd.Series): + expected = pd.MultiIndex.from_product([["Quantiles"], [alpha]]) + else: + # multiply variables with all alpha values + expected = pd.MultiIndex.from_product([y_train.columns, [alpha]]) + assert all(expected == pred_quantiles.columns.to_flat_index()) + + if isinstance(alpha, list): + # sorts the columns that correspond to alpha values + pred_quantiles = pred_quantiles.reindex( + columns=pred_quantiles.columns.reindex(sorted(alpha), level=1)[0] + ) - # check if values are monotonically increasing - for var in pred_quantiles.columns.levels[0]: - for index in range(len(pred_quantiles.index)): - assert pred_quantiles[var].iloc[index].is_monotonic_increasing - - -@pytest.mark.parametrize("Forecaster", FORECASTERS) -@pytest.mark.parametrize("fh", TEST_OOS_FHS) -@pytest.mark.parametrize("alpha", TEST_ALPHAS) -def test_predict_quantiles(Forecaster, fh, alpha): - """Check prediction quantiles returned by predict. - - Arguments - --------- - Forecaster: BaseEstimator class descendant, forecaster to test - fh: ForecastingHorizon, fh at which to test prediction - alpha: float, alpha at which to make prediction intervals - - Raises - ------ - AssertionError - if Forecaster test instance has "capability:pred_int" - and pred. int are not returned correctly when asking predict for them - AssertionError - if Forecaster test instance does not have "capability:pred_int" - and no NotImplementedError is raised when asking predict for pred.int - """ - f = Forecaster.create_test_instance() - n_columns_list = _get_n_columns(f.get_tag("scitype:y")) - for n_columns in n_columns_list: - f = Forecaster.create_test_instance() + # check if values are monotonically increasing + for var in pred_quantiles.columns.levels[0]: + for index in range(len(pred_quantiles.index)): + assert pred_quantiles[var].iloc[index].is_monotonic_increasing + + @pytest.mark.parametrize( + "alpha", TEST_ALPHAS, ids=[f"alpha={a}" for a in TEST_ALPHAS] + ) + @pytest.mark.parametrize( + "fh_int_oos", TEST_OOS_FHS, ids=[f"fh={fh}" for fh in TEST_OOS_FHS] + ) + def test_predict_quantiles(self, estimator_instance, n_columns, fh_int_oos, alpha): + """Check prediction quantiles returned by predict. + + Arguments + --------- + Forecaster: BaseEstimator class descendant, forecaster to test + fh: ForecastingHorizon, fh at which to test prediction + alpha: float, alpha at which to make prediction intervals + + Raises + ------ + AssertionError - if Forecaster test instance has "capability:pred_int" + and pred. int are not returned correctly when asking predict for them + AssertionError - if Forecaster test instance does not have "capability:pred_int" + and no NotImplementedError is raised when asking predict for pred.int + """ y_train = _make_series(n_columns=n_columns) - f.fit(y_train, fh=fh) + estimator_instance.fit(y_train, fh=fh_int_oos) try: - quantiles = f.predict_quantiles(fh=fh, alpha=alpha) - _check_predict_quantiles(quantiles, y_train, fh, alpha) + quantiles = estimator_instance.predict_quantiles(fh=fh_int_oos, alpha=alpha) + self._check_predict_quantiles(quantiles, y_train, fh_int_oos, alpha) except NotImplementedError: pass + def test_pred_int_tag(self, estimator_instance): + """Checks whether the capability:pred_int tag is correctly set. + + Arguments + --------- + Forecaster: BaseEstimator class descendant, forecaster to test + + Raises + ------ + ValueError - if capability:pred_int is True, but neither + predict_interval nor predict_quantiles have implemented content + this can be by direct implementation of _predict_interval/_predict_quantiles + or by defaulting to each other and/or _predict_proba + """ + f = estimator_instance + implements_interval = f._has_implementation_of("_predict_interval") + implements_quantiles = f._has_implementation_of("_predict_quantiles") + implements_proba = f._has_implementation_of("_predict_proba") + + pred_int_works = implements_interval or implements_quantiles or implements_proba + + if not pred_int_works and f.get_class_tag("capability:pred_int", False): + raise ValueError( + f"{f.__name__} does not implement probabilistic forecasting, " + 'but "capability:pred_int" flag has been set to True incorrectly. ' + 'The flag "capability:pred_int" should instead be set to False.' + ) -@pytest.mark.parametrize("Forecaster", FORECASTERS) -def test_pred_int_tag(Forecaster): - """Checks whether the capability:pred_int tag is correctly set. - - Arguments - --------- - Forecaster: BaseEstimator class descendant, forecaster to test - - Raises - ------ - ValueError - if capability:pred_int is True, but neither - predict_interval nor predict_quantiles have implemented content - this can be by direct implementation of _predict_interval or _predict_quantiles - or by defaulting to each other and/or _predict_proba - """ - implements_interval = Forecaster._has_implementation_of("_predict_interval") - implements_quantiles = Forecaster._has_implementation_of("_predict_quantiles") - implements_proba = Forecaster._has_implementation_of("_predict_proba") - - pred_int_works = implements_interval or implements_quantiles or implements_proba - - if not pred_int_works and Forecaster.get_class_tag("capability:pred_int", False): - raise ValueError( - f"{Forecaster.__name__} does not implement probabilistic forecasting, " - 'but "capability:pred_int" flag has been set to True incorrectly. ' - 'The flag "capability:pred_int" should instead be set to False.' - ) - - if pred_int_works and not Forecaster.get_class_tag("capability:pred_int", False): - raise ValueError( - f"{Forecaster.__name__} does implement probabilistic forecasting, " - 'but "capability:pred_int" flag has been set to False incorrectly. ' - 'The flag "capability:pred_int" should instead be set to True.' - ) - - -@pytest.mark.parametrize("Forecaster", FORECASTERS) -@pytest.mark.parametrize("fh", TEST_OOS_FHS) -def test_score(Forecaster, fh): - """Check score method.""" - f = Forecaster.create_test_instance() - n_columns_list = _get_n_columns(f.get_tag("scitype:y")) + if pred_int_works and not f.get_class_tag("capability:pred_int", False): + raise ValueError( + f"{f.__name__} does implement probabilistic forecasting, " + 'but "capability:pred_int" flag has been set to False incorrectly. ' + 'The flag "capability:pred_int" should instead be set to True.' + ) - for n_columns in n_columns_list: - f = Forecaster.create_test_instance() + @pytest.mark.parametrize( + "fh_int_oos", TEST_OOS_FHS, ids=[f"fh={fh}" for fh in TEST_OOS_FHS] + ) + def test_score(self, estimator_instance, n_columns, fh_int_oos): + """Check score method.""" y = _make_series(n_columns=n_columns) y_train, y_test = temporal_train_test_split(y) - f.fit(y_train, fh=fh) - y_pred = f.predict() + estimator_instance.fit(y_train, fh=fh_int_oos) + y_pred = estimator_instance.predict() - fh_idx = check_fh(fh).to_indexer() # get zero based index - actual = f.score(y_test.iloc[fh_idx], fh=fh) + fh_idx = check_fh(fh_int_oos).to_indexer() # get zero based index + actual = estimator_instance.score(y_test.iloc[fh_idx], fh=fh_int_oos) expected = mean_absolute_percentage_error( y_pred, y_test.iloc[fh_idx], symmetric=True ) # compare expected score with actual score - actual = f.score(y_test.iloc[fh_idx], fh=fh) + actual = estimator_instance.score(y_test.iloc[fh_idx], fh=fh_int_oos) assert actual == expected - -@pytest.mark.parametrize("Forecaster", FORECASTERS) -@pytest.mark.parametrize("fh", TEST_OOS_FHS) -@pytest.mark.parametrize("update_params", [True, False]) -def test_update_predict_single(Forecaster, fh, update_params): - """Check correct time index of update-predict.""" - f = Forecaster.create_test_instance() - n_columns_list = _get_n_columns(f.get_tag("scitype:y")) - - for n_columns in n_columns_list: - f = Forecaster.create_test_instance() + @pytest.mark.parametrize( + "fh_int_oos", TEST_OOS_FHS, ids=[f"fh={fh}" for fh in TEST_OOS_FHS] + ) + def test_update_predict_single( + self, estimator_instance, n_columns, fh_int_oos, update_params + ): + """Check correct time index of update-predict.""" y = _make_series(n_columns=n_columns) y_train, y_test = temporal_train_test_split(y) - f.fit(y_train, fh=fh) - y_pred = f.update_predict_single(y_test, update_params=update_params) - _assert_correct_pred_time_index(y_pred.index, y_test.index[-1], fh) - - -def _check_update_predict_predicted_index( - Forecaster, fh, window_length, step_length, update_params -): - f = Forecaster.create_test_instance() - n_columns_list = _get_n_columns(f.get_tag("scitype:y")) + estimator_instance.fit(y_train, fh=fh_int_oos) + y_pred = estimator_instance.update_predict_single( + y_test, update_params=update_params + ) + _assert_correct_pred_time_index(y_pred.index, y_test.index[-1], fh_int_oos) - for n_columns in n_columns_list: - f = Forecaster.create_test_instance() + @pytest.mark.parametrize( + "fh_int_oos", TEST_OOS_FHS, ids=[f"fh={fh}" for fh in TEST_OOS_FHS] + ) + @pytest.mark.parametrize("window_length", TEST_WINDOW_LENGTHS) + def test_update_predict_predicted_index( + self, + estimator_instance, + n_columns, + fh_int_oos, + window_length, + step_length, + update_params, + ): + """Check predicted index in update_predict.""" y = _make_series(n_columns=n_columns, all_positive=True, index_type="datetime") y_train, y_test = temporal_train_test_split(y) cv = SlidingWindowSplitter( - fh, + fh_int_oos, window_length=window_length, step_length=step_length, start_with_window=False, ) - f.fit(y_train, fh=fh) - y_pred = f.update_predict(y_test, cv=cv, update_params=update_params) + estimator_instance.fit(y_train, fh=fh_int_oos) + y_pred = estimator_instance.update_predict( + y_test, cv=cv, update_params=update_params + ) assert isinstance(y_pred, (pd.Series, pd.DataFrame)) - expected = _get_expected_index_for_update_predict(y_test, fh, step_length) + expected = _get_expected_index_for_update_predict( + y_test, fh_int_oos, step_length + ) actual = y_pred.index np.testing.assert_array_equal(actual, expected) - -# test with update_params=False and different values for steps_length -@pytest.mark.parametrize("Forecaster", FORECASTERS) -@pytest.mark.parametrize("fh", TEST_OOS_FHS) -@pytest.mark.parametrize("window_length", TEST_WINDOW_LENGTHS) -@pytest.mark.parametrize("step_length", TEST_STEP_LENGTHS_INT) -@pytest.mark.parametrize("update_params", [False]) -def test_update_predict_predicted_index( - Forecaster, fh, window_length, step_length, update_params -): - """Check predicted index in update_predict with update_params=False.""" - _check_update_predict_predicted_index( - Forecaster, fh, window_length, step_length, update_params - ) - - -# test with update_params=True and step_length=1 -@pytest.mark.parametrize("Forecaster", FORECASTERS) -@pytest.mark.parametrize("fh", TEST_OOS_FHS) -@pytest.mark.parametrize("window_length", TEST_WINDOW_LENGTHS) -@pytest.mark.parametrize("step_length", [1]) -@pytest.mark.parametrize("update_params", [True]) -def test_update_predict_predicted_index_update_params( - Forecaster, fh, window_length, step_length, update_params -): - """Check predicted index in update_predict with update_params=True.""" - _check_update_predict_predicted_index( - Forecaster, fh, window_length, step_length, update_params - ) - - -# test that _y is updated when forecaster is refitted -@pytest.mark.parametrize("Forecaster", FORECASTERS) -def test__y_when_refitting(Forecaster): - f = Forecaster.create_test_instance() - columns = _get_n_columns(f.get_tag("scitype:y")) - for n_columns in columns: - f = Forecaster.create_test_instance() + def test__y_when_refitting(self, estimator_instance, n_columns): + """Test that _y is updated when forecaster is refitted.""" y_train = _make_series(n_columns=n_columns) - f.fit(y_train, fh=FH0) - f.fit(y_train[3:], fh=FH0) + estimator_instance.fit(y_train, fh=FH0) + estimator_instance.fit(y_train[3:], fh=FH0) # using np.squeeze to make the test flexible to shape differeces like # (50,) and (50, 1) - assert np.all(np.squeeze(f._y) == np.squeeze(y_train[3:])) + assert np.all(np.squeeze(estimator_instance._y) == np.squeeze(y_train[3:])) diff --git a/sktime/forecasting/trend.py b/sktime/forecasting/trend.py index 21ae804a0b7..0218f60649b 100644 --- a/sktime/forecasting/trend.py +++ b/sktime/forecasting/trend.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- # !/usr/bin/env python3 -u # copyright: sktime developers, BSD-3-Clause License (see LICENSE file) -"""Implements trend based forecaster.""" +"""Implements trend based forecasters.""" -__author__ = ["Anthony Jancso", "mloning"] -__all__ = ["TrendForecaster", "PolynomialTrendForecaster"] +__author__ = ["Anthony Jancso", "mloning", "aiwalter"] +__all__ = ["TrendForecaster", "PolynomialTrendForecaster", "STLForecaster"] import numpy as np import pandas as pd @@ -12,9 +12,11 @@ from sklearn.linear_model import LinearRegression from sklearn.pipeline import make_pipeline from sklearn.preprocessing import PolynomialFeatures +from statsmodels.tsa.seasonal import STL as _STL from sktime.forecasting.base import BaseForecaster from sktime.forecasting.base._base import DEFAULT_ALPHA +from sktime.forecasting.naive import NaiveForecaster from sktime.utils.datetime import _get_duration @@ -212,3 +214,282 @@ def _predict(self, fh=None, X=None, return_pred_int=False, alpha=DEFAULT_ALPHA): X_pred = fh.to_numpy().reshape(-1, 1) y_pred = self.regressor_.predict(X_pred) return pd.Series(y_pred, index=self.fh.to_absolute(self.cutoff)) + + +class STLForecaster(BaseForecaster): + """Implements STLForecaster based on statsmodels.tsa.seasonal.STL implementation. + + The STLForecaster is using an STL to decompose the given + series y into the three components trend, season and residuals [1]_. Then, + the forecaster_trend, forecaster_seasonal and forecaster_resid are fitted + on the components individually to forecast them also individually. The + final forecast is then the sum of the three component forecasts. The STL + decomposition is done by means of using the package statsmodels [2]_. + + Parameters + ---------- + sp : int, optional + Length of the seasonal period for STL, by default 2. + It's also the default sp for the forecasters + (forecaster_seasonal, forecaster_resid) that are None. The + default forecaster_trend does not get sp as trend is independent + to seasonality. + seasonal : int, optional + Length of the seasonal smoother. Must be an odd integer, and should + normally be >= 7 (default). + trend : {int, None}, optional + Length of the trend smoother. Must be an odd integer. If not provided + uses the smallest odd integer greater than + 1.5 * period / (1 - 1.5 / seasonal), following the suggestion in + the original implementation. + low_pass : {int, None}, optional + Length of the low-pass filter. Must be an odd integer >=3. If not + provided, uses the smallest odd integer > period. + seasonal_deg : int, optional + Degree of seasonal LOESS. 0 (constant) or 1 (constant and trend). + trend_deg : int, optional + Degree of trend LOESS. 0 (constant) or 1 (constant and trend). + low_pass_deg : int, optional + Degree of low pass LOESS. 0 (constant) or 1 (constant and trend). + robust : bool, optional + Flag indicating whether to use a weighted version that is robust to + some forms of outliers. + seasonal_jump : int, optional + Positive integer determining the linear interpolation step. If larger + than 1, the LOESS is used every seasonal_jump points and linear + interpolation is between fitted points. Higher values reduce + estimation time. + trend_jump : int, optional + Positive integer determining the linear interpolation step. If larger + than 1, the LOESS is used every trend_jump points and values between + the two are linearly interpolated. Higher values reduce estimation + time. + low_pass_jump : int, optional + Positive integer determining the linear interpolation step. If larger + than 1, the LOESS is used every low_pass_jump points and values between + the two are linearly interpolated. Higher values reduce estimation + time. + inner_iter: int, optional + Number of iterations to perform in the inner loop. If not provided uses 2 if + robust is True, or 5 if not. This param goes into STL.fit() from statsmodels. + outer_iter: int, optional + Number of iterations to perform in the outer loop. If not provided uses 15 if + robust is True, or 0 if not. This param goes into STL.fit() from statsmodels. + forecaster_trend : sktime forecaster, optional + Forecaster to be fitted on trend_ component of the + STL, by default None. If None, then + a NaiveForecaster(strategy="drift") is used. + forecaster_seasonal : sktime forecaster, optional + Forecaster to be fitted on seasonal_ component of the + STL, by default None. If None, then + a NaiveForecaster(strategy="last") is used. + forecaster_resid : sktime forecaster, optional + Forecaster to be fitted on resid_ component of the + STL, by default None. If None, then + a NaiveForecaster(strategy="mean") is used. + + Attributes + ---------- + trend_ : pd.Series + Trend component. + seasonal_ : pd.Series + Seasonal component. + resid_ : pd.Series + Residuals component. + forecaster_trend_ : sktime forecaster + Fitted trend forecaster. + forecaster_seasonal_ : sktime forecaster + Fitted seasonal forecaster. + forecaster_resid_ : sktime forecaster + Fitted residual forecaster. + + Examples + -------- + >>> from sktime.datasets import load_airline + >>> from sktime.forecasting.trend import STLForecaster + >>> y = load_airline() + >>> forecaster = STLForecaster(sp=12) + >>> forecaster.fit(y) + STLForecaster(...) + >>> y_pred = forecaster.predict(fh=[1,2,3]) + + See Also + -------- + Deseasonalizer + Detrender + + References + ---------- + .. [1] R. B. Cleveland, W. S. Cleveland, J.E. McRae, and I. Terpenning (1990) + STL: A Seasonal-Trend Decomposition Procedure Based on LOESS. + Journal of Official Statistics, 6, 3-73. + .. [2] https://www.statsmodels.org/dev/generated/statsmodels.tsa.seasonal.STL.html + """ + + _tags = { + "scitype:y": "univariate", # which y are fine? univariate/multivariate/both + "ignores-exogeneous-X": False, # does estimator ignore the exogeneous X? + "handles-missing-data": False, # can estimator handle missing data? + "y_inner_mtype": "pd.Series", # which types do _fit, _predict, assume for y? + "X_inner_mtype": "pd.DataFrame", # which types do _fit, _predict, assume for X? + "requires-fh-in-fit": False, # is forecasting horizon already required in fit? + } + + def __init__( + self, + sp=2, + seasonal=7, + trend=None, + low_pass=None, + seasonal_deg=1, + trend_deg=1, + low_pass_deg=1, + robust=False, + seasonal_jump=1, + trend_jump=1, + low_pass_jump=1, + inner_iter=None, + outer_iter=None, + forecaster_trend=None, + forecaster_seasonal=None, + forecaster_resid=None, + ): + self.sp = sp + self.seasonal = seasonal + self.trend = trend + self.low_pass = low_pass + self.seasonal_deg = seasonal_deg + self.trend_deg = trend_deg + self.low_pass_deg = low_pass_deg + self.robust = robust + self.seasonal_jump = seasonal_jump + self.trend_jump = trend_jump + self.low_pass_jump = low_pass_jump + self.inner_iter = inner_iter + self.outer_iter = outer_iter + self.forecaster_trend = forecaster_trend + self.forecaster_seasonal = forecaster_seasonal + self.forecaster_resid = forecaster_resid + super(STLForecaster, self).__init__() + + def _fit(self, y, X=None, fh=None): + """Fit forecaster to training data. + + Parameters + ---------- + y : pd.Series + Target time series to which to fit the forecaster. + fh : int, list, np.array or ForecastingHorizon, optional (default=None) + The forecasters horizon with the steps ahead to to predict. + X : pd.DataFrame, optional (default=None) + + Returns + ------- + self : returns an instance of self. + """ + self._stl = _STL( + y.values, + period=self.sp, + seasonal=self.seasonal, + trend=self.trend, + low_pass=self.low_pass, + seasonal_deg=self.seasonal_deg, + trend_deg=self.trend_deg, + low_pass_deg=self.low_pass_deg, + robust=self.robust, + seasonal_jump=self.seasonal_jump, + trend_jump=self.trend_jump, + low_pass_jump=self.low_pass_jump, + ).fit(inner_iter=self.inner_iter, outer_iter=self.outer_iter) + + self.seasonal_ = pd.Series(self._stl.seasonal, index=y.index) + self.resid_ = pd.Series(self._stl.resid, index=y.index) + self.trend_ = pd.Series(self._stl.trend, index=y.index) + + self.forecaster_seasonal_ = ( + NaiveForecaster(sp=self.sp, strategy="last") + if self.forecaster_seasonal is None + else clone(self.forecaster_seasonal) + ) + # trend forecaster does not need sp + self.forecaster_trend_ = ( + NaiveForecaster(strategy="drift") + if self.forecaster_trend is None + else clone(self.forecaster_trend) + ) + self.forecaster_resid_ = ( + NaiveForecaster(sp=self.sp, strategy="mean") + if self.forecaster_resid is None + else clone(self.forecaster_resid) + ) + + # fitting forecasters to different components + self.forecaster_seasonal_.fit(y=self.seasonal_, X=X, fh=fh) + self.forecaster_trend_.fit(y=self.trend_, X=X, fh=fh) + self.forecaster_resid_.fit(y=self.resid_, X=X, fh=fh) + + def _predict(self, fh, X=None, return_pred_int=False, alpha=DEFAULT_ALPHA): + """Forecast time series at future horizon. + + Parameters + ---------- + fh : int, list, np.array or ForecastingHorizon + Forecasting horizon + X : pd.DataFrame, optional (default=None) + Exogenous time series + return_pred_int : bool, optional (default=False) + If True, returns prediction intervals for given alpha values. + alpha : float or list, optional (default=0.95) + + Returns + ------- + y_pred : pd.Series + Point predictions + """ + y_pred_seasonal = self.forecaster_seasonal_.predict(fh=fh, X=X) + y_pred_trend = self.forecaster_trend_.predict(fh=fh, X=X) + y_pred_resid = self.forecaster_resid_.predict(fh=fh, X=X) + y_pred = y_pred_seasonal + y_pred_trend + y_pred_resid + return y_pred + + def _update(self, y, X=None, update_params=True): + """Update cutoff value and, optionally, fitted parameters. + + Parameters + ---------- + y : pd.Series, pd.DataFrame, or np.array + Target time series to which to fit the forecaster. + X : pd.DataFrame, optional (default=None) + Exogeneous data + update_params : bool, optional (default=True) + whether model parameters should be updated + + Returns + ------- + self : reference to self + """ + self._stl = _STL( + y.values, + period=self.sp, + seasonal=self.seasonal, + trend=self.trend, + low_pass=self.low_pass, + seasonal_deg=self.seasonal_deg, + trend_deg=self.trend_deg, + low_pass_deg=self.low_pass_deg, + robust=self.robust, + seasonal_jump=self.seasonal_jump, + trend_jump=self.trend_jump, + low_pass_jump=self.low_pass_jump, + ).fit(inner_iter=self.inner_iter, outer_iter=self.outer_iter) + + self.seasonal_ = pd.Series(self._stl.seasonal, index=y.index) + self.resid_ = pd.Series(self._stl.resid, index=y.index) + self.trend_ = pd.Series(self._stl.trend, index=y.index) + + self.forecaster_seasonal_.update( + y=self.seasonal_, X=X, update_params=update_params + ) + self.forecaster_trend_.update(y=self.trend_, X=X, update_params=update_params) + self.forecaster_resid_.update(y=self.resid_, X=X, update_params=update_params) + return self diff --git a/sktime/tests/_config.py b/sktime/tests/_config.py index 4116d5d2d51..e5fb78eeae0 100644 --- a/sktime/tests/_config.py +++ b/sktime/tests/_config.py @@ -4,7 +4,6 @@ __all__ = ["ESTIMATOR_TEST_PARAMS", "EXCLUDE_ESTIMATORS", "EXCLUDED_TESTS"] import numpy as np -from hcrystalball.wrappers import HoltSmoothingWrapper from pyod.models.knn import KNN from sklearn.ensemble import RandomForestClassifier from sklearn.linear_model import LinearRegression @@ -48,37 +47,19 @@ from sktime.classification.kernel_based import Arsenal, RocketClassifier from sktime.classification.shapelet_based import ShapeletTransformClassifier from sktime.contrib.vector_classifiers._rotation_forest import RotationForest -from sktime.dists_kernels.compose_tab_to_panel import AggrDist -from sktime.dists_kernels.scipy_dist import ScipyDist -from sktime.forecasting.arima import AutoARIMA -from sktime.forecasting.bats import BATS from sktime.forecasting.compose import ( - AutoEnsembleForecaster, DirectTabularRegressionForecaster, DirectTimeSeriesRegressionForecaster, DirRecTabularRegressionForecaster, DirRecTimeSeriesRegressionForecaster, - EnsembleForecaster, MultioutputTabularRegressionForecaster, MultioutputTimeSeriesRegressionForecaster, - MultiplexForecaster, RecursiveTabularRegressionForecaster, RecursiveTimeSeriesRegressionForecaster, - StackingForecaster, ) from sktime.forecasting.exp_smoothing import ExponentialSmoothing -from sktime.forecasting.fbprophet import Prophet -from sktime.forecasting.hcrystalball import HCrystalBallForecaster -from sktime.forecasting.model_selection import ( - ForecastingGridSearchCV, - ForecastingRandomizedSearchCV, - SingleWindowSplitter, -) from sktime.forecasting.naive import NaiveForecaster -from sktime.forecasting.online_learning import OnlineEnsembleForecaster from sktime.forecasting.structural import UnobservedComponents -from sktime.forecasting.tbats import TBATS -from sktime.performance_metrics.forecasting import MeanAbsolutePercentageError from sktime.registry import ( BASE_CLASS_LIST, BASE_CLASS_LOOKUP, @@ -116,7 +97,6 @@ # ConditionalDeseasonalizer and STLtransformer still need refactoring # (see PR 1773, blocked through open discussion) escaping until then "ConditionalDeseasonalizer", - "STLforecaster", "STLTransformer", ] @@ -160,7 +140,6 @@ ("forecaster", NaiveForecaster()), ] ESTIMATOR_TEST_PARAMS = { - OnlineEnsembleForecaster: {"forecasters": FORECASTERS}, FeatureUnion: {"transformer_list": TRANSFORMERS}, DirectTabularRegressionForecaster: {"estimator": REGRESSOR}, MultioutputTabularRegressionForecaster: {"estimator": REGRESSOR}, @@ -178,21 +157,6 @@ DirRecTimeSeriesRegressionForecaster: { "estimator": make_pipeline(Tabularizer(), REGRESSOR) }, - EnsembleForecaster: {"forecasters": FORECASTERS}, - StackingForecaster: {"forecasters": FORECASTERS}, - AutoEnsembleForecaster: {"forecasters": FORECASTERS}, - ForecastingGridSearchCV: { - "forecaster": NaiveForecaster(strategy="mean"), - "cv": SingleWindowSplitter(fh=1), - "param_grid": {"window_length": [2, 5]}, - "scoring": MeanAbsolutePercentageError(symmetric=True), - }, - ForecastingRandomizedSearchCV: { - "forecaster": NaiveForecaster(strategy="mean"), - "cv": SingleWindowSplitter(fh=1), - "param_distributions": {"window_length": [2, 5]}, - "scoring": MeanAbsolutePercentageError(symmetric=True), - }, ColumnEnsembleClassifier: { "estimators": [ (name, estimator, 0) for (name, estimator) in TIME_SERIES_CLASSIFIERS @@ -213,21 +177,6 @@ ColumnTransformer: { "transformers": [(name, estimator, [0]) for name, estimator in TRANSFORMERS] }, - AutoARIMA: { - "d": 0, - "suppress_warnings": True, - "max_p": 2, - "max_q": 2, - "seasonal": False, - }, - MultiplexForecaster: { - "forecasters": [ - ("Naive_mean", NaiveForecaster(strategy="mean")), - ("Naive_last", NaiveForecaster(strategy="last")), - ("Naive_drift", NaiveForecaster(strategy="drift")), - ], - "selected_forecaster": "Naive_mean", - }, ShapeletTransformClassifier: { "estimator": RotationForest(n_estimators=3), "max_shapelets": 5, @@ -341,33 +290,7 @@ SupervisedTimeSeriesForest: {"n_estimators": 3}, CanonicalIntervalForest: {"n_estimators": 3}, DrCIF: {"n_estimators": 3}, - HCrystalBallForecaster: {"model": HoltSmoothingWrapper()}, - BATS: { - "use_box_cox": False, - "use_trend": False, - "use_damped_trend": False, - "sp": [], - "use_arma_errors": False, - "n_jobs": 1, - }, - TBATS: { - "use_box_cox": False, - "use_trend": False, - "use_damped_trend": False, - "sp": [], - "use_arma_errors": False, - "n_jobs": 1, - }, - Prophet: { - "n_changepoints": 0, - "yearly_seasonality": False, - "weekly_seasonality": False, - "daily_seasonality": False, - "uncertainty_samples": 1000, - "verbose": False, - }, UnobservedComponents: {"level": "local level"}, - AggrDist: {"transformer": ScipyDist()}, PyODAnnotator: {"estimator": ANOMALY_DETECTOR}, ClaSPSegmentation: {"period_length": 5, "n_cps": 1}, } diff --git a/sktime/tests/test_all_estimators.py b/sktime/tests/test_all_estimators.py index 2d7f6674215..c206f68ea7e 100644 --- a/sktime/tests/test_all_estimators.py +++ b/sktime/tests/test_all_estimators.py @@ -11,7 +11,7 @@ import pickle import types from copy import deepcopy -from inspect import signature +from inspect import getfullargspec, isclass, signature import joblib import numpy as np @@ -53,671 +53,964 @@ ) from sktime.utils._testing.scenarios_getter import retrieve_scenarios -ALL_ESTIMATORS = all_estimators( - return_names=False, exclude_estimators=EXCLUDE_ESTIMATORS -) - - -def is_excluded(test_name, est): - """Shorthand to check whether test test_name is excluded for estimator est.""" - return test_name in EXCLUDED_TESTS.get(est.__name__, []) - - -# the following functions define fixture generation logic used in pytest_generate_tests -# each function is of signature (test_name:str, **kwargs) -> List of fixtures -# function with name _generate_[fixture_var] returns list of values for fixture_var -# where fixture_var is a fixture variable used in tests -# the list is conditional on values of other fixtures which can be passed in kwargs -# -# functions _generate_[fixture_var] are stored in the generator_dict at key fixture_var -# for use by the _conditional_fixture plug-in to pytest_generate_tests - - -generator_dict = dict() - -def _generate_estimator_class(test_name, **kwargs): - """Return estimator class fixtures. +class BaseFixtureGenerator: + """Fixture generator for base testing functionality in sktime. + + Test classes inheriting from this and not overriding pytest_generate_tests + will have estimator and scenario fixtures parameterized out of the box. + + Descendants can override: + estimator_type_filter: str, class variable; None or scitype string + e.g., "forecaster", "transformer", "classifier", see BASE_CLASS_SCITYPE_LIST + which estimators are being retrieved and tested + fixture_sequence: list of str + sequence of fixture variable names in conditional fixture generation + _generate_[variable]: object methods, all (test_name: str, **kwargs) -> list + generating list of fixtures for fixture variable with name [variable] + to be used in test with name test_name + can optionally use values for fixtures earlier in fixture_sequence, + these must be input as kwargs in a call + is_excluded: static method (test_name: str, est: class) -> bool + whether test with name test_name should be excluded for estimator est + should be used only for encoding general rules, not individual skips + individual skips should go on the EXCLUDED_TESTS list in _config + requires _generate_estimator_class and _generate_estimator_instance as is + _excluded_scenario: static method (test_name: str, scenario) -> bool + whether scenario should be skipped in test with test_name test_name + requires _generate_estimator_scenario as is Fixtures parameterized ---------------------- estimator_class: estimator inheriting from BaseObject ranges over all estimator classes not excluded by EXCLUDED_TESTS - """ - estimator_classes_to_test = [ - est for est in ALL_ESTIMATORS if not is_excluded(test_name, est) - ] - estimator_names = [est.__name__ for est in estimator_classes_to_test] - - return estimator_classes_to_test, estimator_names - - -generator_dict["estimator_class"] = _generate_estimator_class - - -def _generate_estimator_instance(test_name, **kwargs): - """Return estimator instance fixtures. - - Fixtures parameterized - ---------------------- estimator_instance: instance of estimator inheriting from BaseObject ranges over all estimator classes not excluded by EXCLUDED_TESTS instances are generated by create_test_instance class method + scenario: instance of TestScenario + ranges over all scenarios returned by retrieve_scenarios """ - # call _generate_estimator_class to get all the classes - estimator_classes_to_test, _ = _generate_estimator_class(test_name=test_name) - - # create instances from the classes - estimator_instances_to_test = [] - estimator_instance_names = [] - # retrieve all estimator parameters if multiple, construct instances - for est in estimator_classes_to_test: - all_instances_of_est, instance_names = est.create_test_instances_and_names() - estimator_instances_to_test += all_instances_of_est - estimator_instance_names += instance_names - return estimator_instances_to_test, estimator_instance_names + # class variables which can be overridden by descendants + # which estimator types are generated; None=all, or scitype string like "forecaster" + estimator_type_filter = None -generator_dict["estimator_instance"] = _generate_estimator_instance + # which sequence the conditional fixtures are generated in + fixture_sequence = ["estimator_class", "estimator_instance", "scenario"] + def pytest_generate_tests(self, metafunc): + """Test parameterization routine for pytest. -def _generate_scenario(test_name, **kwargs): - """Return estimator test scenario. + This uses create_conditional_fixtures_and_names and generator_dict + to create the fixtures for a mark.parameterize decoration of all tests. + """ + # get name of the test + test_name = metafunc.function.__name__ - Fixtures parameterized - ---------------------- - scenario: instance of TestScenario - ranges over all scenarios returned by retrieve_scenarios - """ - if "estimator_class" in kwargs.keys(): - obj = kwargs["estimator_class"] - elif "estimator_instance" in kwargs.keys(): - obj = kwargs["estimator_instance"] - else: - return [] + fixture_sequence = self.fixture_sequence - scenarios = retrieve_scenarios(obj) - scenarios = [s for s in scenarios if not _excluded_scenario(test_name, s)] - scenario_names = [type(scen).__name__ for scen in scenarios] + fixture_vars = getfullargspec(metafunc.function)[0] - return scenarios, scenario_names + ( + fixture_param_str, + fixture_prod, + fixture_names, + ) = create_conditional_fixtures_and_names( + test_name=test_name, + fixture_vars=fixture_vars, + generator_dict=self.generator_dict(), + fixture_sequence=fixture_sequence, + ) + metafunc.parametrize(fixture_param_str, fixture_prod, ids=fixture_names) -def _excluded_scenario(test_name, scenario): - """Skip list generator for scenarios to skip in test_name. + def _all_estimators(self): + """Retrieve list of all estimator classes of type self.estimator_type_filter.""" + return all_estimators( + estimator_types=getattr(self, "estimator_type_filter", None), + return_names=False, + exclude_estimators=EXCLUDE_ESTIMATORS, + ) - Arguments - --------- - test_name : str, name of test - scenario : instance of TestScenario, to be used in test + def generator_dict(self): + """Return dict with methods _generate_[variable] collected in a dict. + + The returned dict is the one required by create_conditional_fixtures_and_names, + used in this _conditional_fixture plug-in to pytest_generate_tests, above. + + Returns + ------- + generator_dict : dict, with keys [variable], where + [variable] are all strings such that self has a static method + named _generate_[variable](test_name: str, **kwargs) + value at [variable] is a reference to _generate_[variable] + """ + gens = [attr for attr in dir(self) if attr.startswith("_generate_")] + vars = [gen.replace("_generate_", "") for gen in gens] + + generator_dict = dict() + for var, gen in zip(vars, gens): + generator_dict[var] = getattr(self, gen) + + return generator_dict + + @staticmethod + def is_excluded(test_name, est): + """Shorthand to check whether test test_name is excluded for estimator est.""" + return test_name in EXCLUDED_TESTS.get(est.__name__, []) + + # the following functions define fixture generation logic for pytest_generate_tests + # each function is of signature (test_name:str, **kwargs) -> List of fixtures + # function with name _generate_[fixture_var] returns list of values for fixture_var + # where fixture_var is a fixture variable used in tests + # the list is conditional on values of other fixtures which can be passed in kwargs + + def _generate_estimator_class(self, test_name, **kwargs): + """Return estimator class fixtures. + + Fixtures parameterized + ---------------------- + estimator_class: estimator inheriting from BaseObject + ranges over all estimator classes not excluded by EXCLUDED_TESTS + """ + estimator_classes_to_test = [ + est + for est in self._all_estimators() + if not self.is_excluded(test_name, est) + ] + estimator_names = [est.__name__ for est in estimator_classes_to_test] + + return estimator_classes_to_test, estimator_names + + def _generate_estimator_instance(self, test_name, **kwargs): + """Return estimator instance fixtures. + + Fixtures parameterized + ---------------------- + estimator_instance: instance of estimator inheriting from BaseObject + ranges over all estimator classes not excluded by EXCLUDED_TESTS + instances are generated by create_test_instance class method + """ + # call _generate_estimator_class to get all the classes + estimator_classes_to_test, _ = self._generate_estimator_class( + test_name=test_name + ) - Returns - ------- - bool, whether scenario should be skipped in test_name - """ - # for forecasters tested in test_methods_do_not_change_state - # if fh is not passed in fit, then this test would fail - # since fh will be stored in predict through fh handling - # as there are scenarios which pass it early and everything else is the same - # we skip those scenarios - if test_name == "test_methods_do_not_change_state": - if not scenario.get_tag("fh_passed_in_fit", True, raise_error=False): + # create instances from the classes + estimator_instances_to_test = [] + estimator_instance_names = [] + # retrieve all estimator parameters if multiple, construct instances + for est in estimator_classes_to_test: + all_instances_of_est, instance_names = est.create_test_instances_and_names() + estimator_instances_to_test += all_instances_of_est + estimator_instance_names += instance_names + + return estimator_instances_to_test, estimator_instance_names + + def _generate_scenario(self, test_name, **kwargs): + """Return estimator test scenario. + + Fixtures parameterized + ---------------------- + scenario: instance of TestScenario + ranges over all scenarios returned by retrieve_scenarios + """ + if "estimator_class" in kwargs.keys(): + obj = kwargs["estimator_class"] + elif "estimator_instance" in kwargs.keys(): + obj = kwargs["estimator_instance"] + else: + return [] + + scenarios = retrieve_scenarios(obj) + scenarios = [s for s in scenarios if not self._excluded_scenario(test_name, s)] + scenario_names = [type(scen).__name__ for scen in scenarios] + + return scenarios, scenario_names + + @staticmethod + def _excluded_scenario(test_name, scenario): + """Skip list generator for scenarios to skip in test_name. + + Arguments + --------- + test_name : str, name of test + scenario : instance of TestScenario, to be used in test + + Returns + ------- + bool, whether scenario should be skipped in test_name + """ + # for forecasters tested in test_methods_do_not_change_state + # if fh is not passed in fit, then this test would fail + # since fh will be stored in predict through fh handling + # as there are scenarios which pass it early and everything else is the same + # we skip those scenarios + if test_name == "test_methods_do_not_change_state": + if not scenario.get_tag("fh_passed_in_fit", True, raise_error=False): + return True + + # this line excludes all scenarios that are not 1:1 to the "pre-scenario" state + # pre-refactor, all tests pass, so all post-refactor tests should with below + # comment out to run the full test suite with new scenarios + if not scenario.get_tag("pre-refactor", False, raise_error=False): return True - # this line excludes all scenarios that are not 1:1 to the "pre-scenario" state - # pre-refactor, all tests pass, so all post-refactor tests should with these lines - # comment out to run the full test suite with new scenarios - if not scenario.get_tag("pre-refactor", False, raise_error=False): - return True + return False + + +class QuickTester: + """Mixin class which adds the run_tests method to run tests on one estimator.""" + + def run_tests( + self, estimator, return_exceptions=True, tests_to_run=None, fixtures_to_run=None + ): + """Run all tests on one single estimator. + + All tests in self are run on the following estimator type fixtures: + if est is a class, then estimator_class = est, and + estimator_instance loops over est.create_test_instance() + if est is an object, then estimator_class = est.__class__, and + estimator_instance = est + + This is compatible with pytest.mark.parametrize decoration, + but currently only with multiple *single variable* annotations. + + Parameters + ---------- + estimator : estimator class or estimator instance + return_exception : bool, optional, default=True + whether to return exceptions/failures, or raise them + if True: returns exceptions in results + if False: raises exceptions as they occur + tests_to_run : str or list of str, names of tests to run. default = all tests + sub-sets tests that are run to the tests given here. + fixtures_to_run : str or list of str, pytest test-fixture combination codes. + which test-fixture combinations to run. Default = run all of them. + sub-sets tests and fixtures to run to the list given here. + If both tests_to_run and fixtures_to_run are provided, runs the *union*, + i.e., all test-fixture combinations for tests in tests_to_run, + plus all test-fixture combinations in fixtures_to_run. + + Returns + ------- + results : dict of results of the tests in self + keys are test/fixture strings, identical as in pytest, e.g., test[fixture] + entries are the string "PASSED" if the test passed, + or the exception raised if the test did not pass + returned only if all tests pass, or return_exceptions=True + + Raises + ------ + if return_exception=False, raises any exception produced by the tests directly + + Examples + -------- + >>> from sktime.forecasting.naive import NaiveForecaster + >>> from sktime.tests.test_all_estimators import TestAllEstimators + >>> TestAllEstimators().run_tests( + ... NaiveForecaster, + ... tests_to_run="test_required_params" + ... ) + {'test_required_params[NaiveForecaster]': 'PASSED'} + >>> TestAllEstimators().run_tests( + ... NaiveForecaster, fixtures_to_run="test_repr[NaiveForecaster-2]" + ... ) + {'test_repr[NaiveForecaster-2]': 'PASSED'} + """ + tests_to_run = self._check_None_str_or_list_of_str( + tests_to_run, var_name="tests_to_run" + ) + fixtures_to_run = self._check_None_str_or_list_of_str( + fixtures_to_run, var_name="fixtures_to_run" + ) - return False + # retrieve tests from self + test_names = [attr for attr in dir(self) if attr.startswith("test")] + # we override the generator_dict, by replacing it with temp_generator_dict: + # the only estimator (class or instance) is est, this is overridden + # the remaining fixtures are generated conditionally, without change + temp_generator_dict = deepcopy(self.generator_dict()) -generator_dict["scenario"] = _generate_scenario + if isclass(estimator): + estimator_class = estimator + else: + estimator_class = type(estimator) + def _generate_estimator_class(test_name, **kwargs): + return [estimator_class], [estimator_class.__name__] -# pytest_generate_tests uses create_conditional_fixtures_and_names and generator_dict -# to create the fixtures for a parameterize decoration of all tests + def _generate_estimator_instance(test_name, **kwargs): + return [estimator], [estimator_class.__name__] + def _generate_estimator_instance_cls(test_name, **kwargs): + return estimator_class.create_test_instances_and_names() -def pytest_generate_tests(metafunc): - """Test parameterization routine for pytest. + temp_generator_dict["estimator_class"] = _generate_estimator_class - Fixtures parameterized - ---------------------- - estimator_class: estimator inheriting from BaseObject - ranges over all estimator classes not excluded by EXCLUDED_TESTS - estimator_instance: instance of estimator inheriting from BaseObject - ranges over all estimator classes not excluded by EXCLUDED_TESTS - instances are generated by create_test_instance class method - scenario: instance of TestScenario - ranges over all scenarios returned by retrieve_scenarios - """ - # get name of the test - test_name = metafunc.function.__name__ + if not isclass(estimator): + temp_generator_dict["estimator_instance"] = _generate_estimator_instance + else: + temp_generator_dict["estimator_instance"] = _generate_estimator_instance_cls + # override of generator_dict end, temp_generator_dict is now prepared - fixture_sequence = ["estimator_class", "estimator_instance", "scenario"] + # sub-setting to specific tests to run, if tests or fixtures were speified + if tests_to_run is None and fixtures_to_run is None: + test_names_subset = test_names + else: + test_names_subset = [] + if tests_to_run is not None: + test_names_subset += list(set(test_names).intersection(tests_to_run)) + if fixtures_to_run is not None: + # fixture codes contain the test as substring until the first "[" + tests_from_fixt = [fixt.split("[")[0] for fixt in fixtures_to_run] + test_names_subset += list(set(test_names).intersection(tests_from_fixt)) + test_names_subset = list(set(test_names_subset)) + + # the below loops run all the tests and collect the results here: + results = dict() + # loop A: we loop over all the tests + for test_name in test_names_subset: + + test_fun = getattr(self, test_name) + fixture_sequence = self.fixture_sequence + + # all arguments except the first one (self) + fixture_vars = getfullargspec(test_fun)[0][1:] + fixture_vars = [var for var in fixture_sequence if var in fixture_vars] + + # this call retrieves the conditional fixtures + # for the test test_name, and the estimator + _, fixture_prod, fixture_names = create_conditional_fixtures_and_names( + test_name=test_name, + fixture_vars=fixture_vars, + generator_dict=temp_generator_dict, + fixture_sequence=fixture_sequence, + ) - ( - fixture_param_str, + # if function is decorated with mark.parameterize, add variable settings + # NOTE: currently this works only with single-variable mark.parameterize + if hasattr(test_fun, "pytestmark"): + if len([x for x in test_fun.pytestmark if x.name == "parametrize"]) > 0: + # get the three lists from pytest + ( + pytest_fixture_vars, + pytest_fixture_prod, + pytest_fixture_names, + ) = self._get_pytest_mark_args(test_fun) + # add them to the three lists from conditional fixtures + fixture_vars, fixture_prod, fixture_names = self._product_fixtures( + fixture_vars, + fixture_prod, + fixture_names, + pytest_fixture_vars, + pytest_fixture_prod, + pytest_fixture_names, + ) + + # loop B: for each test, we loop over all fixtures + for params, fixt_name in zip(fixture_prod, fixture_names): + + # this is needed because pytest unwraps 1-tuples automatically + # but subsequent code assumes params is k-tuple, no matter what k is + if len(fixture_vars) == 1: + params = (params,) + key = f"{test_name}[{fixt_name}]" + args = dict(zip(fixture_vars, params)) + + # we subset to test-fixtures to run by this, if given + # key is identical to the pytest test-fixture string identifier + if fixtures_to_run is not None and key not in fixtures_to_run: + continue + + if return_exceptions: + try: + test_fun(**args) + results[key] = "PASSED" + except Exception as err: + results[key] = err + else: + test_fun(**args) + results[key] = "PASSED" + + return results + + @staticmethod + def _check_None_str_or_list_of_str(obj, var_name="obj"): + """Check that obj is None, str, or list of str, and coerce to list of str.""" + if obj is not None: + msg = f"{var_name} must be None, str, or list of str" + if isinstance(obj, str): + obj = [obj] + if not isinstance(obj, list): + raise ValueError(msg) + if not np.all(isinstance(x, str) for x in 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. + + Parameters + ---------- + fun: callable, any function + + Returns + ------- + pytest_fixture_vars: list of str + names of args participating in mark.parameterize marks, in pytest order + pytest_fixt_list: list of tuple + list of value tuples from the mark parameterization + i-th value in each tuple corresponds to i-th arg name in pytest_fixture_vars + pytest_fixt_names: list of str + i-th element is display name for i-th fixture setting in pytest_fixt_list + """ + from itertools import product + + marks = [x for x in fun.pytestmark if x.name == "parametrize"] + + def to_str(obj): + return [str(x) for x in obj] + + pytest_fixture_vars = [x.args[0] for x in marks] + pytest_fixt_raw = [x.args[1] for x in marks] + pytest_fixt_list = product(*pytest_fixt_raw) + pytest_fixt_names_raw = [to_str(range(len(x.args[1]))) for x in marks] + pytest_fixt_names = product(*pytest_fixt_names_raw) + pytest_fixt_names = ["-".join(x) for x in pytest_fixt_names] + + return pytest_fixture_vars, pytest_fixt_list, pytest_fixt_names + + @staticmethod + def _product_fixtures( + fixture_vars, fixture_prod, fixture_names, - ) = create_conditional_fixtures_and_names( - test_name=test_name, - fixture_vars=metafunc.fixturenames, - generator_dict=generator_dict, - fixture_sequence=fixture_sequence, - ) - - metafunc.parametrize(fixture_param_str, fixture_prod, ids=fixture_names) - - -def test_create_test_instance(estimator_class): - """Check first that create_test_instance logic works.""" - estimator = estimator_class.create_test_instance() - - # Check that init does not construct object of other class than itself - assert isinstance(estimator, estimator_class), ( - "object returned by create_test_instance must be an instance of the class, " - f"found {type(estimator)}" - ) - - -def test_create_test_instances_and_names(estimator_class): - """Check that create_test_instances_and_names works.""" - estimators, names = estimator_class.create_test_instances_and_names() - - assert isinstance(estimators, list), ( - "first return of create_test_instances_and_names must be a list, " - f"found {type(estimators)}" - ) - assert isinstance(names, list), ( - "second return of create_test_instances_and_names must be a list, " - f"found {type(names)}" - ) - - assert np.all(isinstance(est, estimator_class) for est in estimators), ( - "list elements of first return returned by create_test_instances_and_names " - "all must be an instance of the class" - ) - - assert np.all(isinstance(name, names) for name in names), ( - "list elements of second return returned by create_test_instances_and_names " - "all must be strings" - ) - - assert len(estimators) == len(names), ( - "the two lists returned by create_test_instances_and_names must have " - "equal length" - ) - - -def test_required_params(estimator_class): - """Check required parameter interface.""" - Estimator = estimator_class - # Check common meta-estimator interface - if hasattr(Estimator, "_required_parameters"): - required_params = Estimator._required_parameters - - assert isinstance(required_params, list), ( - f"For estimator: {Estimator}, `_required_parameters` must be a " - f"tuple, but found type: {type(required_params)}" - ) + pytest_fixture_vars, + pytest_fixture_prod, + pytest_fixture_names, + ): + """Compute products of two sets of fixture vars, values, names.""" + from itertools import product - assert all([isinstance(param, str) for param in required_params]), ( - f"For estimator: {Estimator}, elements of `_required_parameters` " - f"list must be strings" - ) + # product of fixture variable names = concatenation + fixture_vars_return = fixture_vars + pytest_fixture_vars - # check if needless parameters are in _required_parameters - init_params = [ - param.name for param in signature(Estimator.__init__).parameters.values() - ] - in_required_but_not_init = [ - param for param in required_params if param not in init_params - ] - if len(in_required_but_not_init) > 0: - raise ValueError( - f"Found parameters in `_required_parameters` which " - f"are not in `__init__`: " - f"{in_required_but_not_init}" - ) + # this is needed because pytest unwraps 1-tuples automatically + # but subsequent code assumes params is k-tuple, no matter what k is + if len(fixture_vars) == 1: + fixture_prod = [(x,) for x in fixture_prod] + # product of fixture products = Cartesian product plus append tuples + fixture_prod_return = product(fixture_prod, pytest_fixture_prod) + fixture_prod_return = [sum(x, ()) for x in fixture_prod_return] -def test_estimator_tags(estimator_class): - """Check conventions on estimator tags.""" - Estimator = estimator_class - - assert hasattr(Estimator, "get_class_tags") - all_tags = Estimator.get_class_tags() - assert isinstance(all_tags, dict) - assert all(isinstance(key, str) for key in all_tags.keys()) - if hasattr(Estimator, "_tags"): - tags = Estimator._tags - assert isinstance(tags, dict), f"_tags must be a dict, but found {type(tags)}" - assert len(tags) > 0, "_tags is empty" - assert all( - tag in VALID_ESTIMATOR_TAGS for tag in tags.keys() - ), "Some tags in _tags are invalid" - - # Avoid ambiguous class attributes - ambiguous_attrs = ("tags", "tags_") - for attr in ambiguous_attrs: - assert not hasattr(Estimator, attr), ( - f"Please avoid using the {attr} attribute to disambiguate it from " - f"estimator tags." - ) + # product of fixture names = Cartesian product plus concat + fixture_names_return = product(fixture_names, pytest_fixture_names) + fixture_names_return = [".".join(x) for x in fixture_names_return] + return fixture_vars_return, fixture_prod_return, fixture_names_return -def test_inheritance(estimator_class): - """Check that estimator inherits from BaseEstimator.""" - assert issubclass(estimator_class, BaseEstimator), ( - f"Estimator: {estimator_class} " f"is not a sub-class of " f"BaseEstimator." - ) - Estimator = estimator_class - # Usually estimators inherit only from one BaseEstimator type, but in some cases - # they may be predictor and transformer at the same time (e.g. pipelines) - n_base_types = sum(issubclass(Estimator, cls) for cls in VALID_ESTIMATOR_BASE_TYPES) - assert 2 >= n_base_types >= 1 +class TestAllEstimators(BaseFixtureGenerator, QuickTester): + """Package level tests for all sktime estimators.""" - # If the estimator inherits from more than one base estimator type, we check if - # one of them is a transformer base type - if n_base_types > 1: - assert issubclass(Estimator, VALID_TRANSFORMER_TYPES) + def test_create_test_instance(self, estimator_class): + """Check first that create_test_instance logic works.""" + estimator = estimator_class.create_test_instance() + # Check that init does not construct object of other class than itself + assert isinstance(estimator, estimator_class), ( + "object returned by create_test_instance must be an instance of the class, " + f"found {type(estimator)}" + ) -def test_has_common_interface(estimator_class): - """Check estimator implements the common interface.""" - estimator = estimator_class - - # Check class for type of attribute - assert isinstance(estimator.is_fitted, property) - - required_methods = _list_required_methods(estimator_class) - - for attr in required_methods: - assert hasattr( - estimator, attr - ), f"Estimator: {estimator.__name__} does not implement attribute: {attr}" - - if hasattr(estimator, "inverse_transform"): - assert hasattr(estimator, "transform") - if hasattr(estimator, "predict_proba"): - assert hasattr(estimator, "predict") - + def test_create_test_instances_and_names(self, estimator_class): + """Check that create_test_instances_and_names works.""" + estimators, names = estimator_class.create_test_instances_and_names() -def test_get_params(estimator_instance): - """Check that get_params works correctly.""" - estimator = estimator_instance - params = estimator.get_params() - assert isinstance(params, dict) - _check_get_params_invariance(estimator.__class__.__name__, estimator) + assert isinstance(estimators, list), ( + "first return of create_test_instances_and_names must be a list, " + f"found {type(estimators)}" + ) + assert isinstance(names, list), ( + "second return of create_test_instances_and_names must be a list, " + f"found {type(names)}" + ) + assert np.all(isinstance(est, estimator_class) for est in estimators), ( + "list elements of first return returned by create_test_instances_and_names " + "all must be an instance of the class" + ) -def test_set_params(estimator_instance): - """Check that set_params works correctly.""" - estimator = estimator_instance - params = estimator.get_params() - assert estimator.set_params(**params) is estimator - _check_set_params(estimator.__class__.__name__, estimator) + assert np.all(isinstance(name, names) for name in names), ( + "list elements of second return returned by create_test_instances_and_names" + " all must be strings" + ) + assert len(estimators) == len(names), ( + "the two lists returned by create_test_instances_and_names must have " + "equal length" + ) -def test_clone(estimator_instance): - """Check we can call clone from scikit-learn.""" - estimator = estimator_instance - clone(estimator) + def test_required_params(self, estimator_class): + """Check required parameter interface.""" + Estimator = estimator_class + # Check common meta-estimator interface + if hasattr(Estimator, "_required_parameters"): + required_params = Estimator._required_parameters + assert isinstance(required_params, list), ( + f"For estimator: {Estimator}, `_required_parameters` must be a " + f"tuple, but found type: {type(required_params)}" + ) -def test_repr(estimator_instance): - """Check we can call repr.""" - estimator = estimator_instance - repr(estimator) + assert all([isinstance(param, str) for param in required_params]), ( + f"For estimator: {Estimator}, elements of `_required_parameters` " + f"list must be strings" + ) + # check if needless parameters are in _required_parameters + init_params = [ + par.name for par in signature(Estimator.__init__).parameters.values() + ] + in_required_but_not_init = [ + param for param in required_params if param not in init_params + ] + if len(in_required_but_not_init) > 0: + raise ValueError( + f"Found parameters in `_required_parameters` which " + f"are not in `__init__`: " + f"{in_required_but_not_init}" + ) -def check_constructor(estimator_class): - """Check that the constructor behaves correctly.""" - estimator = estimator_class.create_test_instance() + def test_estimator_tags(self, estimator_class): + """Check conventions on estimator tags.""" + Estimator = estimator_class + + assert hasattr(Estimator, "get_class_tags") + all_tags = Estimator.get_class_tags() + assert isinstance(all_tags, dict) + assert all(isinstance(key, str) for key in all_tags.keys()) + if hasattr(Estimator, "_tags"): + tags = Estimator._tags + msg = f"_tags must be a dict, but found {type(tags)}" + assert isinstance(tags, dict), msg + assert len(tags) > 0, "_tags is empty" + assert all( + tag in VALID_ESTIMATOR_TAGS for tag in tags.keys() + ), "Some tags in _tags are invalid" + + # Avoid ambiguous class attributes + ambiguous_attrs = ("tags", "tags_") + for attr in ambiguous_attrs: + assert not hasattr(Estimator, attr), ( + f"Please avoid using the {attr} attribute to disambiguate it from " + f"estimator tags." + ) - # Ensure that each parameter is set in init - init_params = _get_args(type(estimator).__init__) - invalid_attr = set(init_params) - set(vars(estimator)) - {"self"} - assert not invalid_attr, ( - "Estimator %s should store all parameters" - " as an attribute during init. Did not find " - "attributes `%s`." % (estimator.__class__.__name__, sorted(invalid_attr)) - ) + def test_inheritance(self, estimator_class): + """Check that estimator inherits from BaseEstimator.""" + assert issubclass(estimator_class, BaseEstimator), ( + f"Estimator: {estimator_class} " f"is not a sub-class of " f"BaseEstimator." + ) + Estimator = estimator_class + # Usually estimators inherit only from one BaseEstimator type, but in some cases + # they may be predictor and transformer at the same time (e.g. pipelines) + n_base_types = sum( + issubclass(Estimator, cls) for cls in VALID_ESTIMATOR_BASE_TYPES + ) - # Ensure that init does nothing but set parameters - # No logic/interaction with other parameters - def param_filter(p): - """Identify hyper parameters of an estimator.""" - return ( - p.name != "self" and p.kind != p.VAR_KEYWORD and p.kind != p.VAR_POSITIONAL + assert 2 >= n_base_types >= 1 + + # If the estimator inherits from more than one base estimator type, we check if + # one of them is a transformer base type + if n_base_types > 1: + assert issubclass(Estimator, VALID_TRANSFORMER_TYPES) + + def test_has_common_interface(self, estimator_class): + """Check estimator implements the common interface.""" + estimator = estimator_class + + # Check class for type of attribute + assert isinstance(estimator.is_fitted, property) + + required_methods = _list_required_methods(estimator_class) + + for attr in required_methods: + assert hasattr( + estimator, attr + ), f"Estimator: {estimator.__name__} does not implement attribute: {attr}" + + if hasattr(estimator, "inverse_transform"): + assert hasattr(estimator, "transform") + if hasattr(estimator, "predict_proba"): + assert hasattr(estimator, "predict") + + def test_get_params(self, estimator_instance): + """Check that get_params works correctly.""" + estimator = estimator_instance + params = estimator.get_params() + assert isinstance(params, dict) + _check_get_params_invariance(estimator.__class__.__name__, estimator) + + def test_set_params(self, estimator_instance): + """Check that set_params works correctly.""" + estimator = estimator_instance + params = estimator.get_params() + assert estimator.set_params(**params) is estimator + _check_set_params(estimator.__class__.__name__, estimator) + + def test_clone(self, estimator_instance): + """Check we can call clone from scikit-learn.""" + estimator = estimator_instance + clone(estimator) + + def test_repr(self, estimator_instance): + """Check we can call repr.""" + estimator = estimator_instance + repr(estimator) + + def check_constructor(self, estimator_class): + """Check that the constructor behaves correctly.""" + estimator = estimator_class.create_test_instance() + + # Ensure that each parameter is set in init + init_params = _get_args(type(estimator).__init__) + invalid_attr = set(init_params) - set(vars(estimator)) - {"self"} + assert not invalid_attr, ( + "Estimator %s should store all parameters" + " as an attribute during init. Did not find " + "attributes `%s`." % (estimator.__class__.__name__, sorted(invalid_attr)) ) - init_params = [ - p for p in signature(estimator.__init__).parameters.values() if param_filter(p) - ] + # Ensure that init does nothing but set parameters + # No logic/interaction with other parameters + def param_filter(p): + """Identify hyper parameters of an estimator.""" + return p.name != "self" and p.kind not in [p.VAR_KEYWORD, p.VAR_POSITIONAL] - params = estimator.get_params() + init_params = [ + p + for p in signature(estimator.__init__).parameters.values() + if param_filter(p) + ] - # Filter out required parameters with no default value and parameters - # set for running tests - required_params = getattr(estimator, "_required_parameters", tuple()) + params = estimator.get_params() - test_params = estimator_class.get_test_params() - if isinstance(test_params, list): - test_params = test_params[0] - test_params = test_params.keys() + # Filter out required parameters with no default value and parameters + # set for running tests + required_params = getattr(estimator, "_required_parameters", tuple()) - init_params = [ - param - for param in init_params - if param.name not in required_params and param.name not in test_params - ] + test_params = estimator_class.get_test_params() + if isinstance(test_params, list): + test_params = test_params[0] + test_params = test_params.keys() - for param in init_params: - assert param.default != param.empty, ( - "parameter `%s` for %s has no default value and is not " - "included in `_required_parameters`" - % (param.name, estimator.__class__.__name__) - ) - if type(param.default) is type: - assert param.default in [np.float64, np.int64] - else: - assert type(param.default) in [ - str, - int, - float, - bool, - tuple, - type(None), - np.float64, - types.FunctionType, - joblib.Memory, - ] + init_params = [ + param + for param in init_params + if param.name not in required_params and param.name not in test_params + ] - param_value = params[param.name] - if isinstance(param_value, np.ndarray): - np.testing.assert_array_equal(param_value, param.default) - else: - if bool(isinstance(param_value, numbers.Real) and np.isnan(param_value)): - # Allows to set default parameters to np.nan - assert param_value is param.default, param.name - else: - assert param_value == param.default, param.name - - -def test_fit_updates_state(estimator_instance, scenario): - """Check fit/update state change.""" - # Check that fit updates the is-fitted states - attrs = ["_is_fitted", "is_fitted"] - - estimator = estimator_instance - - assert hasattr( - estimator, "_is_fitted" - ), f"Estimator: {estimator.__name__} does not set_is_fitted in construction" - - # Check is_fitted attribute is set correctly to False before fit, at construction - for attr in attrs: - assert not getattr( - estimator, attr - ), f"Estimator: {estimator} does not initiate attribute: {attr} to False" - - fitted_estimator = scenario.run(estimator_instance, method_sequence=["fit"]) - - # Check 0s_fitted attribute is updated correctly to False after calling fit - for attr in attrs: - assert getattr( - fitted_estimator, attr - ), f"Estimator: {estimator} does not update attribute: {attr} during fit" - - -def test_fit_returns_self(estimator_instance, scenario): - """Check that fit returns self.""" - fit_return = scenario.run(estimator_instance, method_sequence=["fit"]) - assert ( - fit_return is estimator_instance - ), f"Estimator: {estimator_instance} does not return self when calling fit" - - -def test_raises_not_fitted_error(estimator_instance, scenario): - """Check that we raise appropriate error for unfitted estimators.""" - # pairwise transformers are exempted from this test, since they have no fitting - PWTRAFOS = (BasePairwiseTransformer, BasePairwiseTransformerPanel) - excepted = isinstance(estimator_instance, PWTRAFOS) - if excepted: - return None - - # call methods without prior fitting and check that they raise our - # NotFittedError - for method in NON_STATE_CHANGING_METHODS: - if _has_capability(estimator_instance, method): - with pytest.raises(NotFittedError, match=r"has not been fitted"): - scenario.run(estimator_instance, method_sequence=[method]) - - -def test_fit_idempotent(estimator_instance, scenario): - """Check that calling fit twice is equivalent to calling it once.""" - estimator = estimator_instance - - # todo: may have to rework this, due to "if estimator has param" - for method in NON_STATE_CHANGING_METHODS: - if _has_capability(estimator, method): - set_random_state(estimator) - results = scenario.run( - estimator, - method_sequence=["fit", method], - return_all=True, - deepcopy_return=True, + for param in init_params: + assert param.default != param.empty, ( + "parameter `%s` for %s has no default value and is not " + "included in `_required_parameters`" + % (param.name, estimator.__class__.__name__) ) + if type(param.default) is type: + assert param.default in [np.float64, np.int64] + else: + assert type(param.default) in [ + str, + int, + float, + bool, + tuple, + type(None), + np.float64, + types.FunctionType, + joblib.Memory, + ] + + param_value = params[param.name] + if isinstance(param_value, np.ndarray): + np.testing.assert_array_equal(param_value, param.default) + else: + if bool( + isinstance(param_value, numbers.Real) and np.isnan(param_value) + ): + # Allows to set default parameters to np.nan + assert param_value is param.default, param.name + else: + assert param_value == param.default, param.name - estimator = results[0] - set_random_state(estimator) + def test_fit_updates_state(self, estimator_instance, scenario): + """Check fit/update state change.""" + # Check that fit updates the is-fitted states + attrs = ["_is_fitted", "is_fitted"] - results_2nd = scenario.run( - estimator, - method_sequence=["fit", method], - return_all=True, - deepcopy_return=True, - ) + estimator = estimator_instance - _assert_array_almost_equal( - results[1], - results_2nd[1], - # err_msg=f"Idempotency check failed for method {method}", - ) + assert hasattr( + estimator, "_is_fitted" + ), f"Estimator: {estimator.__name__} does not set_is_fitted in construction" + + # Check is_fitted attribute is set correctly to False before fit, at init + for attr in attrs: + assert not getattr( + estimator, attr + ), f"Estimator: {estimator} does not initiate attribute: {attr} to False" + + fitted_estimator = scenario.run(estimator_instance, method_sequence=["fit"]) + + # Check 0s_fitted attribute is updated correctly to False after calling fit + for attr in attrs: + assert getattr( + fitted_estimator, attr + ), f"Estimator: {estimator} does not update attribute: {attr} during fit" + + def test_fit_returns_self(self, estimator_instance, scenario): + """Check that fit returns self.""" + fit_return = scenario.run(estimator_instance, method_sequence=["fit"]) + assert ( + fit_return is estimator_instance + ), f"Estimator: {estimator_instance} does not return self when calling fit" + + def test_raises_not_fitted_error(self, estimator_instance, scenario): + """Check that we raise appropriate error for unfitted estimators.""" + # pairwise transformers are exempted from this test, since they have no fitting + PWTRAFOS = (BasePairwiseTransformer, BasePairwiseTransformerPanel) + excepted = isinstance(estimator_instance, PWTRAFOS) + if excepted: + return None + + # call methods without prior fitting and check that they raise our + # NotFittedError + for method in NON_STATE_CHANGING_METHODS: + if _has_capability(estimator_instance, method): + with pytest.raises(NotFittedError, match=r"has not been fitted"): + scenario.run(estimator_instance, method_sequence=[method]) + def test_fit_idempotent(self, estimator_instance, scenario): + """Check that calling fit twice is equivalent to calling it once.""" + estimator = estimator_instance -def test_fit_does_not_overwrite_hyper_params(estimator_instance, scenario): - """Check that we do not overwrite hyper-parameters in fit.""" - estimator = estimator_instance - set_random_state(estimator) - - # Make a physical copy of the original estimator parameters before fitting. - params = estimator.get_params() - original_params = deepcopy(params) - - # Fit the model - fitted_est = scenario.run(estimator_instance, method_sequence=["fit"]) - - # Compare the state of the model parameters with the original parameters - new_params = fitted_est.get_params() - for param_name, original_value in original_params.items(): - new_value = new_params[param_name] - - # We should never change or mutate the internal state of input - # parameters by default. To check this we use the joblib.hash function - # that introspects recursively any subobjects to compute a checksum. - # The only exception to this rule of immutable constructor parameters - # is possible RandomState instance but in this check we explicitly - # fixed the random_state params recursively to be integer seeds. - assert joblib.hash(new_value) == joblib.hash(original_value), ( - "Estimator %s should not change or mutate " - " the parameter %s from %s to %s during fit." - % (estimator.__class__.__name__, param_name, original_value, new_value) - ) + # todo: may have to rework this, due to "if estimator has param" + for method in NON_STATE_CHANGING_METHODS: + if _has_capability(estimator, method): + set_random_state(estimator) + results = scenario.run( + estimator, + method_sequence=["fit", method], + return_all=True, + deepcopy_return=True, + ) + estimator = results[0] + set_random_state(estimator) -def test_methods_do_not_change_state(estimator_instance, scenario): - """Check that non-state-changing methods do not change state. + results_2nd = scenario.run( + estimator, + method_sequence=["fit", method], + return_all=True, + deepcopy_return=True, + ) - Check that methods that are not supposed to change attributes of the - estimators do not change anything (including hyper-parameters and - fitted parameters) - """ - estimator = estimator_instance - set_random_state(estimator) - - for method in NON_STATE_CHANGING_METHODS: - if _has_capability(estimator, method): - - # dict_before = copy of dictionary of estimator before predict, after fit - _ = scenario.run(estimator, method_sequence=["fit"]) - dict_before = estimator.__dict__.copy() - - # dict_after = dictionary of estimator after predict and fit - _ = scenario.run(estimator, method_sequence=[method]) - dict_after = estimator.__dict__ - - if method == "transform" and estimator.get_class_tag("fit-in-transform"): - # Some transformations fit during transform, as they apply - # some transformation to each series passed to transform, - # so transform will actually change the state of these estimator. - continue - - if method == "predict" and estimator.get_class_tag("fit-in-predict"): - # Some annotators fit during predict, as they apply - # some apply annotation to each series passed to predict, - # so predict will actually change the state of these annotators. - continue - - # old logic uses equality without auto-msg, keep comment until refactor - # is_equal = dict_after == dict_before - is_equal, msg = deep_equals(dict_after, dict_before, return_msg=True) - assert is_equal, ( - f"Estimator: {type(estimator).__name__} changes __dict__ " - f"during {method}, " - f"reason/location of discrepancy (x=after, y=before): {msg}" + _assert_array_almost_equal( + results[1], + results_2nd[1], + # err_msg=f"Idempotency check failed for method {method}", + ) + + def test_fit_does_not_overwrite_hyper_params(self, estimator_instance, scenario): + """Check that we do not overwrite hyper-parameters in fit.""" + estimator = estimator_instance + set_random_state(estimator) + + # Make a physical copy of the original estimator parameters before fitting. + params = estimator.get_params() + original_params = deepcopy(params) + + # Fit the model + fitted_est = scenario.run(estimator_instance, method_sequence=["fit"]) + + # Compare the state of the model parameters with the original parameters + new_params = fitted_est.get_params() + for param_name, original_value in original_params.items(): + new_value = new_params[param_name] + + # We should never change or mutate the internal state of input + # parameters by default. To check this we use the joblib.hash function + # that introspects recursively any subobjects to compute a checksum. + # The only exception to this rule of immutable constructor parameters + # is possible RandomState instance but in this check we explicitly + # fixed the random_state params recursively to be integer seeds. + assert joblib.hash(new_value) == joblib.hash(original_value), ( + "Estimator %s should not change or mutate " + " the parameter %s from %s to %s during fit." + % (estimator.__class__.__name__, param_name, original_value, new_value) ) + def test_methods_do_not_change_state(self, estimator_instance, scenario): + """Check that non-state-changing methods do not change state. + + Check that methods that are not supposed to change attributes of the + estimators do not change anything (including hyper-parameters and + fitted parameters) + """ + estimator = estimator_instance + set_random_state(estimator) -def test_methods_have_no_side_effects(estimator_instance, scenario): - """Check that calling methods has no side effects on args.""" - estimator = estimator_instance + for method in NON_STATE_CHANGING_METHODS: + if _has_capability(estimator, method): - set_random_state(estimator) + # dict_before = copy of dictionary of estimator before predict, post fit + _ = scenario.run(estimator, method_sequence=["fit"]) + dict_before = estimator.__dict__.copy() + + # dict_after = dictionary of estimator after predict and fit + _ = scenario.run(estimator, method_sequence=[method]) + dict_after = estimator.__dict__ + + if method == "transform" and estimator.get_class_tag( + "fit-in-transform" + ): + # Some transformations fit during transform, as they apply + # some transformation to each series passed to transform, + # so transform will actually change the state of these estimator. + continue + + if method == "predict" and estimator.get_class_tag("fit-in-predict"): + # Some annotators fit during predict, as they apply + # some apply annotation to each series passed to predict, + # so predict will actually change the state of these annotators. + continue + + # old logic uses equality without auto-msg, keep comment until refactor + # is_equal = dict_after == dict_before + is_equal, msg = deep_equals(dict_after, dict_before, return_msg=True) + assert is_equal, ( + f"Estimator: {type(estimator).__name__} changes __dict__ " + f"during {method}, " + f"reason/location of discrepancy (x=after, y=before): {msg}" + ) - # Fit the model, get args before and after - _, args_after = scenario.run(estimator, method_sequence=["fit"], return_args=True) - fit_args_after = args_after[0] - fit_args_before = scenario.args["fit"] + def test_methods_have_no_side_effects(self, estimator_instance, scenario): + """Check that calling methods has no side effects on args.""" + estimator = estimator_instance - assert deep_equals( - fit_args_before, fit_args_after - ), f"Estimator: {estimator} has side effects on arguments of fit" + set_random_state(estimator) - for method in NON_STATE_CHANGING_METHODS: - if _has_capability(estimator, method): - # Fit the model, get args before and after - _, args_after = scenario.run( - estimator, method_sequence=[method], return_args=True - ) - method_args_after = args_after[0] - method_args_before = scenario.get_args(method, estimator) - - assert deep_equals( - method_args_after, method_args_before - ), f"Estimator: {estimator} has side effects on arguments of {method}" - - -def test_persistence_via_pickle(estimator_instance): - """Check that we can pickle all estimators.""" - estimator = estimator_instance - set_random_state(estimator) - fit_args = _make_args(estimator, "fit") - estimator.fit(*fit_args) - - # Generate results before pickling - results = {} - args = {} - for method in NON_STATE_CHANGING_METHODS: - if _has_capability(estimator, method): - args[method] = _make_args(estimator, method) - results[method] = getattr(estimator, method)(*args[method]) - - # Pickle and unpickle - pickled_estimator = pickle.dumps(estimator) - unpickled_estimator = pickle.loads(pickled_estimator) - - # Compare against results after pickling - for method, value in results.items(): - unpickled_result = getattr(unpickled_estimator, method)(*args[method]) - _assert_array_almost_equal( - value, - unpickled_result, - decimal=6, - err_msg="Results are not the same after pickling", + # Fit the model, get args before and after + _, args_after = scenario.run( + estimator, method_sequence=["fit"], return_args=True ) + fit_args_after = args_after[0] + fit_args_before = scenario.args["fit"] + assert deep_equals( + fit_args_before, fit_args_after + ), f"Estimator: {estimator} has side effects on arguments of fit" -# 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(estimator_class, scenario): - """Test that single and multi-process run results are identical. - - Check that running an estimator on a single process is no different to running - it on multiple processes. We also check that we can set n_jobs=-1 to make use - of all CPUs. The test is not really necessary though, as we rely on joblib for - parallelization and can trust that it works as expected. - """ - estimator = estimator_class.create_test_instance() - params = estimator.get_params() - - if "n_jobs" in params: for method in NON_STATE_CHANGING_METHODS: if _has_capability(estimator, method): - # run on a single process - # ----------------------- - estimator = estimator_class.create_test_instance() - estimator.set_params(n_jobs=1) - set_random_state(estimator) - result_single_process = scenario.run( - estimator, method_sequence=["fit", method] - ) - - # run on multiple processes - # ------------------------- - estimator = estimator_class.create_test_instance() - estimator.set_params(n_jobs=-1) - set_random_state(estimator) - result_multiple_process = scenario.run( - estimator, method_sequence=["fit", method] - ) - _assert_array_equal( - result_single_process, - result_multiple_process, - err_msg="Results are not equal for n_jobs=1 and n_jobs=-1", + # Fit the model, get args before and after + _, args_after = scenario.run( + estimator, method_sequence=[method], return_args=True ) + method_args_after = args_after[0] + method_args_before = scenario.get_args(method, estimator) + + assert deep_equals( + method_args_after, method_args_before + ), f"Estimator: {estimator} has side effects on arguments of {method}" + + def test_persistence_via_pickle(self, estimator_instance): + """Check that we can pickle all estimators.""" + estimator = estimator_instance + set_random_state(estimator) + fit_args = _make_args(estimator, "fit") + estimator.fit(*fit_args) + + # Generate results before pickling + results = {} + args = {} + for method in NON_STATE_CHANGING_METHODS: + if _has_capability(estimator, method): + args[method] = _make_args(estimator, method) + results[method] = getattr(estimator, method)(*args[method]) + # Pickle and unpickle + pickled_estimator = pickle.dumps(estimator) + unpickled_estimator = pickle.loads(pickled_estimator) -def test_valid_estimator_class_tags(estimator_class): - """Check that Estimator class tags are in VALID_ESTIMATOR_TAGS.""" - for tag in estimator_class.get_class_tags().keys(): - assert tag in VALID_ESTIMATOR_TAGS - - -def test_valid_estimator_tags(estimator_instance): - """Check that Estimator tags are in VALID_ESTIMATOR_TAGS.""" - for tag in estimator_instance.get_tags().keys(): - assert tag in VALID_ESTIMATOR_TAGS - + # Compare against results after pickling + for method, value in results.items(): + unpickled_result = getattr(unpickled_estimator, method)(*args[method]) + _assert_array_almost_equal( + value, + unpickled_result, + decimal=6, + err_msg="Results are not the same after pickling", + ) -def _get_err_msg(estimator): - return ( - f"Invalid estimator type: {type(estimator)}. Valid estimator types are: " - f"{VALID_ESTIMATOR_TYPES}" - ) + # 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): + """Test that single and multi-process run results are identical. + + Check that running an estimator on a single process is no different to running + it on multiple processes. We also check that we can set n_jobs=-1 to make use + of all CPUs. The test is not really necessary though, as we rely on joblib for + parallelization and can trust that it works as expected. + """ + params = estimator_instance.get_params() + + if "n_jobs" in params: + for method in NON_STATE_CHANGING_METHODS: + if _has_capability(estimator_instance, method): + # run on a single process + # ----------------------- + estimator = deepcopy(estimator_instance) + estimator.set_params(n_jobs=1) + set_random_state(estimator) + result_single_process = scenario.run( + estimator, method_sequence=["fit", method] + ) + + # run on multiple processes + # ------------------------- + estimator = deepcopy(estimator_instance) + estimator.set_params(n_jobs=-1) + set_random_state(estimator) + result_multiple_process = scenario.run( + estimator, method_sequence=["fit", method] + ) + _assert_array_equal( + result_single_process, + result_multiple_process, + err_msg="Results are not equal for n_jobs=1 and n_jobs=-1", + ) + + def test_valid_estimator_class_tags(self, estimator_class): + """Check that Estimator class tags are in VALID_ESTIMATOR_TAGS.""" + for tag in estimator_class.get_class_tags().keys(): + assert tag in VALID_ESTIMATOR_TAGS + + def test_valid_estimator_tags(self, estimator_instance): + """Check that Estimator tags are in VALID_ESTIMATOR_TAGS.""" + for tag in estimator_instance.get_tags().keys(): + assert tag in VALID_ESTIMATOR_TAGS + + def _get_err_msg(estimator): + return ( + f"Invalid estimator type: {type(estimator)}. Valid estimator types are: " + f"{VALID_ESTIMATOR_TYPES}" + ) diff --git a/sktime/transformations/panel/rocket/_minirocket.py b/sktime/transformations/panel/rocket/_minirocket.py index 9d7a27b8d9f..0ecbf7160c7 100644 --- a/sktime/transformations/panel/rocket/_minirocket.py +++ b/sktime/transformations/panel/rocket/_minirocket.py @@ -53,9 +53,7 @@ def __init__( self.max_dilations_per_kernel = max_dilations_per_kernel self.n_jobs = n_jobs - self.random_state = ( - np.int32(random_state) if isinstance(random_state, int) else None - ) + self.random_state = random_state super(MiniRocket, self).__init__() def fit(self, X, y=None): @@ -71,6 +69,11 @@ def fit(self, X, y=None): self """ X = check_X(X, enforce_univariate=True, coerce_to_numpy=True) + + random_state = ( + np.int32(self.random_state) if isinstance(self.random_state, int) else None + ) + X = X[:, 0, :].astype(np.float32) _, n_timepoints = X.shape if n_timepoints < 9: @@ -81,7 +84,7 @@ def fit(self, X, y=None): ) ) self.parameters = _fit( - X, self.num_kernels, self.max_dilations_per_kernel, self.random_state + X, self.num_kernels, self.max_dilations_per_kernel, random_state ) self._is_fitted = True return self diff --git a/sktime/transformations/series/detrend/_deseasonalize.py b/sktime/transformations/series/detrend/_deseasonalize.py index f0602df68e9..b0db5f6c71f 100644 --- a/sktime/transformations/series/detrend/_deseasonalize.py +++ b/sktime/transformations/series/detrend/_deseasonalize.py @@ -393,6 +393,7 @@ class STLTransformer(_SeriesToSeriesTransformer): -------- Detrender Deseasonalizer + STLForecaster References ---------- diff --git a/sktime/transformations/series/tests/test_window_summarizer.py b/sktime/transformations/series/tests/test_window_summarizer.py new file mode 100644 index 00000000000..219204cb426 --- /dev/null +++ b/sktime/transformations/series/tests/test_window_summarizer.py @@ -0,0 +1,131 @@ +# -*- coding: utf-8 -*- +"""Test extraction of features across (shifted) windows.""" +__author__ = ["danbartl"] + +import numpy as np +import pandas as pd +import pytest + +from sktime.datasets import load_airline, load_longley +from sktime.datatypes import get_examples +from sktime.forecasting.model_selection import temporal_train_test_split +from sktime.transformations.series.window_summarizer import WindowSummarizer + + +def check_eval(test_input, expected): + """Test which columns are returned for different arguments. + + For a detailed description what these arguments do, + and how theyinteract see docstring of DateTimeFeatures. + """ + if test_input is not None: + assert len(test_input) == len(expected) + assert all([a == b for a, b in zip(test_input, expected)]) + else: + assert expected is None + + +# Load data that will be the basis of tests +y = load_airline() +y_pd = get_examples(mtype="pd.DataFrame", as_scitype="Series")[0] +y_series = get_examples(mtype="pd.Series", as_scitype="Series")[0] +y_multi = get_examples(mtype="pd-multiindex", as_scitype="Panel")[0] +# y Train will be univariate data set +y_train, y_test = temporal_train_test_split(y) + +# Create Panel sample data +mi = pd.MultiIndex.from_product([[0], y.index], names=["instances", "timepoints"]) +y_group1 = pd.DataFrame(y.values, index=mi, columns=["y"]) + +mi = pd.MultiIndex.from_product([[1], y.index], names=["instances", "timepoints"]) +y_group2 = pd.DataFrame(y.values, index=mi, columns=["y"]) + +y_grouped = pd.concat([y_group1, y_group2]) + +y_ll, X_ll = load_longley() +y_ll_train, _, X_ll_train, X_ll_test = temporal_train_test_split(y_ll, X_ll) + +# Get different WindowSummarizer functions +kwargs = WindowSummarizer.get_test_params()[0] +kwargs_alternames = WindowSummarizer.get_test_params()[1] +kwargs_variant = WindowSummarizer.get_test_params()[2] + + +def count_gt100(x): + """Count how many observations lie above threshold 100.""" + return np.sum((x > 100)[::-1]) + + +# Cannot be pickled in get_test_params, therefore here explicit +kwargs_custom = { + "lag_config": { + "cgt100": [count_gt100, [[3, 2]]], + } +} +# Generate named and unnamed y +y_train.name = None +y_train_named = y_train.copy() +y_train_named.name = "y" + +# Target for multivariate extraction +Xtmvar = ["POP_lag_3_0", "POP_lag_6_0", "GNP_lag_3_0", "GNP_lag_6_0"] +Xtmvar = Xtmvar + ["GNPDEFL", "UNEMP", "ARMED"] +Xtmvar_none = ["GNPDEFL_lag_3_0", "GNPDEFL_lag_6_0", "GNP", "UNEMP", "ARMED", "POP"] + +# Some tests are commented out until hierarchical PR works + + +@pytest.mark.parametrize( + "kwargs, column_names, y, target_cols, truncate", + [ + ( + kwargs, + ["y_lag_1_0", "y_mean_3_0", "y_mean_12_0", "y_std_4_0"], + y_train_named, + None, + None, + ), + (kwargs_alternames, Xtmvar, X_ll_train, ["POP", "GNP"], None), + (kwargs_alternames, Xtmvar_none, X_ll_train, None, None), + # (kwargs, ["lag_1_0", "mean_3_0", "mean_12_0", "std_4_0"], y_group1), + # (kwargs, ["lag_1_0", "mean_3_0", "mean_12_0", "std_4_0"], y_grouped), + # (None, ["lag_1_0"], y_multi), + (None, None, y_train, None, None), + (None, ["a_lag_1_0"], y_pd, None, None), + (kwargs_custom, ["a_cgt100_3_2"], y_pd, None, None), + (kwargs_alternames, ["0_lag_3_0", "0_lag_6_0"], y_train, None, "bfill"), + ( + kwargs_variant, + ["0_mean_7_0", "0_mean_7_7", "0_covar_feature_28_0"], + y_train, + None, + None, + ), + ], +) +def test_windowsummarizer(kwargs, column_names, y, target_cols, truncate): + """Test columns match kwargs arguments.""" + if kwargs is not None: + transformer = WindowSummarizer( + **kwargs, target_cols=target_cols, truncate=truncate + ) + else: + transformer = WindowSummarizer(target_cols=target_cols, truncate=truncate) + Xt = transformer.fit_transform(y) + if Xt is not None: + if isinstance(Xt, pd.DataFrame): + Xt_columns = Xt.columns.to_list() + else: + Xt_columns = Xt.name + else: + Xt_columns = None + + check_eval(Xt_columns, column_names) + + +@pytest.mark.xfail(raises=ValueError) +def test_wrong_column(): + """Test mismatch between X column names and target_cols.""" + transformer = WindowSummarizer(target_cols=["dummy"]) + Xt = transformer.fit_transform(X_ll_train) + return Xt diff --git a/sktime/transformations/series/window_summarizer.py b/sktime/transformations/series/window_summarizer.py new file mode 100644 index 00000000000..b686e7d63d5 --- /dev/null +++ b/sktime/transformations/series/window_summarizer.py @@ -0,0 +1,434 @@ +#!/usr/bin/env python3 -u +# -*- coding: utf-8 -*- +# copyright: sktime developers, BSD-3-Clause License (see LICENSE file) +"""Extract features across (shifted) windows from provided series.""" + +__author__ = ["danbartl"] +__all__ = ["WindowSummarizer"] + +import pandas as pd +from joblib import Parallel, delayed + +from sktime.transformations.base import BaseTransformer + + +class WindowSummarizer(BaseTransformer): + """Transformer for extracting time series features. + + The WindowSummarizer transforms input series to features + based on a provided dictionary of window summarizer, window shifts + and window lengths. + + Parameters + ---------- + n_jobs : int, optional (default=-1) + The number of jobs to run in parallel for applying the window functions. + ``-1`` means using all processors. + target_cols: list of str, optional (default = None) + Specifies which columns in X to target for applying the window functions. + ``None`` will target the first column + lag_config: dict of str and list, optional (default = dict containing first lag) + Dictionary specifying as key the `name` of the columns to be + generated. As value the dict specifies the type of function via the argument + `summarize` as well as the length 2 list argument `window`. The list `window` + will be resolved by the internal function _window_feature to `window length` + - the length of the window across which to apply the function - as well as + the argument `starting_at`, which will specify how far back in the past + the window will start. + + For example for `window = [4, 3]`, we have a `window_length` of 4 and + `starting_at` of 3 to target the four days prior to the last three days. + Here is a representation of the selected window: + + |-------------------------------| + | x * * * * * * * x x x z - - - | + |-------------------------------| + + ``-`` = future observations. + ``z`` = current observation, to which the window should be relative to. + ``x`` = past observations. + ``*`` = selected window of past observations across which summarizer + function will be applied. + + key (resolved to name) : str, name of the derived features, will be appended by + window_length and starting_at parameter. + first value (resolved to summarizer): either custom function call (to be + provided by user) or str corresponding to native pandas window function: + * "sum", + * "mean", + * "median", + * "std", + * "var", + * "kurt", + * "min", + * "max", + * "corr", + * "cov", + * "skew", + * "sem" + See also: https://pandas.pydata.org/docs/reference/window.html. + second value (window): list of integers + List containg window_length and starting_at parameters. + truncate: str, optional (default = None) + Defines how to deal with NAs that were created as a result of applying the + functions in the lag_config dict across windows that are longer than + the remaining history of data. + For example a lag config of [7, 14] - a window_length of 7 starting at 14 + observations in the past - cannot be fully applied for the first 20 + observations of the targeted column. + A lag_config of [[7, 14], [0, 28]] cannot be correctly applied for the + first 21 resp. 28 observations of the targeted column. Possible values + to deal with those NAs: + * None + * "bfill" + None will keep the NAs generated, and would leave it for the user to choose + an estimator that can correctly deal with observations with missing values, + "bfill" will fill the NAs by carrying the first observation backwards. + + + Attributes + ---------- + truncate_start : int + See section Parameters - truncate for a more detailed explanation of truncation + as a result of applying windows of certain lengths across past observations. + A lag_config of [[7, 14], [0, 28]] cannot be correctly applied for the + first 21 resp. 28 observations of the targeted column. truncate_start will + give the maximum og observations that are filled with NAs across all arguments + of the lag_config, in this case 28. + + + Returns + ------- + X: pd.DataFrame + Contains all transformed columns as well as non-transformed columns. + The raw inputs to transformed columns will be dropped. + self: reference to self + + Examples + -------- + >>> import pandas as pd + >>> from sktime.transformations.series.window_summarizer import WindowSummarizer + >>> from sktime.datasets import load_airline, load_longley + >>> from sktime.forecasting.naive import NaiveForecaster + >>> from sktime.forecasting.base import ForecastingHorizon + >>> from sktime.forecasting.compose import ForecastingPipeline + >>> from sktime.forecasting.model_selection import temporal_train_test_split + >>> y = load_airline() + >>> kwargs = { + ... "lag_config": { + ... "lag": ["lag", [[1, 0]]], + ... "mean": ["mean", [[3, 0], [12, 0]]], + ... "std": ["std", [[4, 0]]], + ... } + ... } + >>> transformer = WindowSummarizer(**kwargs) + >>> y_transformed = transformer.fit_transform(y) + + Example with transforming multiple columns of exogeneous features + >>> y, X = load_longley() + >>> y_train, y_test, X_train, X_test = temporal_train_test_split(y, X) + >>> fh = ForecastingHorizon(X_test.index, is_relative=False) + >>> # Example transforming only X + >>> pipe = ForecastingPipeline( + ... steps=[ + ... ("a", WindowSummarizer(n_jobs=1, target_cols=["POP", "GNPDEFL"])), + ... ("b", WindowSummarizer(n_jobs=1, target_cols=["GNP"], **kwargs)), + ... ("forecaster", NaiveForecaster(strategy="drift")), + ... ] + ... ) + >>> pipe_return = pipe.fit(y_train, X_train) + >>> y_pred1 = pipe_return.predict(fh=fh, X=X_test) + + Example with transforming multiple columns of exogeneous features + as well as the y column + >>> Z_train = pd.concat([X_train, y_train], axis=1) + >>> Z_test = pd.concat([X_test, y_test], axis=1) + >>> pipe = ForecastingPipeline( + ... steps=[ + ... ("a", WindowSummarizer(n_jobs=1, target_cols=["POP", "TOTEMP"])), + ... ("b", WindowSummarizer(**kwargs, n_jobs=1, target_cols=["GNP"])), + ... ("forecaster", NaiveForecaster(strategy="drift")), + ... ] + ... ) + >>> pipe_return = pipe.fit(y_train, Z_train) + >>> y_pred2 = pipe_return.predict(fh=fh, X=Z_test) + """ + + _tags = { + "scitype:transform-input": "Series", + "scitype:transform-output": "Series", + "scitype:instancewise": True, + "capability:inverse_transform": False, + "scitype:transform-labels": False, + "X_inner_mtype": "pd.DataFrame", # which mtypes do _fit/_predict support for X? + "skip-inverse-transform": True, # is inverse-transform skipped when called? + "univariate-only": False, # can the transformer handle multivariate X? + "handles-missing-data": True, # can estimator handle missing data? + "X-y-must-have-same-index": False, # can estimator handle different X/y index? + "enforce_index_type": None, # index type that needs to be enforced in X/y + "fit-in-transform": False, # is fit empty and can be skipped? Yes = True + "transform-returns-same-time-index": False, + # does transform return have the same time index as input X + } + + def __init__( + self, + lag_config=None, + n_jobs=-1, + target_cols=None, + truncate=None, + ): + + # self._converter_store_X = dict() + self.lag_config = lag_config + self.n_jobs = n_jobs + self.target_cols = target_cols + self.truncate = truncate + + super(WindowSummarizer, self).__init__() + + def _fit(self, X, y=None): + """Fit transformer to X and y. + + Private _fit containing the core logic, called from fit + + Attributes + ---------- + truncate_start : int + See section Parameters - truncate for a more detailed explanation of + truncation as a result of applying windows of certain lengths across past + observations. + A lag_config of [[7, 14], [0, 28]] cannot be correctly applied for the + first 21 resp. 28 observations of the targeted column. truncate_start will + give the maximum og observations that are filled with NAs across all + arguments of the lag_config, in this case 28. + + Returns + ------- + X: pd.DataFrame + Contains all transformed columns as well as non-transformed columns. + The raw inputs to transformed columns will be dropped. + self: reference to self + """ + X_name = get_name_list(X) + + if self.target_cols is not None: + if not all(x in X_name for x in self.target_cols): + missing_cols = [x for x in self.target_cols if x not in X_name] + raise ValueError( + "target_cols " + + " ".join(missing_cols) + + " specified that do not exist in X." + ) + + if self.target_cols is None: + self._target_cols = [X_name[0]] + else: + self._target_cols = self.target_cols + + if self.lag_config is None: + func_dict = pd.DataFrame( + { + "lag": ["lag", [[1, 0]]], + } + ).T.reset_index() + else: + func_dict = pd.DataFrame(self.lag_config).T.reset_index() + + func_dict.rename( + columns={"index": "name", 0: "summarizer", 1: "window"}, + inplace=True, + ) + func_dict = func_dict.explode("window") + self.truncate_start = func_dict["window"].apply(lambda x: x[0] + x[1]).max() + + self._func_dict = func_dict + + def _transform(self, X, y=None): + """Transform X and return a transformed version. + + Parameters + ---------- + X : pd.DataFrame + y : None + + Returns + ------- + transformed version of X + """ + func_dict = self._func_dict + target_cols = self._target_cols + + X.columns = X.columns.map(str) + Xt_out = [] + if self.truncate == "bfill": + bfill = True + else: + bfill = False + for cols in target_cols: + if isinstance(X.index, pd.MultiIndex): + X_grouped = getattr(X.groupby("instances"), X.loc[:, [cols]]) + df = Parallel(n_jobs=self.n_jobs)( + delayed(_window_feature)(X_grouped, **kwargs, bfill=bfill) + for index, kwargs in func_dict.iterrows() + ) + else: + df = Parallel(n_jobs=self.n_jobs)( + delayed(_window_feature)(X.loc[:, [cols]], **kwargs, bfill=bfill) + for _index, kwargs in func_dict.iterrows() + ) + Xt = pd.concat(df, axis=1) + Xt = Xt.add_prefix(str(cols) + "_") + Xt_out.append(Xt) + Xt_out_df = pd.concat(Xt_out, axis=1) + Xt_return = pd.concat([Xt_out_df, X.drop(target_cols, axis=1)], axis=1) + + return Xt_return + + @classmethod + def get_test_params(cls): + """Return testing parameter settings for the estimator. + + Returns + ------- + params : dict or list of dict, default = {} + Parameters to create testing instances of the class + Each dict are parameters to construct an "interesting" test instance, i.e., + `MyClass(**params)` or `MyClass(**params[i])` creates a valid test instance. + `create_test_instance` uses the first (or only) dictionary in `params` + """ + params1 = { + "lag_config": { + "lag": ["lag", [[1, 0]]], + "mean": ["mean", [[3, 0], [12, 0]]], + "std": ["std", [[4, 0]]], + } + } + + params2 = { + "lag_config": { + "lag": ["lag", [[3, 0], [6, 0]]], + } + } + + params3 = { + "lag_config": { + "mean": ["mean", [[7, 0], [7, 7]]], + "covar_feature": ["cov", [[28, 0]]], + } + } + + return [params1, params2, params3] + + +# List of native pandas rolling window function. +# In the future different engines for pandas will be investigated +pd_rolling = [ + "sum", + "mean", + "median", + "std", + "var", + "kurt", + "min", + "max", + "corr", + "cov", + "skew", + "sem", +] + + +def get_name_list(Z): + """Get names of pd.Series or pd.Dataframe.""" + if isinstance(Z, pd.DataFrame): + Z_name = Z.columns.to_list() + else: + if Z.name is not None: + Z_name = [Z.name] + else: + Z_name = None + Z_name = [str(z) for z in Z_name] + return Z_name + + +def _window_feature(Z, name=None, summarizer=None, window=None, bfill=False): + """Compute window features and lag. + + Apply summarizer passed over a certain window + of past observations, e.g. the mean of a window of length 7 days, lagged by 14 days. + + Z: pandas Dataframe with a single column. + name : str, base string of the derived features, will be appended by + window length and starting at parameters defined in window. + summarizer: either str corresponding to pandas window function, currently + * "sum", + * "mean", + * "median", + * "std", + * "var", + * "kurt", + * "min", + * "max", + * "corr", + * "cov", + * "skew", + * "sem" + or custom function call. See for the native window functions also + https://pandas.pydata.org/docs/reference/window.html. + window: list of integers + List containg window_length and starting_at parameters, see WindowSummarizer + class description for in-depth explanation. + """ + window_length = window[0] + starting_at = window[1] + 1 + + if summarizer in pd_rolling: + if isinstance(Z.index, pd.MultiIndex): + if bfill is False: + feat = getattr( + Z.shift(starting_at).rolling(window_length), summarizer + )() + else: + feat = getattr( + Z.shift(starting_at).fillna(method="bfill").rolling(window_length), + summarizer, + )() + else: + if bfill is False: + feat = Z.apply( + lambda x: getattr( + x.shift(starting_at).rolling(window_length), summarizer + )() + ) + else: + feat = Z.apply( + lambda x: getattr( + x.shift(starting_at) + .fillna(method="bfill") + .rolling(window_length), + summarizer, + )() + ) + else: + if bfill is False: + feat = Z.shift(starting_at) + else: + feat = Z.shift(starting_at).fillna(method="bfill") + if isinstance(Z.index, pd.MultiIndex) and callable(summarizer): + feat = feat.rolling(window_length).apply(summarizer, raw=True) + elif not isinstance(Z.index, pd.MultiIndex) and callable(summarizer): + feat = feat.apply( + lambda x: x.rolling(window_length).apply(summarizer, raw=True) + ) + if bfill is True: + feat = feat.fillna(method="bfill") + + feat.rename( + columns={ + feat.columns[0]: name + "_" + "_".join([str(item) for item in window]) + }, + inplace=True, + ) + + return feat diff --git a/sktime/utils/_testing/_conditional_fixtures.py b/sktime/utils/_testing/_conditional_fixtures.py index 1129ca1362b..59149ea1a11 100644 --- a/sktime/utils/_testing/_conditional_fixtures.py +++ b/sktime/utils/_testing/_conditional_fixtures.py @@ -95,6 +95,7 @@ def create_conditional_fixtures_and_names( fixture names correspond to fixtures with the same indices at picks (from lists) """ fixture_vars = _check_list_of_str(fixture_vars, name="fixture_vars") + fixture_vars = [var for var in fixture_vars if var in generator_dict.keys()] # order fixture_vars according to fixture_sequence if provided if fixture_sequence is not None: @@ -132,7 +133,7 @@ def get_fixtures(fixture_var, **kwargs): """ try: res = generator_dict[fixture_var](test_name, **kwargs) - if len(res) == 2: + if isinstance(res, tuple) and len(res) == 2: fixture_prod = res[0] fixture_names = res[1] else: @@ -157,19 +158,25 @@ def get_fixtures(fixture_var, **kwargs): new_fixture_names = [] for j, fixture in enumerate(fixture_prod): + # retrieve kwargs corresponding to old fixture values fixture_name = fixture_names[j] if i == 0: kwargs = dict() else: kwargs = dict(zip(old_fixture_vars, fixture)) - + # retrieve conditional fixtures, conditional on fixture values in kwargs new_fixtures, new_fixture_names_r = deepcopy( get_fixtures(fixture_var, **kwargs) ) + # new fixture values are concatenation/product of old values plus new new_fixture_prod += [ deepcopy(fixture) + (new_fixture,) for new_fixture in new_fixtures ] - new_fixture_names += [f"{fixture_name}-{x}" for x in new_fixture_names_r] + # new fixture name is concatenation of name so far and "dash-new name" + # if the new name is empty string, don't add a dash + if len(new_fixture_names_r) > 0 and new_fixture_names_r[0] != "": + new_fixture_names_r = [f"-{x}" for x in new_fixture_names_r] + new_fixture_names += [f"{fixture_name}{x}" for x in new_fixture_names_r] fixture_prod = new_fixture_prod fixture_names = new_fixture_names diff --git a/sktime/utils/validation/__init__.py b/sktime/utils/validation/__init__.py index fcef2e54bad..31682c112b5 100644 --- a/sktime/utils/validation/__init__.py +++ b/sktime/utils/validation/__init__.py @@ -21,6 +21,7 @@ import numpy as np import pandas as pd +ACCEPTED_DATETIME_TYPES = np.datetime64, pd.Timestamp ACCEPTED_TIMEDELTA_TYPES = pd.Timedelta, timedelta, np.timedelta64 ACCEPTED_DATEOFFSET_TYPES = pd.DateOffset ACCEPTED_WINDOW_LENGTH_TYPES = Union[ @@ -31,6 +32,11 @@ ] +def is_array(x) -> bool: + """Check if x is either a list or np.ndarray.""" + return isinstance(x, (list, np.ndarray)) + + def is_int(x) -> bool: """Check if x is of integer type, but not boolean.""" # boolean are subclasses of integers in Python, so explicitly exclude them @@ -47,6 +53,11 @@ def is_timedelta(x) -> bool: return isinstance(x, ACCEPTED_TIMEDELTA_TYPES) +def is_datetime(x) -> bool: + """Check if x is of datetime type.""" + return isinstance(x, ACCEPTED_DATETIME_TYPES) + + def is_date_offset(x) -> bool: """Check if x is of pd.DateOffset type.""" return isinstance(x, ACCEPTED_DATEOFFSET_TYPES) @@ -57,6 +68,21 @@ def is_timedelta_or_date_offset(x) -> bool: return is_timedelta(x=x) or is_date_offset(x=x) +def array_is_int(x) -> bool: + """Check if array is of integer type.""" + return all([is_int(value) for value in x]) + + +def array_is_datetime64(x) -> bool: + """Check if array is of np.datetime64 type.""" + return all([is_datetime(value) for value in x]) + + +def array_is_timedelta_or_date_offset(x) -> bool: + """Check if array is timedelta or pd.DateOffset type.""" + return all([is_timedelta_or_date_offset(value) for value in x]) + + def check_n_jobs(n_jobs: int) -> int: """Check `n_jobs` parameter according to the scikit-learn convention. diff --git a/sktime/utils/validation/forecasting.py b/sktime/utils/validation/forecasting.py index 6870d191b1d..51fdf42be9c 100644 --- a/sktime/utils/validation/forecasting.py +++ b/sktime/utils/validation/forecasting.py @@ -15,7 +15,7 @@ "check_sp", "check_regressor", ] -__author__ = ["Markus L枚ning", "@big-o"] +__author__ = ["mloning", "@big-o", "khrapovs"] from datetime import timedelta from typing import Optional, Union @@ -25,9 +25,18 @@ from sklearn.base import clone, is_regressor from sklearn.ensemble import GradientBoostingRegressor -from sktime.utils.validation import is_date_offset, is_int, is_timedelta +from sktime.utils.validation import ( + array_is_datetime64, + array_is_int, + is_date_offset, + is_int, + is_timedelta, +) from sktime.utils.validation.series import check_equal_time_index, check_series +ACCEPTED_CUTOFF_TYPES = np.ndarray, pd.Index +VALID_CUTOFF_TYPES = Union[ACCEPTED_CUTOFF_TYPES] + def check_y_X( y, @@ -321,7 +330,7 @@ def check_alpha(alpha): return alpha -def check_cutoffs(cutoffs: Union[np.ndarray, pd.Index]) -> np.ndarray: +def check_cutoffs(cutoffs: VALID_CUTOFF_TYPES) -> np.ndarray: """Validate the cutoff. Parameters @@ -339,11 +348,11 @@ def check_cutoffs(cutoffs: Union[np.ndarray, pd.Index]) -> np.ndarray: If cutoffs array is empty. """ - if not isinstance(cutoffs, (np.ndarray, pd.Index)): + if not isinstance(cutoffs, ACCEPTED_CUTOFF_TYPES): raise ValueError( - f"`cutoffs` must be a np.array or pd.Index, " f"but found: {type(cutoffs)}" + f"`cutoffs` must be a np.array or pd.Index, but found: {type(cutoffs)}" ) - assert np.issubdtype(cutoffs.dtype, np.integer) + assert array_is_int(cutoffs) or array_is_datetime64(cutoffs) if len(cutoffs) == 0: raise ValueError("Found empty `cutoff` array") diff --git a/sktime/utils/validation/series.py b/sktime/utils/validation/series.py index 623dd8cf875..85fb338f142 100644 --- a/sktime/utils/validation/series.py +++ b/sktime/utils/validation/series.py @@ -18,7 +18,13 @@ # We currently support the following types for input data and time index types. VALID_DATA_TYPES = (pd.DataFrame, pd.Series, np.ndarray) -VALID_INDEX_TYPES = (pd.Int64Index, pd.RangeIndex, pd.PeriodIndex, pd.DatetimeIndex) +VALID_INDEX_TYPES = ( + pd.Int64Index, + pd.RangeIndex, + pd.PeriodIndex, + pd.DatetimeIndex, + pd.TimedeltaIndex, +) def _check_is_univariate(y, var_name="input"): diff --git a/sktime/utils/validation/tests/test_forecasting.py b/sktime/utils/validation/tests/test_forecasting.py index 60b317b821e..c3da0f9c7cf 100644 --- a/sktime/utils/validation/tests/test_forecasting.py +++ b/sktime/utils/validation/tests/test_forecasting.py @@ -1,8 +1,9 @@ #!/usr/bin/env python3 -u # -*- coding: utf-8 -*- # copyright: sktime developers, BSD-3-Clause License (see LICENSE file) +"""Test forecasting module.""" -__author__ = ["Markus L枚ning"] +__author__ = ["mloning"] import numpy as np import pandas as pd @@ -16,5 +17,6 @@ @pytest.mark.parametrize("arg", empty_input) def test_check_fh_empty_input(arg): - with raises(ValueError): + """Test that fh validation throws an error with empty container.""" + with raises(ValueError, match="`fh` must not be empty"): check_fh(arg)