{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Univariate time series classification with sktime-dl\n", "[Github](https://github.com/sktime/sktime-dl)\n", "\n", "In this notebook, we use sktime-dl to perform for univariate time series classification by deep learning." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "import seaborn as sns\n", "\n", "from sklearn.model_selection import GridSearchCV\n", "from sktime.datasets import load_gunpoint, load_italy_power_demand\n", "from sktime_dl.deeplearning import CNNClassifier\n", "\n", "sns.set_style('whitegrid') " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Load a dataset" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
dim_0
00 -0.710520\n", "1 -1.183300\n", "2 -1.372400\n", "3...
10 -0.993010\n", "1 -1.426800\n", "2 -1.579900\n", "3...
20 1.319100\n", "1 0.569770\n", "2 0.195130\n", "3...
30 -0.812440\n", "1 -1.157600\n", "2 -1.416400\n", "3...
40 -0.972840\n", "1 -1.390500\n", "2 -1.536700\n", "3...
\n", "
" ], "text/plain": [ " dim_0\n", "0 0 -0.710520\n", "1 -1.183300\n", "2 -1.372400\n", "3...\n", "1 0 -0.993010\n", "1 -1.426800\n", "2 -1.579900\n", "3...\n", "2 0 1.319100\n", "1 0.569770\n", "2 0.195130\n", "3...\n", "3 0 -0.812440\n", "1 -1.157600\n", "2 -1.416400\n", "3...\n", "4 0 -0.972840\n", "1 -1.390500\n", "2 -1.536700\n", "3..." ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "X_train, y_train = load_italy_power_demand(split='train', return_X_y=True)\n", "X_test, y_test = load_italy_power_demand(split='test', return_X_y=True)\n", "X_train.head()" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "-0.71052" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "i = 0\n", "X_train.loc[i, \"dim_0\"]#.iloc[0]\n", "X_train.loc[i, \"dim_0\"].iloc[0]" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "def plot_data_samples(X, y, sample_numbers):\n", " ''' \n", " Plot the time series data relating to the input list of sample numbers.\n", "\n", " sample_numbers: list of integers\n", " E.g. [1, 7, 22, 42]\n", " '''\n", " \n", " unique_labels = np.unique(y).astype(int)\n", " num_classes = len(unique_labels)\n", " if num_classes<=4:\n", " class_colors = ['red', 'blue', 'green' , 'orange']\n", " else:\n", " class_colors = sns.color_palette(n_colors=num_classes)\n", "\n", " fig, ax = plt.subplots()\n", " for i in sample_numbers:\n", " print('sample', i, 'class', str(y[i]))\n", " color_num = y[i].astype(int) - unique_labels.min()\n", " X_train.loc[i, \"dim_0\"].plot(label=str(y[i]), color=class_colors[color_num])\n", "\n", " print('')\n", " plt.ylim([-3.5, 3.5])\n", " if num_classes<=2:\n", " title = class_colors[0]+' : class '+str(unique_labels[0])\n", " title = title + '\\n'+class_colors[1]+' : class '+str(unique_labels[1])\n", " plt.title(title)\n", " ax.set_ylabel('Data value')\n", " ax.set_xlabel('Data point number')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Plot some data samples" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "sample 0 class 1\n", "sample 1 class 1\n", "sample 2 class 2\n", "sample 3 class 2\n", "\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "plot_data_samples(X_train, y_train, [0, 1, 2, 3])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Train a single deep neural network classifier\n", "Here we choose to use the CNN (convolutional neural network) classifier. Other classifiers provided by sktime-dl include MLP, ResNet and InceptionTime." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.6180758017492711" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "network = CNNClassifier(nb_epochs=200, verbose=False)\n", "network.fit(X_train, y_train)\n", "network.score(X_test, y_test)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Save the model to file" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "network.model.save(\"temp_model.h5\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Grid Search\n", "sktime-dl is compatible with scikit-learn and can use sklearn's GridSearchCV.\n", "\n", "Here we search over two parameters, number of epochs and CNN kernel size." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Best cross-validation accuracy: 0.68\n", "Test set score: 0.53\n", "Best parameters: {'kernel_size': 9, 'nb_epochs': 100}\n" ] } ], "source": [ "param_grid = {'nb_epochs': [50, 100],\n", " 'kernel_size': [5, 7, 9] }\n", "grid = GridSearchCV(network, param_grid=param_grid, cv=5) \n", "grid.fit(X_train, y_train)\n", " \n", "print(\"Best cross-validation accuracy: {:.2f}\".format(grid.best_score_))\n", "print(\"Test set score: {:.2f}\".format(grid.score(X_test, y_test)))\n", "print(\"Best parameters: {}\".format(grid.best_params_))" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.7.5" } }, "nbformat": 4, "nbformat_minor": 4 }