diff --git a/docs/examples.md b/docs/examples.md index 7817ea24be..025b43ff2e 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -118,6 +118,19 @@ Early TSC ::: +::: + +:::{grid-item-card} +:img-top: examples/classification/img/rotation_forest.png +:class-img-top: aeon-card-image-m +:link: /examples/classification/rotation_forest.ipynb +:link-type: ref +:text-align: center + +Rotation Forest Classifier + +::: + :::: ## Regression diff --git a/examples/classification/img/rotation_forest.png b/examples/classification/img/rotation_forest.png new file mode 100644 index 0000000000..c25b73ee51 Binary files /dev/null and b/examples/classification/img/rotation_forest.png differ diff --git a/examples/classification/rotation_forest.ipynb b/examples/classification/rotation_forest.ipynb new file mode 100644 index 0000000000..0f70a0d80d --- /dev/null +++ b/examples/classification/rotation_forest.ipynb @@ -0,0 +1,203 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Rotation Forest Classifier\n", + "\n", + "RotationForest is an ensemble learning algorithm designed to improve the accuracy and diversity of decision tree-based classifiers. It was introduced as an extension of the popular RandomForest algorithm. The key idea behind RotationForest is to apply **Principal Component Analysis (PCA)** to rotate the feature space for each tree in the ensemble, creating diverse and accurate base classifiers.\n", + "\n", + "Unlike RandomForest, which selects a random subset of features at each node, RotationForest:\n", + "\n", + "- Divides features into random subsets and applies PCA transformation to each subset.\n", + "- Ensures all original features are used for each tree (instead of random feature selection).\n", + "- Uses scikit-learn decision tree (CART algorithm).\n", + "\n", + "Rotation Forest is relevant for **Time Series Classification (TSC)** because it effectively captures complex feature interactions and correlations which are often critical in time series data using PCA-based rotations. It works well with feature extraction methods (e.g., **TSFresh**) and is used in TSC pipelines like **FreshPRINCE** and **STC**, making it robust for both **univariate** and **multivariate** time series data.\n", + "\n", + "In this notebook, we will see how to use the `RotationForestClassifier` algorithm for time series classification." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# Import necessary libraries\n", + "import matplotlib.pyplot as plt\n", + "from sklearn.metrics import (\n", + " ConfusionMatrixDisplay,\n", + " accuracy_score,\n", + " classification_report,\n", + " confusion_matrix,\n", + ")\n", + "\n", + "from aeon.classification.sklearn import RotationForestClassifier\n", + "from aeon.datasets import load_italy_power_demand # univariate dataset" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "italy, italy_labels = load_italy_power_demand(split=\"train\")\n", + "italy_test, italy_test_labels = load_italy_power_demand(split=\"test\")" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((67, 1, 24), (67,))" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "italy.shape, italy_labels.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "RotationForestClassifier is not a time series classifier. \n", + "A valid sklearn input such as a 2d numpy array is required." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# Convert 3D array to 2D array\n", + "italy = italy.reshape(italy.shape[0], -1)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(67, 24)" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "italy.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: 0.9708454810495627 \n", + "\n", + "Classification Report:\n", + " precision recall f1-score support\n", + "\n", + " 1 0.97 0.97 0.97 513\n", + " 2 0.97 0.97 0.97 516\n", + "\n", + " accuracy 0.97 1029\n", + " macro avg 0.97 0.97 0.97 1029\n", + "weighted avg 0.97 0.97 0.97 1029\n", + "\n" + ] + } + ], + "source": [ + "rotation = RotationForestClassifier()\n", + "rotation.fit(italy, italy_labels)\n", + "y_pred = rotation.predict(italy_test)\n", + "\n", + "accuracy = accuracy_score(italy_test_labels, y_pred)\n", + "print(\"Accuracy: \", accuracy, \"\\n\")\n", + "\n", + "report = classification_report(italy_test_labels, y_pred)\n", + "print(\"Classification Report:\\n\", report)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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1WqVJB0/ftyp/j/88IMCAgLUrFkzh/b4+HhFR0frhx9+cGhv1KhRlXPUqVNHv/zyyzlGXNVNN92kTp06afTo0YqLi9OQIUP0xhtv/GHir4wzKSmpyr4WLVro559/VnFxsUP7779LnTp1JMml73LttdcqMjJS//nPf7R48WJdfvnlVf4uK9lsNs2ZM0cXX3yxQkJCdMEFF6hevXr69ttvVVBQ4PQ1L7zwQpcW4z355JOKiYlRVlaW5s2bp9jYWKePBfArkj3OG1arVQkJCdq2bZtLx/1+gdzZBAYGnrHdMIxzvkblfHKlsLAwrVu3Tp988omGDx+ub7/9VjfddJOuvvrqKn3d4c53qRQSEqKBAwdq0aJFWrp06Vmrekl67LHHNH78eHXp0kWvvfaaPvroI61cuVKXXnqp0yMY0um/H1d88803Onz4sCRp69atLh0L4Fcke5xX+vXrp927dyszM/NP+yYmJspms2nXrl0O7YcOHVJ+fr59Zb0n1KlTx2HleqXfjx5IUkBAgHr06KGnn35a3333nR599FGtXr1an3766RnPXRlndnZ2lX07d+7UBRdcoPDwcPe+wFkMHTpU33zzjY4fP37GRY2V3nrrLXXv3l0vv/yyhgwZol69eqlnz55V/k6c/eHljOLiYo0cOVLJycm64447NHv2bG3atMlj5wfMhGSP88oDDzyg8PBwjR49WocOHaqyf/fu3Zo7d66k08PQkqqsmH/66aclSX379vVYXBdddJEKCgr07bff2tsOHjyopUuXOvQ7duxYlWMrHy7z+9sBK9WvX19t27bVokWLHJLntm3b9PHHH9u/pzd0795dDz/8sP7xj38oPj7+rP0CAwOrjBq8+eab+umnnxzaKn+UnOmHkasmTZqk/fv3a9GiRXr66afVuHFjpaamnvXvEcDZ8VAdnFcuuugiLVmyRDfddJNatGjh8AS9DRs26M0339SIESMkSW3atFFqaqr++c9/Kj8/X127dtWXX36pRYsWacCAAWe9retcDBkyRJMmTdINN9yge+65RydOnNDzzz+vSy65xGGBWnp6utatW6e+ffsqMTFRhw8f1nPPPacGDRroyiuvPOv5n3jiCfXp00cpKSkaNWqUTp48qWeffVZRUVGaMWOGx77H7wUEBGjKlCl/2q9fv35KT0/XyJEjdcUVV2jr1q1avHixmjZt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wEB17drV6bhzcnJ04sQJXX311Q7tZWVl+stf/iJJ2rFjh0MckpSSkuL0NSr95z//0bx587R7924VFRXp1KlTslqtDn0aNWqkCy+80OE6NptN2dnZioyM1O7duzVq1Cjdfvvt9j6nTp1SVFSUy/EA8A6SPfxW9+7d9fzzzys4OFgJCQkKCnL85x4eHu7wuaioSO3bt9fixYurnKtevXrnFENYWJjLxxQVFUmS3nvvPYckK51eh+ApmZmZGjZsmGbOnKnevXsrKipKr7/+up566imXY33xxRer/PgIDAz0WKwA3EOyh98KDw9Xs2bNnO7frl07/ec//1FsbGyV6rZS/fr1tXHjRnXp0kXS6Qp28+bNateu3Rn7t2rVSjabTWvXrlXPnj2r7K8cWaioqLC3JScnKyQkRPv37z/riECLFi3siw0rffHFF3/+JX9jw4YNSkxM1EMPPWRv++GHH6r0279/v3Jzc5WQkGC/TkBAgJKSkhQXF6eEhATt2bNHw4YNc+n6AKoPC/SA/xk2bJguuOAC9e/fX5999pn27t2rNWvW6J577tGPP/4oSbr33nv1+OOPa9myZdq5c6fuvvvuP7xHvnHjxkpNTdVtt92mZcuW2c/5xhtvSJISExNlsVi0YsUKHTlyREVFRYqMjNSECRM0btw4LVq0SLt379bXX3+tZ5991r7o7c4779SuXbs0ceJEZWdna8mSJcrIyHDp+1588cXav3+/Xn/9de3evVvz5s0742LD0NBQpaamasuWLfrss890zz33aPDgwYqPj5ckzZw5U7NmzdK8efP0/fffa+vWrVq4cKGefvppl+IB4D0ke+B/ateurXXr1qlRo0YaOHCgWrRooVGjRqmkpMRe6d9///0aPny4UlNTlZKSosjISN1www1/eN7nn39eN954o+6++241b95ct99+u4qLiyVJF154oWbOnKkHH3xQcXFxGjNmjCTp4Ycf1tSpUzVr1iy1aNFC11xzjd577z01adJE0ul59LffflvLli1TmzZttGDBAj322GMufd/rr79e48aN05gxY9S2bVtt2LBBU6dOrdKvWbNmGjhwoK699lr16tVLrVu3dri1bvTo0XrppZe0cOFCtWrVSl27dlVGRoY9VgA1z2KcbWURAADwC1T2AAD4OZI9AAB+jmQPAICfI9kDAODnSPYAAPg5kj0AAH6OZA8AgJ8j2QMA4OdI9gAA+DmSPQAAfo5kDwCAnyPZAwDg5/4/TfIOUoUeD3kAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Plot confusion matrix\n", + "cm = confusion_matrix(italy_test_labels, y_pred)\n", + "disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=rotation.classes_)\n", + "disp.plot(cmap=\"YlOrRd\")\n", + "plt.title(\"Confusion Matrix\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### References:\n", + "\n", + "\\[1\\] J. J. Rodriguez, L. I. Kuncheva and C. J. Alonso, \"Rotation Forest: A New Classifier Ensemble Method,\" in IEEE Transactions on Pattern Analysis and Machine Intelligence, vol. 28, no. 10, pp. 1619-1630, Oct. 2006, doi: 10.1109/TPAMI.2006.211.\n", + "\n", + "\\[2\\] Bagnall, A., Flynn, M., Large, J., Line, J., Bostrom, A., & Cawley, G. (2018). Is rotation forest the best classifier for problems with continuous features? ArXiv. https://arxiv.org/abs/1809.06705" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "myaeon", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}