├── .gitignore ├── .gitignore~ ├── ARIMA (Exploration).ipynb ├── ARIMA.ipynb ├── Data Analysis.ipynb ├── LSTM.ipynb ├── LSTM_Data_Analysis.ipynb ├── LSTM_Findings.txt ├── LSTM_Multi-Layer.ipynb └── LSTM_Multi-Layer_Concurrent.ipynb /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.csv 3 | *.png 4 | *.zip 5 | .ipynb_checkpoints/ 6 | 7 | # stored arima pickles 8 | *.arima 9 | arima_models/ 10 | -------------------------------------------------------------------------------- /.gitignore~: -------------------------------------------------------------------------------- 1 | 2 | *.csv 3 | *.png 4 | *.zip 5 | .ipynb_checkpoints/ 6 | -------------------------------------------------------------------------------- /ARIMA.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 47, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import math\n", 10 | "import pandas as pd\n", 11 | "import numpy as np\n", 12 | "import matplotlib.pyplot as plt\n", 13 | "import pmdarima as pm\n", 14 | "from pmdarima import model_selection\n", 15 | "import statsmodels\n", 16 | "from pmdarima.pipeline import Pipeline\n", 17 | "from pmdarima import preprocessing\n", 18 | "from pmdarima import arima\n", 19 | "from datetime import datetime\n", 20 | "import pickle\n", 21 | "import glob" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 48, 27 | "metadata": {}, 28 | "outputs": [], 29 | "source": [ 30 | "# Mean Absolute Percentage Error\n", 31 | "def mape(preds, labels):\n", 32 | " err = 0\n", 33 | " for (pred, label) in zip(preds, labels):\n", 34 | " denum = np.absolute(label) if label !=0 else 100 # this might be wrong\n", 35 | " err += (np.absolute(pred-label) / denum)\n", 36 | " err /= preds.shape[0]\n", 37 | " print(\"MAPE - {}\".format(err))\n", 38 | " return err\n", 39 | " \n", 40 | "# Brier Score or Mean Squared Error\n", 41 | "def mse(preds, labels):\n", 42 | " err = np.sum(np.power(preds-labels, 2)) / preds.shape[0]\n", 43 | " print(\"MSE - {}\".format(err))\n", 44 | " return err\n", 45 | "\n", 46 | "# Mean Absolute Error\n", 47 | "def mae(preds, labels):\n", 48 | " err = np.sum(np.abs(preds-labels)) / preds.shape[0]\n", 49 | " print(\"MAE - {}\".format(err))\n", 50 | " return err\n", 51 | " \n", 52 | "# Root Mean Squared Error\n", 53 | "def rmse(preds, labels):\n", 54 | " err = np.power(mse(preds, labels), 0.5)\n", 55 | " print(\"RMSE - {}\".format(err))\n", 56 | " return err\n", 57 | "\n", 58 | "# Calculates the error for MAE, RMSE, and RMSE\n", 59 | "# Returns the results in a list\n", 60 | "def calculate_errors(preds, labels):\n", 61 | " return [fn(preds, labels) for fn in [mae, rmse, mape]]\n" 62 | ] 63 | }, 64 | { 65 | "cell_type": "markdown", 66 | "metadata": {}, 67 | "source": [ 68 | "Trains an ARIMA model for every dataset, then makes a prediction on the test set. Models are saved to disk as a pickle file for reuse. Returns a dictionary of predictions. " 69 | ] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "execution_count": 4, 74 | "metadata": { 75 | "scrolled": false 76 | }, 77 | "outputs": [], 78 | "source": [ 79 | "save_path = 'arima_output'\n", 80 | "# Freq is the frequency in minutes to downsample to,\n", 81 | "# split is train/test set split. Parameters are (p,d,q)\n", 82 | "# Seasonal parameters are (P, D, Q). Assumes daily seasons\n", 83 | "# Each prediction set is in an (ARIMA, mean, naive) tuple\n", 84 | "def train_arima_models(freq=20, split=0.8, parameters=(1,0,1), seasonal_parameters = (3, 0, 3), load_from_disk=True): \n", 85 | " p, d, q= parameters\n", 86 | " P, D, Q = seasona_parameters\n", 87 | " seasonality = (24 * 60) // freq\n", 88 | " \n", 89 | " filenames = glob.glob('samples/*.csv')\n", 90 | " datasets = [filename.split('/')[1].split('.')[0] for filename in filenames]\n", 91 | "\n", 92 | " arima_maes = []\n", 93 | " mean_maes = []\n", 94 | " for dataset in datasets:\n", 95 | " # Generates train and test sets \n", 96 | " data = pd.read_csv('samples/' + dataset + '.csv', delimiter=',', index_col=0, parse_dates=True)\n", 97 | " downsampled = data.resample(str(freq) + 'T').mean()\n", 98 | " raw_values = np.asarray(downsampled['CpuUtilizationAverage'])\n", 99 | " tsize = math.floor(raw_values.shape[0] * split)\n", 100 | " train, test = model_selection.train_test_split(raw_values, train_size=tsize)\n", 101 | "\n", 102 | " \n", 103 | " model_filename = f\"{save_path}/models/{dataset}.arima\"\n", 104 | " \n", 105 | " # Train ARIMA models\n", 106 | " if (not load_from_disk):\n", 107 | " start = datetime.now()\n", 108 | " model = arima.ARIMA((p,d,q), (P,D,Q,seasonality), method='powell')\n", 109 | " model.fit(train)\n", 110 | " end = datetime.now()\n", 111 | " print(f\"Trained {dataset} in \" + str(end - start))\n", 112 | " \n", 113 | " # Save models to disk\n", 114 | " pickle.dump(model, open(model_filename, \"wb\" ))\n", 115 | " else: \n", 116 | " model = pickle.load(open(model_filename, \"rb\" ))\n", 117 | " \n", 118 | " print(f\"Loaded {f} from disk\")\n", 119 | "\n", 120 | " # Predict future\n", 121 | " arima_forecast = model.predict(test.shape[0])\n", 122 | " \n", 123 | " #Calculate Naive predictions\n", 124 | " mean = train.mean()\n", 125 | " mean_forecast = np.ones(test.shape[0]) * mean\n", 126 | " naive_forecast = np.ones(test.shape[0]) * train[-1]\n", 127 | "\n", 128 | " # Create plot of prediction vs actual\n", 129 | " fig, ax = plt.subplots()\n", 130 | " x = np.arange(raw_values.shape[0])\n", 131 | " plt.plot(x[:tsize], train, c='blue')\n", 132 | " plt.plot(x[tsize:], model_forecasts, c='green')\n", 133 | " plt.plot(x[tsize:], raw_values[tsize:], c='blue', alpha=0.3)\n", 134 | " plt.xlabel('Time (Days)')\n", 135 | " plt.ylabel('CPU Usage')\n", 136 | " ticks = np.arange(0, raw_values.shape[0], seasonality)\n", 137 | " tick_labels = [str(label) for label in ticks // seasonality]\n", 138 | " ax = plt.gca()\n", 139 | " plt.xticks(ticks)\n", 140 | " ax.set_xticklabels(tick_labels)\n", 141 | " plt.draw()\n", 142 | " plotname = f\"./save_path/plots/{dataset}.png\"\n", 143 | " plt.savefig(plotname, format='png')\n", 144 | "\n", 145 | " # Calculate errors\n", 146 | " errors = []\n", 147 | "\n", 148 | " for forecast in [model_forecasts, mean_forecasts, naive_forecasts]:\n", 149 | " errors.extend(calculate_errors(forecast, test))\n", 150 | " errors.extend(calculate_errors(forecast[:3], test[:3]))\n", 151 | " \n", 152 | " arima_maes.append(mae(model_forecasts, test))\n", 153 | " mean_maes.append(mae(mean_forecasts, test))\n", 154 | " \n", 155 | " \n", 156 | " row = pd.DataFrame([errors], index=[dataset], columns = columns, dtype=np.float64 )\n", 157 | " df = pd.concat([row, df])\n", 158 | "\n", 159 | " # Calculate avg stats\n", 160 | " avg_row = df.mean(axis=0).rename('Average', inplace=True)\n", 161 | " min_row = df.max(axis=0).rename('Maximum', inplace=True)\n", 162 | " max_row = df.min(axis=0).rename('Minimum', inplace = True)\n", 163 | " df = df.append(avg_row).append(min_row).append(max_row)\n", 164 | "\n", 165 | " # Saves everything to CSV\n", 166 | " df.to_csv(f\"{save_path}/all_results.csv\")\n", 167 | " \n", 168 | " # Separate CSV just for short term results\n", 169 | " columns = ['3pt MAE','3pt MAPE', '3pt MEAN MAE','3pt MEAN MAPE']\n", 170 | " short_term_df = df[columns]\n", 171 | " short_term_df.to_csv(f\"{save_path}/short_term_results.csv\", float_format=\"%.2f\")\n", 172 | "\n", 173 | " # Separate CSV just for long term results\n", 174 | " columns = ['MAE', 'MAPE', 'MEAN_MAE', 'MEAN_MAPE']\n", 175 | " long_term_df = df[columns]\n", 176 | " long_term_df.to_csv(f\"{save_path}/long_term_results.csv\", float_format=\"%.2f\")\n", 177 | " \n", 178 | " # Creates graph showing MAE of all files \n", 179 | " figure(num=None, figsize=(16, 6), dpi=80, facecolor='w', edgecolor='k')\n", 180 | " X = np.arange(50)\n", 181 | " handle1 = plt.bar(X, arima_maes, color='blue', width = 0.25, tick_label=trim_filenames, label = 'ARIMA')\n", 182 | " handle2 = plt.bar(X+0.25, mean_maes, color='red', width = 0.25, tick_label=trim_filenames, label = 'Naive Mean')\n", 183 | " plt.legend(handles = [handle1, handle2])\n", 184 | " plt.ylabel(\"Mean Absolute Error\")\n", 185 | " plt.xlabel(\"Time Series\")\n", 186 | " filename = f\"{save_path}/mae_plot.png\"\n", 187 | " plt.savefig(filename, dpi=200, bbox_inches='tight')\n", 188 | " \n", 189 | " # Prints percent of times ARIMA outperformed Naive mean\n", 190 | " tot = 0\n", 191 | " for arima_mae, mean_mae in zip(arima_maes, mean_maes):\n", 192 | " if (arima_mae < mean):\n", 193 | " tot += 1\n", 194 | " print(\"Percentage of times ARIMA outperformed mean:\")\n", 195 | " print(tot / len(datasets) * 100))\n" 196 | ] 197 | }, 198 | { 199 | "cell_type": "code", 200 | "execution_count": null, 201 | "metadata": {}, 202 | "outputs": [], 203 | "source": [] 204 | } 205 | ], 206 | "metadata": { 207 | "kernelspec": { 208 | "display_name": "Python 3", 209 | "language": "python", 210 | "name": "python3" 211 | }, 212 | "language_info": { 213 | "codemirror_mode": { 214 | "name": "ipython", 215 | "version": 3 216 | }, 217 | "file_extension": ".py", 218 | "mimetype": "text/x-python", 219 | "name": "python", 220 | "nbconvert_exporter": "python", 221 | "pygments_lexer": "ipython3", 222 | "version": "3.6.9" 223 | } 224 | }, 225 | "nbformat": 4, 226 | "nbformat_minor": 4 227 | } 228 | -------------------------------------------------------------------------------- /Data Analysis.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import numpy as np\n", 10 | "import pandas as pd\n", 11 | "from os import listdir\n", 12 | "import matplotlib.pyplot as plt" 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": 2, 18 | "metadata": {}, 19 | "outputs": [], 20 | "source": [ 21 | "def genNumbers(path):\n", 22 | " means = []\n", 23 | " variances = []\n", 24 | " stds = []\n", 25 | " states = []\n", 26 | "\n", 27 | " for state in listdir(path):\n", 28 | " df = pd.read_csv(path+state, delimiter=',', index_col=0, parse_dates=True)\n", 29 | " data = df.iloc[:,0:1].values\n", 30 | " means.append(data.mean(axis=0)[0])\n", 31 | " variances.append(data.var(axis=0)[0])\n", 32 | " stds.append(data.std(axis=0)[0])\n", 33 | " states.append(state.replace(\".csv\", \"\"))\n", 34 | " \n", 35 | " return (states, means, variances, stds)\n" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": 28, 41 | "metadata": {}, 42 | "outputs": [], 43 | "source": [ 44 | "def graph(dist, name, states, color):\n", 45 | " x_pos = [i for i, _ in enumerate(states)]\n", 46 | " plt.figure(figsize=(16, 4))\n", 47 | " plt.bar(x_pos, dist, color=color)\n", 48 | " plt.xlabel(\"Data File\")\n", 49 | " plt.ylabel(name)\n", 50 | " plt.title(\"Data {} Dist\".format(name))\n", 51 | "\n", 52 | " plt.xticks(x_pos, states)\n", 53 | "\n", 54 | " plt.savefig(\"data_plots/{}.png\".format(name))\n", 55 | " plt.show()" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 29, 61 | "metadata": {}, 62 | "outputs": [ 63 | { 64 | "data": { 65 | "image/png": "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\n", 66 | "text/plain": [ 67 | "
" 68 | ] 69 | }, 70 | "metadata": { 71 | "needs_background": "light" 72 | }, 73 | "output_type": "display_data" 74 | }, 75 | { 76 | "data": { 77 | "image/png": "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\n", 78 | "text/plain": [ 79 | "
" 80 | ] 81 | }, 82 | "metadata": { 83 | "needs_background": "light" 84 | }, 85 | "output_type": "display_data" 86 | }, 87 | { 88 | "data": { 89 | "image/png": "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\n", 90 | "text/plain": [ 91 | "
" 92 | ] 93 | }, 94 | "metadata": { 95 | "needs_background": "light" 96 | }, 97 | "output_type": "display_data" 98 | }, 99 | { 100 | "name": "stdout", 101 | "output_type": "stream", 102 | "text": [ 103 | "Mean of Means 15.930103301004547 - Std of Means - 13.946258320413394\n", 104 | "Mean of Stds 15.308431088260235 - Std of Stds - 9.226917504443955\n" 105 | ] 106 | }, 107 | { 108 | "data": { 109 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAA6wAAAEWCAYAAABi9Rp+AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+j8jraAAAgAElEQVR4nO3dd7gtZXn38e9PwAoWFAlFORYs2FCJNRp7UFEwUQQViSESE01ejA1LgqSpibFFjcGKDSQqisYawYiiiYAI2AugKMIRBERRRO73j3k2LBar7bL2nnPO93Nd69p7+j2zpt3zPPOsVBWSJEmSJPXNtdY6AEmSJEmSRjFhlSRJkiT1kgmrJEmSJKmXTFglSZIkSb1kwipJkiRJ6iUTVkmSJElSL5mwSpK0CEk+m+RPxwxbl6SSbL7acW0MklyS5NZrHYckqT9MWCVJqybJmUkuTfLzJBcmOSHJM5LMdD1aiYSwTX/boX4vTfLupc5zHtq2etiE4Q9q63L0UP+7tf6fnXuQM2qxXtES0kuSnJ3kqCS/OzheVW1ZVd+fYV5nzzdiSVJfmLBKklbbY6pqK2An4OXAC4C3rm1IG6z1wH2T3HSg3/7At9conkl+XFVbAlsB9wG+CRyf5KFrG5Ykqc9MWCVJa6KqLqqqY4AnAvsnuTNAkkcn+UqSi5P8MMlLByb7XPt7YSupu2+S2yQ5Nsn5SX6a5D1Jbryc2JLcL8mXk1zU/t5vzHibJXllW+73gUcPDd8+yTFJLkjy3SRPHxj2jiT/MNB9ZclhkncBtwQ+0tbz+WNCvQz4ELDPQjx02/M9Q3HcIcmnWxzfSrL3wLCx23ugRHv/JD9o6/nigeH3SnJim/bcJK+auGGB6pxdVX8LvAV4xcD8riz9TvKoJF9vpfE/SvLcJDcAPg5sP1Bau/20ZUqSNlwmrJKkNVVV/wecDTyg9foF8FTgxnQJ4J8n2asNe2D7e+NWffSLQICXAdsDdwRuAbx0qfEk2Rr4L+B1wE2BVwH/NVSKueDpwB7A3YHdgMcPDT+yrdv2bdg/JXnItBiqaj/gB3Sl0VtW1T9PGP2ddNsL4A+A04EfD6zPDYBPA+8Fbk6X3L4xyS5tlEnbe8HvAbcHHgr8bZI7tv6vBV5bVTcEbgMcNW3dhnwQuEeLcdhbgT9rpfF3Bo6tql8Aj6SV1rbPj0dMK0naSJiwSpL64MfA1gBV9dmqOq2qrqiqU4EjgN8fN2FVfbeqPl1Vv66q9XQJ5tjxm5PbO7QXJrkQOHhg2KOB71TVu6rq8qo6gq766mNGzGdv4DVV9cOquoAucQYgyS2A+wMvqKpfVdUpdCWKTx0xnyWrqhOArZPcvs37nUOj7AGcWVVvb+vzFeADwBPa9LNs70Or6tKq+irwVeBurf9vgNsmuVlVXVJVX1pk+D+me+AwqkT8N8AuSW5YVT+rqpMXOW9J0kbAhFWS1Ac7ABcAJLl3kuOSrE9yEfAM4GbjJkyybZIjW7XRi4F3Txq/uUdV3XjhQ/cu7YLtgbOGxj+rxThse+CHQ+MNDrugqn4+w3yW613As4AHA0cPDdsJuPdQgv5k4Hdg5u39k4H/fwls2f4/ALgd8M1WdXqPRca9A1DAhSOG/RHwKOCsJP+T5L6LnLckaSNgwipJWlOtpdgdgM+3Xu8FjgFuUVU3At5EVwoHXXIz7J9a/7u0qqlPGRh/KX5Ml+QNuiXwoxHjnkNXBXlwvMH5bJ1kqzHz+QVw/YFhvzM071HrOs67gL8APlZVvxwa9kPgfwYT9FaV9s/b8Enbe6Kq+k5V7UtX1fgVwPvHVO8d53HAya2q7/C8v1xVe7Z5f4irqhsvZrtIkjZwJqySpDWR5IatRO5I4N1VdVobtBVdyeSvktwLeNLAZOuBK4DB3+rcCrgEuCjJDsDzlhnax4DbJXlSks2TPBHYBfjoiHGPAv4qyY5JbsJA1eKq+iFwAvCyJNdNcle6EsmFn885BXhUkq2T/A5w0NC8zx1az7Gq6gy6arwvHjH4o2199kuyRfv87sB7qJO290RJnpJkm6q6gqtKSa+YMk2S7JDkEOBPgReNGOfaSZ6c5EZV9Rvg4oH5ngvcNMmNZo1TkrThMmGVJK22jyT5OV3J34vp3jl92sDwvwD+ro3ztww05NNKD/8R+EKr3nof4FDgHsBFdI0lfXA5wVXV+XTvfT4HOB94PrBHVf10xOhvBj5J917nySOWvS+wjq609WjgkKr67zbsXW26M4FPAe8bmvZlwEvaej53hrg/P6oBolYl+RF0jS39mK567yuA67RRxm7vGewOfC3JJXQNMO1TVZeOGXf7Nt4lwJeBuwAPqqpPjRl/P+DMVs37GXTVmKmqb9K9Z/v9tm1sJViSNmKpsmaNJEmSJKl/LGGVJEmSJPWSCaskSZIkqZdMWCVJkiRJvWTCKkmSJEnqpc3XOoBZ3OxmN6t169atdRiSJEmSpDk46aSTflpV2wz33yAS1nXr1nHiiSeudRiSJEmSpDlIctao/lYJliRJkiT1kgmrJEmSJKmXTFglSZIkSb1kwipJkiRJ6iUTVkmSJElSL5mwSpIkSZJ6yYRVkiRJktRLJqySJEmSpF4yYZUkSZIk9dLmax2AJEkbqxyaRU9Th9QcIpEkacNkCaskSZIkqZdMWCVJkiRJvWTCKkmSJEnqJRNWSZIkSVIvmbBKkiRJknrJhFWSJEmS1EsmrJIkSZKkXjJhlSRJkiT1kgmrJEmSJKmXNl/rACRJKy+HZtHT1CE1h0gkSZKWzhJWSZIkSVIvmbBKkiRJknrJhFWSJEmS1Eu+wypJPbOU909hZd9B9R1YSZLUB5awSpIkSZJ6yYRVkiRJktRLJqySJEmSpF6a6zusSc4Efg78Fri8qnZLsjXwPmAdcCawd1X9bJ5xSJIkSZI2PKtRwvrgqtq1qnZr3QcDn6mqnYHPtG5JkiRJkq5mLaoE7wkc3v4/HNhrDWKQJEmSJPXcvBPWAj6V5KQkB7Z+21bVOe3/nwDbjpowyYFJTkxy4vr16+ccpiRJkiSpb+b9O6y/V1U/SnJz4NNJvjk4sKoqycgf7quqw4DDAHbbbTd/3E+SJEmSNjFzLWGtqh+1v+cBRwP3As5Nsh1A+3vePGOQJEmSJG2Y5pawJrlBkq0W/gceAZwOHAPs30bbH/jwvGKQJEmSJG245lkleFvg6CQLy3lvVX0iyZeBo5IcAJwF7D3HGCRJkiRJG6i5JaxV9X3gbiP6nw88dF7LlSRJkiRtHNbiZ20kSZIkSZpq3q0EawORQ7PoaeoQG2+WJEmSND+WsEqSJEmSesmEVZIkSZLUSyaskiRJkqReMmGVJEmSJPWSCaskSZIkqZdMWCVJkiRJvWTCKkmSJEnqJRNWSZIkSVIvmbBKkiRJknrJhFWSJEmS1EsmrJIkSZKkXjJhlSRJkiT1kgmrJEmSJKmXTFglSZIkSb1kwipJkiRJ6iUTVkmSJElSL5mwSpIkSZJ6yYRVkiRJktRLJqySJEmSpF4yYZUkSZIk9ZIJqyRJkiSpl0xYJUmSJEm9ZMIqSZIkSeolE1ZJkiRJUi+ZsEqSJEmSesmEVZIkSZLUS3NPWJNsluQrST7aum+V5H+TfDfJ+5Jce94xSJIkSZI2PKtRwvr/gG8MdL8CeHVV3Rb4GXDAKsQgSZIkSdrAzDVhTbIj8GjgLa07wEOA97dRDgf2mmcMkiRJkqQN07xLWF8DPB+4onXfFLiwqi5v3WcDO8w5BkmSJEnSBmhuCWuSPYDzquqkJU5/YJITk5y4fv36FY5OkiRJktR38yxhvT/w2CRnAkfSVQV+LXDjJJu3cXYEfjRq4qo6rKp2q6rdttlmmzmGKUmSJEnqo7klrFX1wqrasarWAfsAx1bVk4HjgMe30fYHPjyvGCRJkiRJG65FJaxJrpXkhstc5guAv07yXbp3Wt+6zPlJkiRJkjZCUxPWJO9NcsMkNwBOB76e5HmLWUhVfbaq9mj/f7+q7lVVt62qJ1TVr5cWuiRJkiRpYzZLCesuVXUx3c/PfBy4FbDfXKOSJEmSJG3yZklYt0iyBV3CekxV/Qao+YYlSZIkSdrUzZKw/gdwJnAD4HNJdgIunmdQkiRJkiRtPm2Eqnod8LqBXmclefD8QpIkSZIkaYaENcl1gD8C1g2N/3dzikmSJEmSpOkJK93vpF4EnATYoq8kSZIkaVXMkrDuWFW7zz0SSZIkSZIGzNLo0glJ7jL3SCRJkiRJGjBLCevvAX+c5Ay6KsEBqqruOtfIJEmSJEmbtFkS1kfOPQpJkiRJkobM8rM2ZwEkuTlw3blHJEmSJEkSM7zDmuSxSb4DnAH8D3Am8PE5xyVJkiRJ2sTN0ujS3wP3Ab5dVbcCHgp8aa5RSZIkSZI2ebMkrL+pqvOBayW5VlUdB+w257gkSZIkSZu4WRpdujDJlsDxwHuSnAf8Yr5hSZIkSZI2dbOUsO4J/BI4CPgE8D3gMfMMSpIkSZKkWVoJ/kWSnYCdq+rwJNcHNpt/aJIkSZKkTdksrQQ/HXg/8B+t1w7Ah+YZlCRJkiRJs1QJfiZwf+BigKr6DnDzeQYlSZIkSdIsCeuvq+qyhY4kmwM1v5AkSZIkSZqtleD/SfIi4HpJHg78BfCR+YYlSZKkvsihWfQ0dYjlG5KWb5YS1oOB9cBpwJ8BHwNeMs+gJEmSJEmapZXgK4A3t48kSZIkSatibMKa5NRJE1bVXVc+HEmSJEmSOpNKWK+ga1zpvXTvrF66KhFJkiRJksSEd1iraldgX2BLuqT1H4E7AT+qqrNWJzxJkiRJ0qZqYqNLVfXNqjqkqu5BV8r6TuDZqxKZJEmSJGmTNrHRpSQ7APsAjwN+RpesHr0KcUmSJEmSNnGTGl36H2Ar4CjgacD5bdC1k2xdVRdMmnGS6wKfA67TlvP+qjokya2AI4GbAicB+1XVZcteE0mSJEnSRmVSleCdgJvQ/fbqJ4ET2+ek9neaXwMPqaq7AbsCuye5D/AK4NVVdVu6UtsDlh6+JEmSJGljNbaEtarWLWfGVVXAJa1zi/Yp4CHAk1r/w4GXAv++nGVJkiRJkjY+ExtdWq4kmyU5BTgP+DTwPeDCqrq8jXI2sMM8Y5AkSZIkbZgmNrq0XFX1W2DXJDema6zpDrNOm+RA4ECAW97ylvMJUNKKy6FZ9DR1SM0hEkmSJG3o5lrCuqCqLgSOA+4L3DjJQqK8I/CjMdMcVlW7VdVu22yzzWqEKUmSJEnqkakJa5J3zdJvxDjbtJJVklwPeDjwDbrE9fFttP2BDy8mYEmSJEnSpmGWKsF3GuxIshlwzxmm2w44vI1/LeCoqvpokq8DRyb5B+ArwFsXGbMkSZIkaRMw6XdYXwi8CLhekosXegOXAYdNm3FVnQrcfUT/7wP3WlK0kiRJkqRNxtgqwVX1sqraCviXqrph+2xVVTetqheuYoySJEmSpE3QLFWCP57kgcM9q+pzc4hHkiRJkiRgtoT1eQP/X5euOu9JwEPmEpEkSZIkScyQsFbVYwa7k9wCeM3cIpIkSZIkiaX9DuvZwB1XOhBJkiRJkgZNLWFN8m9Atc5rAbsCJ88zKEmSJEmSZnmH9cSB/y8HjqiqL8wpHkmSJEmSgNneYT08ybWB27Ve35pvSJIkSZIkzVYl+EHA4cCZQIBbJNnfn7WRJEmSJM3TLFWC/xV4RFV9CyDJ7YAjgHvOMzBJkiRJ0qZtloR1i4VkFaCqvp1kiznGpA1UDs2ip6lDavpIkiRJkjZJMzW6lOQtwLtb95O5ekNMkiRJktR7FrBseGZJWP8ceCbwV637eOCNc4tIkpbJi5EkSdLGYZZWgn8NvKp9JEmSJElaFWMT1iSnAWOLHKrqrnOJSJIkSZIkJpew7tH+PrP9fVf7+xQmJLKSJEmSJK2EsQlrVZ0FkOThVXX3gUEvSHIycPC8g5MkSZIkbbquNcM4SXL/gY77zTidJEmSJElLNksrwQcAb0tyIyDAz4A/mWtUkiRJkqRN3iytBJ8E3K0lrFTVRXOPSpIkSZK0yZvUSvBfj+kPQFX5MzeSJEmSpLmZVMK61apFIUmSJEnSkEmtBB+6moFIkiRJkjRoamu/SXZMcnSS89rnA0l2XI3gJEmSJEmbrll+nubtwDHA9u3zkdZPkiRJkqS5mSVh3aaq3l5Vl7fPO4Bt5hyXJEmSJGkTN0vCen6SpyTZrH2eApw/78AkSZIkSZu2qb/DCvwJ8G/Aq4ECTgCeNs+gJEmSJPVLDs2ip6lDag6RaFMyNWGtqrOAx65CLJIkSdJGyWRPWpqxCWuSf6MrUR2pqv5q0oyT3AJ4J7Btm89hVfXaJFsD7wPWAWcCe1fVzxYdubQR8mImSZIkXWXSO6wnAie1z2MH/l/4THM58Jyq2gW4D/DMJLsABwOfqaqdgc+0bkmSJEmSrmZsCWtVHb7wf5KDBrtnUVXnAOe0/3+e5BvADsCewIPaaIcDnwVesKioJUmSJEkbvVlaCYYJVYNnkWQdcHfgf4FtWzIL8BO6KsOjpjkwyYlJTly/fv1yFi9JkiRJ2gDNmrAuWZItgQ8AB1XVxYPDqqoYkwxX1WFVtVtV7bbNNv7sqyRJkiRtaiY1uvRzrkomr59kIdkMXa55w2kzT7IFXbL6nqr6YOt9bpLtquqcJNsB5y09fEmSJEnSxmrSO6xbLWfGSQK8FfhGVb1qYNAxwP7Ay9vfDy9nOZK00mytWZIkqR+m/g7rMtwf2A84Lckprd+L6BLVo5IcAJwF7D3HGCRJkiRJG6i5JaxV9Xm66sOjPHRey5UkSZIkbRzm3uiSJEmSJElLMc8qwZIkSZJ0JduJ0GJZwipJkiRJ6iVLWCVJ0kiWhEiS1poJa094UyBJkiRJV2fCKkmSJEmrxIKqxfEdVkmSJElSL1nCKq0gn5hJkiRJK8eEVWqWkmyCCackzZMPAiVp02aVYEmSJElSL1nCKknqJUvWJEmSJaySJEmSpF4yYZUkSZIk9ZIJqyRJkiSpl0xYJUmSJEm9ZMIqSZIkSeolWwmWJEmawBarJWntWMIqSZIkSeolS1glSZKkKSxpl9aGJaySJEmSpF4yYZUkSZIk9ZJVgiX1ilWuJGnj47ld0lKZsEqSpLkxUZEkLYcJqzYa3hRJkiRJGxcTVkmSpI2cD3UlbahsdEmSJEmS1EuWsErSCrMkQ5IkaWWYsEqStJHy4Yk2Fu7L0qZrblWCk7wtyXlJTh/ot3WSTyf5Tvt7k3ktX5IkSZK0YZtnCes7gNcD7xzodzDwmap6eZKDW/cL5hiDJGkTZYmMJEkbvrmVsFbV54ALhnrvCRze/j8c2Gtey5ckSZIkbdhWu5XgbavqnPb/T4Btx42Y5MAkJyY5cf369asTnSRJkiSpN9as0aWqqiRj615V1WHAYQC77bZbr+toWe1MkiRJklbeaies5ybZrqrOSbIdcN4qL1+SJEnaIFlIok3RaiesxwD7Ay9vfz+8ystXj3kSlqSr87woaSV5TtGGaG4Ja5IjgAcBN0tyNnAIXaJ6VJIDgLOAvee1/E2NJyBJkiRJG5u5JaxVte+YQQ+d1zIlSZIkSRuPNWt0SZKkPrPmirRx8ZjWxmJT25dNWCVdzaZ2EpQkSVJ/rfbvsEqSJEmSNBNLWCVJkubImivSxsPjefWZsEobEU+ikiRJ2piYsEqSJPWYDyMlbcp8h1WSJEmS1EsmrJIkSZKkXrJKsCRpxVmFUZIkrQRLWCVJkiRJvWTCKkmSJEnqJasES5IkSdog+MrJpseEVZIkbbS8uZWkDZtVgiVJkiRJvWTCKkmSJEnqJRNWSZIkSVIvmbBKkiRJknrJhFWSJEmS1EsmrJIkSZKkXjJhlSRJkiT1kgmrJEmSJKmXTFglSZIkSb1kwipJkiRJ6iUTVkmSJElSL5mwSpIkSZJ6yYRVkiRJktRLJqySJEmSpF4yYZUkSZIk9dKaJKxJdk/yrSTfTXLwWsQgSZIkSeq3VU9Yk2wGvAF4JLALsG+SXVY7DkmSJElSv61FCeu9gO9W1fer6jLgSGDPNYhDkiRJktRjqarVXWDyeGD3qvrT1r0fcO+qetbQeAcCB7bO2wPfWtVAV87NgJ+u4fR9iGGtp+9DDK5DP2JY6+n7EIPr4DboSwyug9ugLzG4Dm6DvsTQh3VYSztV1TbX6FtVq/oBHg+8ZaB7P+D1qx3HKq7viWs5fR9iWOvp+xCD69CPGNZ6+j7E4Dq4DfoSg+vgNuhLDK6D26AvMfRhHfr4WYsqwT8CbjHQvWPrJ0mSJEnSldYiYf0ysHOSWyW5NrAPcMwaxCFJkiRJ6rHNV3uBVXV5kmcBnwQ2A95WVV9b7ThW0WFrPH0fYljr6fsQg+vQjxjWevo+xOA6uA36EoPr4DboSwyug9ugLzH0YR16Z9UbXZIkSZIkaRZrUSVYkiRJkqSpTFglSZIkSb1kwroCklSSfx3ofm6Sl7b/X5rkR0lOSfKdJB9MssuY+Vwy8P+jknw7yXFJ/nyg/72TnJpkiwnx/LYt7/QkH0ly49Z/XZLTJ0z3O0mOTPK9JCcl+ViS27VhByX5VZIbzbDcryX5apLnJLlWG/agJBe14Qufh42Yx45JPty21feSvDbJtdv0Hx0Y7x+SfCLJdYamn/W7WPjceGjadw90b55k/cJyk/xx6/5Ki++TSe43Yvlj5zHQ/0NJvjRhW17S/q5Lcmlb5jeS/F+SP54w3XFJ/mCo30FJ/j3JzZL8Jskzxk3fxr/pwPb5ycA2+16SM5Js3ca7SeteN2Y+w/vTcUl+2eZ1QZv2lCT/PTTd1G2YZK92HHwjyWlJ9hqax7ZJ3pvk+23ZX0zyuIHhr2nrNfUcOPRdjD1+Jkw/bZ987oRp92rT36F1P3No/z29Db/jIuaxqPUYM/2lbflfT/LODJ2Pkrw6yUED3Z9M8paB7n9NckWS2w9N95okLxjqN8tx+foJ8Y/c/kke3vaLtP6btePsfgPjjjsWTpn0vc64DU8fGP70tp/eZMz0k86LC+fVbyZ55SLW//eTfHFo3M2TnJtk+xHzGXV92inJ7ZN8tsXwjSTXeHdq2rZK8tS2L5/WvoPnjph+lnPz4LGxSxs2y754WZK7DPR7XpL/WOTyr0hy14FxTs/AuTGjz81/07bZtHPiLOvw1wNxvXz4OxhYj5nPRUnOTHKzoX4j7xOS3CnJsUm+1fbTv0m6Y2uW7ZjkaQPf3WVtXzhlcF1miL+S3HZg+EGt325Dcbw43X3KqW0Z92778Ldav28meX0G7g9mWYfWvW1bn6+mOz9+bNR30ca9ZKh76n1WG2+m+6Q27juSPH7EPAbvE/8zyfWH1mfkPjTDOlx5Ph61T42bPt05sZL85cCw12fM/c4ijomJ17qB7bDwWTdqO46Z9hrX0rbOv8hV18dLB+Y96nu4ZLjfwLCZ7lPG7M9bJHl520dOTnete+S0deozE9aV8WvgDzN0Yh/w6qratap2Bt4HHJvkmj+K2yR5KPA64JF0rSg/L8k2bad9PfAXVfWbCfFc2pZ3Z+AC4JnTVqBdWI4GPltVt6mqewIvBLZto+xL18LzH86w3DsBD2/xHzIw/Pg2fOEzfFEO8EHgQ21b3Q7YEvjHofFeAtwfeFxV/Xoohlm/i4XPhQPDfgHcOcn1WvfDueZPLr2vqu7e4ns58MFcPVmYOo92EbwncKMktx4T56DvtWXekW5/OCjJ08aMe0QbZ9A+rf8TgC/RfZdjVdX5C9sHeBNXbbPbAP9Ot960v4dV1ZnD8xizPx0E/EGb7zHA89p8hx9cTNyGSe4GvBLYs22TxwKvTLtZbMv+EPC5qrp1W/Y+dD+hRTuOHgf8EPj9SdtihUzbJyfZF/h8+0tVvWFw/6Xbju+pqm/MOo/lxtB8ry3/LnTbde+hab4A3A+u3N43A+40MPx+wGcZ2FfbeI8Hjhya1yzH5SQjt39VfRo4Czig9fpLut+uO2FgnHHHwq7j5jvG2O8gyX5t2X9QVT8bMXzaefH4Fs/dgT2S3H+W9QeOB3ZMstNAv4cBX6uqH49bkcHrU1Wd1f5f2C53BP5txGRjt1W7iToIeERV3QW4D3DR0GiznpsHz+1fb/1n2Rf/FnhjOjsAzwAOXuTyzwZePGLdF4w6Nz8a+LMZzomzrMMJLa5vA09o+82w5ZyLpt0nHAO8vKpuD9ytxfQXQ7MYux2r6u0Dx9aPgQe37sHvYVr8p3H1bfwE4GqNeia5L7AHcI+quivdPv/DNvjJrd9d27I+PGIZ0/aFvwM+XVV3q6pduPp+NM3U+6xZ75NmMHifeBndPg/T96F5Og/4f+l+QWSaWY+JaS4dOm+cuciYRzmk7cePol0r2+f9s85g1vuUCfvz3wPbAXeuqnsAewFbLXWF+sCEdWVcTtci17OnjVhV7wM+BTxp1PAkDwTeDOxRVd+rqnPpbs7/me6EcmpVfX4RsX0R2GGG8R4M/Kaq3jQQ61er6vgkt6E7Ib6EGW96q+o84EDgWYs46T0E+FVVvb3N47d02/RPgIWnf8+hS4QfU1WXjpjHzN/FGB+ju4mAbl2PGDdiVR3XlnXgIufxh8BH6G7Mh29gJqqq7wN/DfzVmFHeDzx64YSf7gn/9nQ3p/sCzwF2SLLjYpY74NXAfdqTzd+j2zdHGbs/zbicSdvwucA/VdUZbb5nAC8DnteGPwS4bGjZZ1XVwo30g+huYv6dpSdxi7GkfTLJlnTb+ABG7CftXLE317wpnHkey42hHaP/xzXPMScA923/3wk4Hfh5ulL56wB3pNseTxyY5oHAWS0JGjbzcTnCpO3/bOCFSe4EPAt4wYhxljLfK03ahkn2pruhfURV/XTMLKaeF1v/S4FTuOZ3MTLOqroCOGoopoWHW+PW5WrXp9Z7O7pkbWG+p42YdNK2eiHw3IUkuap+XVVvHjHeUveBWfbFVwHnAE+lO8e9dMTDg2nL/yhwpwzVGhgw6dy8EutwcovrtcAPBsYftNzr48jzOl3S9IWq+lTr90u642lUsjavYxm6B5V7ArT7louA4eNqO+CnCw+7q+qnww9oquoy4PnALdsD0sWsw/DxcOr01boy3lnus2Y6Hwcn9twAAA0iSURBVCzS8cBCyfS0fWie1gOfAfafYdxZjokL5hLl6ngQs92nXGN/Bi4Eng785UD/c6vqqLlGPGcmrCvnDcCTM6UqR3MycIcR/a9Dd8Ldq6q+OdD/TcAudDfkz581oCSbAQ9ltt+5vTNw0phh+9AlV8cDt0+y7ZjxrqYlV5sBN2+9HpCrV724zdAkdxqOoaoupjtx3pauVPUZdE/2x1ajYPJ38eyB5R83YviRwD5Jrkv3lPV/p6zmqO9y2jwWLnBHsLSEadz+Q1VdQJdALFT92IfupnRHYLuq+r/W/cRR009TXcn+8+hu6g6q8SX9k/anWUzahtfYT4ATuerp6p3ottE4C9v/aLobyLHV61fQYs4PC/YEPlFV3wbOT3LPhQGtlP4dwP7tGFn0PJYbQ4vjusC9gU8M9m83gJcnuSXdk+4v0n2H9wV2A05rN7pXDNwQTkqWFntcDhu5/avqHOA1Lb5/aMfPsuc7ZNw23ImuxswjquonE6afdl4EIF114p2Bzy0izitL/dpN3qOAD4yJY9z16dV0tYY+nuTZGVGNckoMs54rpu0DTxy6vlwPZt4XL6Mr5f1HYJuqetcSln8F3YPlF40Kfty5uWr6TzXMsg5093MPo3sYOunaMuv18RS6hHrQuO9q1D76PWDLJDccGncux3JzMfDDJHem277vGzHOp4BbpKvS/sYkI0uvWiL4VUZfayetwxuAt6arAv7ijKheP8as91nTzgcPGPoOHztpoUk2p9snT2vrM8s+NOh6Q8v7uxmmmeQVwHPb/etYMx4Tl82wvMH4j15e6Ctq1vuUUfvzbYEfTLk32OCYsK6QtmO8k/ElX4PGlTj+hu6p0QGDPduT8P8APl5V588w/+u1E8dP6KrqfHqGaSbZFziyxfEBumo2SzFcJfh70ye5mu/SbbuHTxppyncxWCX4wSOmPRVYR7fOY989GXCN73LSPNpFaGfg8+0G9jft4roY00qsB6ueLSQBT6RLVKG7KC6nZPGRdKURi417Zkv4HsZK8oZ07xN9uZVuPIquOtXFdBe4P5g8h+Vb5Plhwb5cVT12+Dt7E/CuqvrCMuaxnBhu084x5wLnjClFOIHuRmLhZuKLA90LcR9Bd+O3OV2Vpf8cFcRy94cp2/8NwGZV9Y4Vnu+CcdtwPd1N5nB16sV6QJKv0lVL/OSo5HdcnFV1Il1ScXu64/p/JyTt465Pb6crzfhPulKBL2WobYFJMcxqhn1guErwYA2cqftiuwE+lq5EYynLB3gvXQ2UW40ZPurcPKtp67AHcFxb7w8Ae4266V/E9XGhau6KmvOxDFfVXNqL7mZ/ePpL6F7JOZDuGHxfxrcLMfJaO2kdquqTwK3paiLcAfhKJrwCNmAu91mML7BYuE88ke489FZm3IeGXDq0vL9dYtzAlQUd/8uYWohDZrnGTDMY/+Omj371cBfZfyaLuU8ZtT/TnYc3OiasK+s1dBfzG0wZ7+7AqHfOrqC7eblXkuGntFe0zywubSeOnehOuFPfYaWrenCN0pd0DVHsDHw6yZl0F4KZbnrTvZ/5W7r3Embx9eEY2tPZW9Ilq+fSHcSvSXKNZHPIrN/FKMfQVXWd5WZi3Hc5bh57AzcBzmjbcx2LTyLGLXPBh4GHJrkHcP2qOqkt44/bMo8B7ppk50UulyS70j0wuA/d0/jtxow6cn9apHHb8Br7SeteeFfpa8A9FgZU1TPpahpsQ3fSvzHd0+Qz6apqrka1YFjEPpmuYauHAG9pcT4P2Dud/emO7b9fyjyY/sBjlukX3mG9DXDPJKOe4i+8Y3QXuupaX6J7+j34btGRbZ4Po3vd4dwJIS3muBxl5PZvN4jLucEY+71O2Ya/pDufPSPJkyfMf9p58fiquhtdycsB7RhdTJwLSdS0BGrs9amqflxVb6uqPemqbY57mDUqhsWcK5a6D8yyL8L06+zE5VfV5cC/Mr5q+ahz80qtw77Aw9p+dhJwU7p9b5SlXh/HfVej9tFbA5eMKeWZy7HcfBTYjwklTFX126r6bFUdQld1+Y+Gx2mJ2l0Yf60duw5VdUFVvbeq9qN7J/WBk1ZmkfdZ084HsxpM1P6y1TJYzD40T/9EdwxNu1bNelzPy/l093ODtuaa1dAXa1H3KSP258fQVWcfrt2wQTNhXUHtyfRRDD2BHpTkj4BHMP6C90u6dyOenGTsfGaM55d0TyGf00owJjkWuE6SK9/HTNeIzevo3udZ1z7bA9vn6g11XEN7ovgm4PWzVHlqPgNcP8lT2zw2o7v4v4Pu5o5WKvmHwLsn3JjN9F1M8Dbg0Br9LtaVWtWLA+mepM46j32B3Re2J92FZ+Z3C9O99/RKRjdsAlz5xO24FsMR6Vp63rKqdhhY7stYZKKWJHSlDwdV1Q+Af2H8O6wj96ckD1jEIsdtw1fSvXe4rs13HV01vIXWI48FrpuB1rW56t2efYE/HdgOtwIentZC4jwtcp98PF0J6k4t1lsAZwAPoLuYP7ndHC9lHreYMeSp01f3vszBdO8hDjuB7on9Be2CegHdRfi+bdhCtcGf0jXgNe3mdabjcpxlnhOWOt+J27C6d/13B/4pQy3IDph6XmzzOoNuO45MlibEeQTwFLob01GNzAzO4xrXpyS7L1RXS/I7dDe5IxvFGhPDy4B/adOSrrXTPx0TwlL3gan74oxmWf476B7AXKNUbfjcvIjlwuR1OIXu3HDLgXPbMxlzjl/GsTDuPuFbwO+ltfyfrjr26+iqSI8yt2O57aMvYEwjROlatR58WLsrXeNrg+NsQbdf/rDGv4M6ch2SPCRXtbi7Fd1DvR9MWaV9mf0+a6bzwWK15GbmfWieqnvl4Ot0idckK3VcL0k7ns9J8hC48gHl7nQN7C3HzPcpY/bnb9GVmL82V70zv02SpZba94IJ68r7V7rWygYtvBfyHdqNQVWtHzeDdtDtDrxkTMnFzKrqK8CpTG8ZtuhaJHtYumbSv0Z3wn4Q16xWczSjk6yFdwG+Bvw3Xd36QweGD7/DerUmvgdieELbVt8GfsXQO0FV9WXgacAxueZ7sIMmfRdXNmE+PFFVnV1Vrxszz4X3pL7d4vqjGtFC66h5tGXtRPcUcGG8M4CLktx7wnrcJu1nbegu0q+r1uDCBEfQtdS48B7K8Hf4ARZ/IXo63VPrhSrmbwTumBHvAE3Ynya9qzc8j5HfQ1WdQndD8pEk36R73+b5rf/CsvcCfj/dz0T8H3A4XYvVuwP/NTCvX9BdXKZdGBfcPsnZA5/FXgCG98nN6VqjHDbuO3saXfL9waH9eNSDgHHzeOGM6zFp+kEforuBGo7hNLp1/dJQv4vq6g0MHUFXde6DI2K40pTjclajzgkrYdx8p27Ddg54LPC2JPcansGs58XmTcADR53XxsXZzl+/AI5tx8NEI65PjwBOT1ct+ZN0Ld1OOs6vFkNVfYzuXd7/bueJk4GRJQMznpsXPoM/OTbrvjjRLPtgK6l6HVe13TBs8Ny8GGPXga4xpGPr6q3mfxh4TEZUz24WfSxMOa/vSbdPfKvF9WW673XUfOZ6LFfVkVU1rh2DLYHD0/3kyKl07YO8tA17T+t3Ol3p7Z7jFj5hHe4JnNjm80XgLe2eZZJ9mPE+a5Hng8V4HIvfh+bpH2kt+0+wIsf1GA8dukaOa4DqqcDfpKtefSzdQ4zFvO52/aHlvIjF3aeM259fQldF+Ovpfnrno3TveG+wUjMXfkmSVlK6Rh7e3G7aJUmSNMQSVklaA0lOo3tf7lNrHYskSVJfWcIqSZIkSeolS1glSZIkSb1kwipJkiRJ6iUTVkmSJElSL5mwSpK0DEl+u/CTXkm+muQ5SSZeX5OsS/KkZSzryp/mSnLCwDxPX+p6SJLUR5uvdQCSJG3gLq2qXQGS3Bx4L91viR4yYZp1wJPauEta1oD7jRxTkqSNgCWskiStkKo6DzgQeFY665Icn+Tk9llILl8OPKCVkj57wnhTJblkRL/NkvxLki8nOTXJn63MGkqStLosYZUkaQVV1feTbAbcHDgPeHhV/SrJzsARwG7AwcBzq2oPgCTXHzPesOslOaX9f0ZVPW5MGAcAF1XV7ya5DvCFJJ+qqjNWbEUlSVoFJqySJM3PFsDrk+wK/Ba43TLHG1UleJRHAHdN8vjWfSNgZ8CEVZK0QTFhlSRpBSW5NV3SeR7de6znAnejew3nV2Mme/aM480cBvCXVfXJZc5HkqQ15TuskiStkCTbAG8CXl9VRVeyeU5VXQHsB2zWRv05sNXApOPGW6pPAn+eZIsW1+2S3GCZ85QkadVZwipJ0vIsvFe6BXA58C7gVW3YG4EPJHkq8AngF63/qcBvk3wVeMeE8ZbqLXQtEZ+cJMB6YK9lzlOSpFWX7gGwJEmSJEn9YpVgSZIkSVIvmbBKkiRJknrJhFWSJEmS1EsmrJIkSZKkXjJhlSRJkiT1kgmrJEmSJKmXTFglSZIkSb30/wGYVGkdEPIF9gAAAABJRU5ErkJggg==\n", 110 | "text/plain": [ 111 | "
" 112 | ] 113 | }, 114 | "metadata": { 115 | "needs_background": "light" 116 | }, 117 | "output_type": "display_data" 118 | }, 119 | { 120 | "data": { 121 | "image/png": "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\n", 122 | "text/plain": [ 123 | "
" 124 | ] 125 | }, 126 | "metadata": { 127 | "needs_background": "light" 128 | }, 129 | "output_type": "display_data" 130 | }, 131 | { 132 | "data": { 133 | "image/png": "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\n", 134 | "text/plain": [ 135 | "
" 136 | ] 137 | }, 138 | "metadata": { 139 | "needs_background": "light" 140 | }, 141 | "output_type": "display_data" 142 | }, 143 | { 144 | "name": "stdout", 145 | "output_type": "stream", 146 | "text": [ 147 | "Mean of Means 17.677527937516047 - Std of Means - 13.147117763916889\n", 148 | "Mean of Stds 15.657197190167292 - Std of Stds - 9.318549800818786\n" 149 | ] 150 | } 151 | ], 152 | "source": [ 153 | "(states, means, variances, stds) = genNumbers(\"samples/\")\n", 154 | "graph(means, \"Sample Means\", states, 'green')\n", 155 | "graph(variances, \"Sample Variances\", states, 'blue')\n", 156 | "graph(stds, \"Sample Standard Deviations\", states, 'red')\n", 157 | "\n", 158 | "print(\"Mean of Means {} - Std of Means - {}\".format(np.mean(means), np.std(means)))\n", 159 | "print(\"Mean of Stds {} - Std of Stds - {}\".format(np.mean(stds), np.std(stds)))\n", 160 | "\n", 161 | "(states, means, variances, stds) = genNumbers(\"holdout/\")\n", 162 | "graph(means, \"Holdout Means\", states, 'green')\n", 163 | "graph(variances, \"Holdout Variances\", states, 'blue')\n", 164 | "graph(stds, \"Holdout Standard Deviations\", states, 'red')\n", 165 | "\n", 166 | "print(\"Mean of Means {} - Std of Means - {}\".format(np.mean(means), np.std(means)))\n", 167 | "print(\"Mean of Stds {} - Std of Stds - {}\".format(np.mean(stds), np.std(stds)))" 168 | ] 169 | }, 170 | { 171 | "cell_type": "markdown", 172 | "metadata": {}, 173 | "source": [ 174 | "# Initial Findings\n", 175 | "
    \n", 176 | "
  • States have the same distribution across sample and holdout
  • \n", 177 | "
  • States have different distributions
  • \n", 178 | "
  • Distribution affects LSTM performance (ND with lower variance has better accuracy than NV)
  • \n", 179 | "
" 180 | ] 181 | }, 182 | { 183 | "cell_type": "code", 184 | "execution_count": 6, 185 | "metadata": {}, 186 | "outputs": [ 187 | { 188 | "name": "stdout", 189 | "output_type": "stream", 190 | "text": [ 191 | "Mean of Means 17.677527937516047 - Std of Means - 13.147117763916889\n", 192 | "Mean of Stds 15.657197190167292 - Std of Stds - 9.318549800818786\n" 193 | ] 194 | } 195 | ], 196 | "source": [ 197 | "\n" 198 | ] 199 | }, 200 | { 201 | "cell_type": "code", 202 | "execution_count": null, 203 | "metadata": {}, 204 | "outputs": [], 205 | "source": [] 206 | } 207 | ], 208 | "metadata": { 209 | "kernelspec": { 210 | "display_name": "Python 3", 211 | "language": "python", 212 | "name": "python3" 213 | }, 214 | "language_info": { 215 | "codemirror_mode": { 216 | "name": "ipython", 217 | "version": 3 218 | }, 219 | "file_extension": ".py", 220 | "mimetype": "text/x-python", 221 | "name": "python", 222 | "nbconvert_exporter": "python", 223 | "pygments_lexer": "ipython3", 224 | "version": "3.8.2" 225 | } 226 | }, 227 | "nbformat": 4, 228 | "nbformat_minor": 4 229 | } 230 | -------------------------------------------------------------------------------- /LSTM_Data_Analysis.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 2, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import pandas as pd\n", 10 | "import numpy as np\n", 11 | "from matplotlib.pyplot import figure\n", 12 | "import matplotlib.pyplot as plt" 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": 2, 18 | "metadata": {}, 19 | "outputs": [], 20 | "source": [ 21 | "#path = \"lstm-out/NO-SCALE-1-5-100-120-60-30-0.01-1.csv\"\n", 22 | "def readFile(path):\n", 23 | " df = pd.read_csv(\"lstm-out/\"+path, delimiter=',', index_col=0, parse_dates=True)\n", 24 | " return df" 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "execution_count": 59, 30 | "metadata": {}, 31 | "outputs": [], 32 | "source": [ 33 | "def getMean(df, m=\"MAE\"):\n", 34 | " #print(df[m])\n", 35 | " print(df[m].mean())\n", 36 | " \n", 37 | "def getMeanNaive(df, m=\"NAIVE_MAPE\"):\n", 38 | " columns = ['MAE', 'RMSE', 'MAPE', 'MEAN_MAE', 'MEAN_RMSE', 'MEAN_MAPE', 'NAIVE_MAE', 'NAIVE_RMSE', 'NAIVE_MAE']\n", 39 | " df = df.set_axis(['MAE', 'RMSE', 'MAPE', 'MEAN_MAE', 'MEAN_RMSE', 'MEAN_MAPE', 'NAIVE_MAE', 'NAIVE_RMSE', 'NAIVE_MAPE'], axis=1, inplace=False)\n", 40 | " print(df[m].mean())\n", 41 | " " 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": 163, 47 | "metadata": {}, 48 | "outputs": [], 49 | "source": [ 50 | "def graph(df):\n", 51 | " columns = ['MAE', 'RMSE', 'MAPE', 'MEAN_MAE', 'MEAN_RMSE', 'MEAN_MAPE', 'NAIVE_MAE', 'NAIVE_RMSE', 'NAIVE_MAE']\n", 52 | " df = df.set_axis(['MAE', 'RMSE', 'MAPE', 'MEAN_MAE', 'MEAN_RMSE', 'MEAN_MAPE', 'NAIVE_MAE', 'NAIVE_RMSE', 'NAIVE_MAPE'], axis=1, inplace=False)\n", 53 | " #print(df)\n", 54 | " figure(num=None, figsize=(16, 6), dpi=80, facecolor='w', edgecolor='k')\n", 55 | " X = np.arange(50)\n", 56 | " X = X[::-1]\n", 57 | "\n", 58 | " states = list(df.index) \n", 59 | " #plt.bar(X, df.iloc[:, 0], color='blue', width = 0.25, tick_label=states)\n", 60 | " #plt.bar(X+0.25, df.iloc[:, 4], color='red', width = 0.25, tick_label=states)\n", 61 | " handle1 = plt.bar(X, df['MAPE'], color='blue', width = 0.25, tick_label=states, label=\"LSTM\")\n", 62 | " #plt.bar(X+0.5, df['NAIVE_MAE'], color='green', width = 0.25, tick_label=states)\n", 63 | " handle2 = plt.bar(X+0.25, df['MEAN_MAPE'], color='red', width = 0.25, tick_label=states, label=\"Naive Mean\")\n", 64 | " plt.legend(handles = [handle1, handle2])\n", 65 | " plt.ylabel(\"Mean Absolute Error\")\n", 66 | " plt.xlabel(\"Time Series\")\n", 67 | " plt.savefig(\"lstm-out/concur_perf\", dpi=200, bbox_inches='tight')\n", 68 | "\n", 69 | " plt.show()" 70 | ] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "execution_count": 172, 75 | "metadata": {}, 76 | "outputs": [], 77 | "source": [ 78 | "def arima_graph(df):\n", 79 | " figure(num=None, figsize=(16, 6), dpi=80, facecolor='w', edgecolor='k')\n", 80 | " X = np.arange(50)\n", 81 | " X = X[::-1]\n", 82 | "\n", 83 | " states = list(df.index) \n", 84 | " #plt.bar(X, df.iloc[:, 0], color='blue', width = 0.25, tick_label=states)\n", 85 | " #plt.bar(X+0.25, df.iloc[:, 4], color='red', width = 0.25, tick_label=states)\n", 86 | " handle1 = plt.bar(X, df['3pt MAE'], color='blue', width = 0.25, tick_label=states, label=\"ARIMA\")\n", 87 | " #plt.bar(X+0.5, df['NAIVE_MAE'], color='green', width = 0.25, tick_label=states)\n", 88 | " handle2 = plt.bar(X+0.25, df['3pt MEAN MAE'], color='red', width = 0.25, tick_label=states, label=\"Naive Mean\")\n", 89 | " plt.legend(handles = [handle1, handle2])\n", 90 | " plt.ylabel(\"Mean Absolute Error\")\n", 91 | " plt.xlabel(\"Time Series\")\n", 92 | " plt.savefig(\"lstm-out/arima_short\", dpi=200, bbox_inches='tight')\n", 93 | "\n", 94 | " plt.show()" 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": 60, 100 | "metadata": {}, 101 | "outputs": [ 102 | { 103 | "name": "stdout", 104 | "output_type": "stream", 105 | "text": [ 106 | "0 dropout\n", 107 | "4.298370980247335\n", 108 | "3.6014706240337695\n", 109 | "3.4827134789636953\n", 110 | "3.503821593667475\n", 111 | "0.5 dropout\n", 112 | "4.135488849254573\n", 113 | "3.543675341855778\n", 114 | "3.4994457377253614\n", 115 | "3.4815771798092636\n", 116 | "1 dropout\n", 117 | "4.333278150055787\n", 118 | "3.552305426568229\n", 119 | "3.495370882001099\n", 120 | "3.4967572616165516\n", 121 | "naive errors\n", 122 | "16.747641391013374\n", 123 | "16.776559536252197\n", 124 | "0.9026623904314729\n", 125 | "0.9370662754748225\n" 126 | ] 127 | } 128 | ], 129 | "source": [ 130 | "print(\"0 dropout\")\n", 131 | "paths = []\n", 132 | "# number of hidden parameters\n", 133 | "paths.append(\"1-2-100-6-3-30-0.01-0.csv\")\n", 134 | "paths.append(\"1-5-100-6-3-30-0.01-0.csv\")\n", 135 | "paths.append(\"1-10-100-6-3-30-0.01-0.csv\")\n", 136 | "paths.append(\"1-20-100-6-3-30-0.01-0.csv\")\n", 137 | "\n", 138 | "for path in paths:\n", 139 | " df = readFile(path)\n", 140 | " getMean(df)\n", 141 | "\n", 142 | "print(\"0.5 dropout\")\n", 143 | "paths = []\n", 144 | "# number of hidden parameters\n", 145 | "paths.append(\"1-2-100-6-3-30-0.01-0.5.csv\")\n", 146 | "paths.append(\"1-5-100-6-3-30-0.01-0.5.csv\")\n", 147 | "paths.append(\"1-10-100-6-3-30-0.01-0.5.csv\")\n", 148 | "paths.append(\"1-20-100-6-3-30-0.01-0.5.csv\")\n", 149 | "\n", 150 | "for path in paths:\n", 151 | " df = readFile(path)\n", 152 | " getMean(df)\n", 153 | " \n", 154 | "print(\"1 dropout\")\n", 155 | "paths = []\n", 156 | "# number of hidden parameters\n", 157 | "paths.append(\"1-2-100-6-3-30-0.01-1.csv\")\n", 158 | "paths.append(\"1-5-100-6-3-30-0.01-1.csv\")\n", 159 | "paths.append(\"1-10-100-6-3-30-0.01-1.csv\")\n", 160 | "paths.append(\"1-20-100-6-3-30-0.01-1.csv\")\n", 161 | "\n", 162 | "for path in paths:\n", 163 | " df = readFile(path)\n", 164 | " getMean(df)\n", 165 | " \n", 166 | "#graph(readFile(paths[0]))\n", 167 | "#getMeanNaive(readFile(paths[0]))\n", 168 | "print(\"naive errors\")\n", 169 | "getMeanNaive(readFile(paths[0]), \"NAIVE_MAE\")\n", 170 | "getMeanNaive(readFile(paths[0]), \"MEAN_MAE\")\n", 171 | "getMeanNaive(readFile(paths[0]), \"NAIVE_MAPE\")\n", 172 | "getMeanNaive(readFile(paths[0]), \"MEAN_MAPE\")\n", 173 | "# performance is best with 5-10 hidden parameters and lower drop out" 174 | ] 175 | }, 176 | { 177 | "cell_type": "code", 178 | "execution_count": 61, 179 | "metadata": {}, 180 | "outputs": [ 181 | { 182 | "name": "stdout", 183 | "output_type": "stream", 184 | "text": [ 185 | "0 dropout\n", 186 | "4.608110191116682\n", 187 | "3.6469025541666547\n", 188 | "3.4768592374882705\n", 189 | "3.450118531609922\n", 190 | "0.5 dropout\n", 191 | "5.253860691902162\n", 192 | "3.853761327669385\n", 193 | "3.6318326877341316\n", 194 | "3.6928452403052163\n", 195 | "1 dropout\n", 196 | "11.050875113630616\n", 197 | "11.035655229410313\n", 198 | "11.123989696525506\n", 199 | "11.060788659632301\n" 200 | ] 201 | } 202 | ], 203 | "source": [ 204 | "# Same but 2 layers\n", 205 | "print(\"0 dropout\")\n", 206 | "paths = []\n", 207 | "# number of hidden parameters\n", 208 | "paths.append(\"2-2-100-6-3-30-0.01-0.csv\")\n", 209 | "paths.append(\"2-5-100-6-3-30-0.01-0.csv\")\n", 210 | "paths.append(\"2-10-100-6-3-30-0.01-0.csv\")\n", 211 | "paths.append(\"2-20-100-6-3-30-0.01-0.csv\")\n", 212 | "\n", 213 | "for path in paths:\n", 214 | " df = readFile(path)\n", 215 | " getMean(df)\n", 216 | "\n", 217 | "print(\"0.5 dropout\")\n", 218 | "paths = []\n", 219 | "# number of hidden parameters\n", 220 | "paths.append(\"2-2-100-6-3-30-0.01-0.5.csv\")\n", 221 | "paths.append(\"2-5-100-6-3-30-0.01-0.5.csv\")\n", 222 | "paths.append(\"2-10-100-6-3-30-0.01-0.5.csv\")\n", 223 | "paths.append(\"2-20-100-6-3-30-0.01-0.5.csv\")\n", 224 | "\n", 225 | "for path in paths:\n", 226 | " df = readFile(path)\n", 227 | " getMean(df)\n", 228 | " \n", 229 | "print(\"1 dropout\")\n", 230 | "paths = []\n", 231 | "# number of hidden parameters\n", 232 | "paths.append(\"2-2-100-6-3-30-0.01-1.csv\")\n", 233 | "paths.append(\"2-5-100-6-3-30-0.01-1.csv\")\n", 234 | "paths.append(\"2-10-100-6-3-30-0.01-1.csv\")\n", 235 | "paths.append(\"2-20-100-6-3-30-0.01-1.csv\")\n", 236 | "\n", 237 | "for path in paths:\n", 238 | " df = readFile(path)\n", 239 | " getMean(df)\n", 240 | " \n", 241 | "#graph(readFile(paths[0]))\n", 242 | "\n", 243 | "# performance is best with 5-10 hidden parameters and lower drop out" 244 | ] 245 | }, 246 | { 247 | "cell_type": "code", 248 | "execution_count": 63, 249 | "metadata": {}, 250 | "outputs": [ 251 | { 252 | "name": "stdout", 253 | "output_type": "stream", 254 | "text": [ 255 | "0 dropout\n", 256 | "6.362222937212054\n", 257 | "3.7338905942370957\n", 258 | "3.63152434640155\n", 259 | "3.584895649880234\n", 260 | "0.5 dropout\n", 261 | "6.833871854175323\n", 262 | "4.099741614601321\n", 263 | "3.8222641841121043\n", 264 | "3.696953729904467\n", 265 | "1 dropout\n", 266 | "11.056231356922174\n", 267 | "11.1669083372883\n", 268 | "11.08291939910325\n", 269 | "11.067943990858065\n" 270 | ] 271 | } 272 | ], 273 | "source": [ 274 | "# Same but 3 layers\n", 275 | "print(\"0 dropout\")\n", 276 | "paths = []\n", 277 | "# number of hidden parameters\n", 278 | "paths.append(\"3-2-100-6-3-30-0.01-0.csv\")\n", 279 | "paths.append(\"3-5-100-6-3-30-0.01-0.csv\")\n", 280 | "paths.append(\"3-10-100-6-3-30-0.01-0.csv\")\n", 281 | "paths.append(\"3-20-100-6-3-30-0.01-0.csv\")\n", 282 | "\n", 283 | "for path in paths:\n", 284 | " df = readFile(path)\n", 285 | " getMean(df)\n", 286 | "\n", 287 | "print(\"0.5 dropout\")\n", 288 | "paths = []\n", 289 | "# number of hidden parameters\n", 290 | "paths.append(\"3-2-100-6-3-30-0.01-0.5.csv\")\n", 291 | "paths.append(\"3-5-100-6-3-30-0.01-0.5.csv\")\n", 292 | "paths.append(\"3-10-100-6-3-30-0.01-0.5.csv\")\n", 293 | "paths.append(\"3-20-100-6-3-30-0.01-0.5.csv\")\n", 294 | "\n", 295 | "for path in paths:\n", 296 | " df = readFile(path)\n", 297 | " getMean(df)\n", 298 | " \n", 299 | "print(\"1 dropout\")\n", 300 | "paths = []\n", 301 | "# number of hidden parameters\n", 302 | "paths.append(\"3-2-100-6-3-30-0.01-1.csv\")\n", 303 | "paths.append(\"3-5-100-6-3-30-0.01-1.csv\")\n", 304 | "paths.append(\"3-10-100-6-3-30-0.01-1.csv\")\n", 305 | "paths.append(\"3-20-100-6-3-30-0.01-1.csv\")\n", 306 | "\n", 307 | "for path in paths:\n", 308 | " df = readFile(path)\n", 309 | " getMean(df)\n", 310 | " \n", 311 | "#graph(readFile(paths[0]))\n", 312 | "\n", 313 | "# performance is best with 5-10 hidden parameters and lower drop out" 314 | ] 315 | }, 316 | { 317 | "cell_type": "code", 318 | "execution_count": 179, 319 | "metadata": {}, 320 | "outputs": [ 321 | { 322 | "name": "stdout", 323 | "output_type": "stream", 324 | "text": [ 325 | "1 layer\n", 326 | "11.707901753223203\n", 327 | "11.094179024933958\n", 328 | "10.848624087604676\n", 329 | "10.907888719614935\n", 330 | "2 layers\n", 331 | "11.816644308605884\n", 332 | "11.060142354802803\n", 333 | "10.817485659856372\n", 334 | "11.123639579348753\n", 335 | "3 layers\n", 336 | "11.561774247263747\n", 337 | "11.498964251169003\n", 338 | "11.25136782861082\n", 339 | "11.05480728485285\n" 340 | ] 341 | } 342 | ], 343 | "source": [ 344 | "# Long Term Analysis\n", 345 | "print(\"1 layer\")\n", 346 | "paths = []\n", 347 | "paths.append(\"1-5-100-432-216-30-0.01-0.csv\")\n", 348 | "paths.append(\"1-10-100-432-216-30-0.01-0.csv\")\n", 349 | "paths.append(\"1-20-100-432-216-30-0.01-0.csv\")\n", 350 | "paths.append(\"1-30-100-432-216-30-0.01-0.csv\")\n", 351 | "\n", 352 | "for path in paths:\n", 353 | " df = readFile(path)\n", 354 | " getMean(df)\n", 355 | "\n", 356 | "print(\"2 layers\")\n", 357 | "paths = []\n", 358 | "paths.append(\"2-5-100-432-216-30-0.01-0.csv\")\n", 359 | "paths.append(\"2-10-100-432-216-30-0.01-0.csv\")\n", 360 | "paths.append(\"2-20-100-432-216-30-0.01-0.csv\")\n", 361 | "paths.append(\"2-30-100-432-216-30-0.01-0.csv\")\n", 362 | "\n", 363 | "for path in paths:\n", 364 | " df = readFile(path)\n", 365 | " getMean(df)\n", 366 | " \n", 367 | "print(\"3 layers\")\n", 368 | "paths = []\n", 369 | "paths.append(\"3-5-100-432-216-30-0.01-0.csv\")\n", 370 | "paths.append(\"3-10-100-432-216-30-0.01-0.csv\")\n", 371 | "paths.append(\"3-20-100-432-216-30-0.01-0.csv\")\n", 372 | "paths.append(\"3-30-100-432-216-30-0.01-0.csv\")\n", 373 | "\n", 374 | "\n", 375 | "for path in paths:\n", 376 | " df = readFile(path)\n", 377 | " getMean(df)\n", 378 | " \n", 379 | "#graph(readFile(paths[0]))\n", 380 | "\n", 381 | "# performance is best with 5-10 hidden parameters and lower drop out" 382 | ] 383 | }, 384 | { 385 | "cell_type": "code", 386 | "execution_count": null, 387 | "metadata": {}, 388 | "outputs": [], 389 | "source": [ 390 | "# no resample\n", 391 | "paths = []\n", 392 | "paths.append(\"NO-SCALE-1-5-100-120-60-30-0.01-1.csv\")\n", 393 | "paths.append(\"NO-SCALE-1-10-100-120-60-30-0.01-1.csv\")\n", 394 | "paths.append(\"NO-SCALE-1-20-100-120-60-30-0.01-1.csv\")\n", 395 | "paths.append(\"NO-SCALE-2-5-100-120-60-30-0.01-1.csv\")\n", 396 | "\n", 397 | "for path in paths:\n", 398 | " df = readFile(path)\n", 399 | " getMean(df)\n", 400 | " \n", 401 | "print(\"naive perf\")\n", 402 | "for path in paths:\n", 403 | " df = readFile(path)\n", 404 | " getMeanNaive(df)" 405 | ] 406 | }, 407 | { 408 | "cell_type": "code", 409 | "execution_count": 178, 410 | "metadata": { 411 | "scrolled": true 412 | }, 413 | "outputs": [ 414 | { 415 | "name": "stdout", 416 | "output_type": "stream", 417 | "text": [ 418 | "10.611669625162085\n", 419 | "None\n", 420 | "0\n", 421 | "10.611669625162085\n", 422 | "1.784377328956223\n" 423 | ] 424 | } 425 | ], 426 | "source": [ 427 | "#df = readFile(\"3-20-100-532-216-40-0.01-0.1.csv\")\n", 428 | "#df = readFile(\"trash/NO-SCALE-1-10-100-120-60-30-0.01-1.csv\")\n", 429 | "df = readFile(\"concur-2-10-100-6-3-50-0.01-0.5.csv\")\n", 430 | "#df = readFile(\"4-20-100-6-3-30-0.01-0.csv\")\n", 431 | "#df = readFile(\"2-20-100-6-3-30-0.01-0.csv\")\n", 432 | "#print(df)\n", 433 | "#graph(df)\n", 434 | "#print(df)\n", 435 | "print(getMean(df, m=\"MAE\"))\n", 436 | "\n", 437 | "print(count)\n", 438 | "print(df['MAE'].mean())\n", 439 | "print(df['MAPE'].mean())" 440 | ] 441 | }, 442 | { 443 | "cell_type": "code", 444 | "execution_count": 5, 445 | "metadata": {}, 446 | "outputs": [ 447 | { 448 | "name": "stdout", 449 | "output_type": "stream", 450 | "text": [ 451 | "5.3790731785813675\n", 452 | "8.641332964665912\n", 453 | "0.6695990111234613\n", 454 | "5.287843993989368\n" 455 | ] 456 | } 457 | ], 458 | "source": [ 459 | "# arima analysis\n", 460 | "df = pd.read_csv(\"arima_results.csv\", delimiter=',', index_col=0, parse_dates=True)\n", 461 | "\n", 462 | "#print(df)\n", 463 | "print(df['3pt MAE'].mean())\n", 464 | "print(df['MAE'].mean())\n", 465 | "print(df['3pt MAPE'].mean())\n", 466 | "print(df['MAPE'].mean())\n", 467 | "#arima_graph(df)" 468 | ] 469 | }, 470 | { 471 | "cell_type": "code", 472 | "execution_count": null, 473 | "metadata": {}, 474 | "outputs": [], 475 | "source": [] 476 | } 477 | ], 478 | "metadata": { 479 | "kernelspec": { 480 | "display_name": "Python 3", 481 | "language": "python", 482 | "name": "python3" 483 | }, 484 | "language_info": { 485 | "codemirror_mode": { 486 | "name": "ipython", 487 | "version": 3 488 | }, 489 | "file_extension": ".py", 490 | "mimetype": "text/x-python", 491 | "name": "python", 492 | "nbconvert_exporter": "python", 493 | "pygments_lexer": "ipython3", 494 | "version": "3.8.2" 495 | } 496 | }, 497 | "nbformat": 4, 498 | "nbformat_minor": 4 499 | } 500 | -------------------------------------------------------------------------------- /LSTM_Findings.txt: -------------------------------------------------------------------------------- 1 | Larger Batch sizes result in better peformance 2 | Smaller batch sizes result in overfitting, and therefore require a smaller learning rate and fewer epochs of training 3 | 4 | Increased LSTM layers have an adverse effect on performance. This may be because the data is of a single dimension (time) 5 | - consider concurrently looking at 50 at a time 6 | 7 | Performance increases with more hidden parameters (10 is the best) 8 | 9 | -------------------------------------------------------------------------------- /LSTM_Multi-Layer_Concurrent.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Implementation of LSTM\n", 8 | "## Variables to Consider\n", 9 | "
    \n", 10 | "
  • Hidden Parameters (more seems better until 10)
  • \n", 11 | "
  • Hidden Layers (more than 1 seems useless, makes sense because input is few dimensions)
  • \n", 12 | "
  • Learning Rate (smaller learning rate requires more epoches to achieve similar results)
  • \n", 13 | "
  • Mini-Batch Size (seems to have slight improvement)
  • \n", 14 | "
  • Number Epochs
  • \n", 15 | "
  • Sequence Length (4)
  • \n", 16 | "
  • Length of Prediction (1)
  • \n", 17 | "
" 18 | ] 19 | }, 20 | { 21 | "cell_type": "code", 22 | "execution_count": 1, 23 | "metadata": { 24 | "colab": { 25 | "base_uri": "https://localhost:8080/", 26 | "height": 811 27 | }, 28 | "colab_type": "code", 29 | "executionInfo": { 30 | "elapsed": 13538, 31 | "status": "error", 32 | "timestamp": 1590900514206, 33 | "user": { 34 | "displayName": "Langston Nashold", 35 | "photoUrl": "", 36 | "userId": "03058483142038316977" 37 | }, 38 | "user_tz": 300 39 | }, 40 | "id": "VAzzi5jKnjvJ", 41 | "outputId": "42fe0153-d955-48ba-c761-2319f3dfad81" 42 | }, 43 | "outputs": [], 44 | "source": [ 45 | "#!pip uninstall statsmodels\n", 46 | "#!pip install pmdarima\n", 47 | "import pandas as pd\n", 48 | "import numpy as np\n", 49 | "import matplotlib.pyplot as plt\n", 50 | "import torch\n", 51 | "import torch.nn as nn\n", 52 | "import torch.nn.functional as F\n", 53 | "import torch.optim as optim\n", 54 | "from tqdm import tqdm\n", 55 | "from os import listdir\n", 56 | "from torch.autograd import Variable\n", 57 | "from sklearn.preprocessing import MinMaxScaler" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 2, 63 | "metadata": {}, 64 | "outputs": [ 65 | { 66 | "name": "stdout", 67 | "output_type": "stream", 68 | "text": [ 69 | "using cuda\n" 70 | ] 71 | } 72 | ], 73 | "source": [ 74 | "if torch.cuda.is_available():\n", 75 | " device = torch.device(\"cuda\")\n", 76 | " print(\"using cuda\")" 77 | ] 78 | }, 79 | { 80 | "cell_type": "code", 81 | "execution_count": 20, 82 | "metadata": { 83 | "colab": { 84 | "base_uri": "https://localhost:8080/", 85 | "height": 803 86 | }, 87 | "colab_type": "code", 88 | "executionInfo": { 89 | "elapsed": 771, 90 | "status": "ok", 91 | "timestamp": 1590900464686, 92 | "user": { 93 | "displayName": "Langston Nashold", 94 | "photoUrl": "", 95 | "userId": "03058483142038316977" 96 | }, 97 | "user_tz": 300 98 | }, 99 | "id": "DzEKHrLmtEYI", 100 | "outputId": "b523f4cb-6c47-440e-89a7-0df85cf4fb02" 101 | }, 102 | "outputs": [], 103 | "source": [ 104 | "class Parameters():\n", 105 | " def __init__(self, num_layers = 1, hidden_size = 10, batch_size = 100, seq_len = 6, pred_len = 3, num_epochs = 20, learning_rate = 0.01, dropout = 1):\n", 106 | " self.num_layers = num_layers\n", 107 | " self.hidden_size = hidden_size\n", 108 | " self.batch_size = batch_size\n", 109 | " self.seq_len = seq_len\n", 110 | " self.pred_len = pred_len\n", 111 | " self.num_epochs = num_epochs\n", 112 | " self.learning_rate = learning_rate\n", 113 | " self.dropout = dropout\n", 114 | " \n", 115 | " def __str__(self):\n", 116 | " return \"{}-{}-{}-{}-{}-{}-{}-{}\".format(self.num_layers, self.hidden_size, self.batch_size, self.seq_len, self.pred_len, self.num_epochs, self.learning_rate, self.dropout)\n" 117 | ] 118 | }, 119 | { 120 | "cell_type": "markdown", 121 | "metadata": { 122 | "colab_type": "text", 123 | "id": "kXV_VIWvO-he" 124 | }, 125 | "source": [ 126 | "Following Code Adapted from ([github sample](https://github.com/spdin/time-series-prediction-lstm-pytorch/blob/master/Time_Series_Prediction_with_LSTM_Using_PyTorch.ipynb))" 127 | ] 128 | }, 129 | { 130 | "cell_type": "code", 131 | "execution_count": 21, 132 | "metadata": {}, 133 | "outputs": [ 134 | { 135 | "name": "stdout", 136 | "output_type": "stream", 137 | "text": [ 138 | "(1080, 1)\n" 139 | ] 140 | } 141 | ], 142 | "source": [ 143 | "def readData(file='samples/WY.csv', freq=20):\n", 144 | " data = pd.read_csv(file, delimiter=',', index_col=0, parse_dates=True)\n", 145 | "\n", 146 | " #plt.figure(figsize=(20, 4))\n", 147 | " #plt.plot(data)\n", 148 | " #print(data)\n", 149 | " data = data.resample(str(freq) + 'T').mean()\n", 150 | " raw_values = np.asarray(data['CpuUtilizationAverage']).reshape(data.shape[0], 1)\n", 151 | " #plt.plot(data)\n", 152 | " #plt.show()\n", 153 | " #print(raw_values)\n", 154 | " return raw_values\n", 155 | "\n", 156 | "training_set = readData()\n", 157 | "print(training_set.shape)" 158 | ] 159 | }, 160 | { 161 | "cell_type": "code", 162 | "execution_count": 52, 163 | "metadata": { 164 | "colab": {}, 165 | "colab_type": "code", 166 | "id": "ESj__1lcPQzg", 167 | "scrolled": true 168 | }, 169 | "outputs": [ 170 | { 171 | "name": "stderr", 172 | "output_type": "stream", 173 | "text": [ 174 | ":51: FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison\n", 175 | " if state_name==state:\n" 176 | ] 177 | }, 178 | { 179 | "name": "stdout", 180 | "output_type": "stream", 181 | "text": [ 182 | "(1072, 3)\n", 183 | "torch.Size([800, 6, 50])\n", 184 | "torch.Size([800, 3])\n" 185 | ] 186 | } 187 | ], 188 | "source": [ 189 | "from torch.utils.data import TensorDataset, DataLoader\n", 190 | "\n", 191 | "# just used to store some data variables\n", 192 | "class Data:\n", 193 | " pass\n", 194 | "\n", 195 | "def large_sliding_windows(data, seq_length, pred_length=2):\n", 196 | " x = []\n", 197 | " y = []\n", 198 | "\n", 199 | " for i in range(len(data)-seq_length-pred_length+1):\n", 200 | " _x = data[i:(i+seq_length)]\n", 201 | " _y = data[i+seq_length:i+seq_length+pred_length]\n", 202 | " x.append(_x)\n", 203 | " y.append(_y)\n", 204 | "\n", 205 | " return np.array(x),np.array(y)\n", 206 | "\n", 207 | "def sliding_windows(data, seq_length):\n", 208 | " x = []\n", 209 | " y = []\n", 210 | "\n", 211 | " for i in range(len(data)-seq_length-1):\n", 212 | " _x = data[i:(i+seq_length)]\n", 213 | " _y = data[i+seq_length]\n", 214 | " x.append(_x)\n", 215 | " y.append(_y)\n", 216 | "\n", 217 | " return np.array(x),np.array(y)\n", 218 | "\n", 219 | "def get_concurrent():\n", 220 | " data = np.zeros((50, 21600))\n", 221 | " for i, state in enumerate(listdir(\"samples/\")):\n", 222 | " training_set = readData(\"samples/\"+state)\n", 223 | " training_set = training_set.flatten()\n", 224 | " data[i] = training_set\n", 225 | " x = []\n", 226 | " y = []\n", 227 | " \n", 228 | " for i in range(21600-1):\n", 229 | " _x = data[:,i:(i+1)]\n", 230 | " _y = data[:,i+1]\n", 231 | " x.append(_x)\n", 232 | " y.append(_y)\n", 233 | " return np.array(x), np.array(y)\n", 234 | "\n", 235 | "def get_concurrent_features(seq_len, pred_len, state_name):\n", 236 | " data = np.zeros((1080, 50)) #fix hard coding\n", 237 | " state_id=0\n", 238 | " for i, state in enumerate(listdir(\"samples/\")):\n", 239 | " if state_name==state:\n", 240 | " state_id=i\n", 241 | " print(\"using state {} with id {}\".format(state, i))\n", 242 | " training_set = readData(\"samples/\"+state)\n", 243 | " training_set = training_set.flatten()\n", 244 | " for j in range(data.shape[0]):\n", 245 | " data[j][i] = training_set[j]\n", 246 | " x, y = large_sliding_windows(data, seq_len, pred_len)\n", 247 | " y = y[:,:,state_id]\n", 248 | " print(y.shape)\n", 249 | " return x, y\n", 250 | " \n", 251 | "\n", 252 | "def generateData(state_name, d, params):\n", 253 | " d.sc = MinMaxScaler()\n", 254 | " training_data = d.sc.fit_transform(training_set) # normalizes the data\n", 255 | "\n", 256 | " seq_length = params.seq_len # parameter\n", 257 | " pred_len = params.pred_len # parameter\n", 258 | " x, y = get_concurrent_features(seq_length, pred_len, state_name)\n", 259 | "\n", 260 | " batch_size= params.batch_size\n", 261 | " d.max_size = int(batch_size*(len(y)//batch_size))\n", 262 | " d.train_size = int(batch_size*(d.max_size*(0.8)//batch_size)) #train_size = int(len(y) * 0.67)\n", 263 | " d.test_size = d.max_size-d.train_size\n", 264 | " #test_size = len(y) - train_size\n", 265 | "\n", 266 | " d.dataX = Variable(torch.Tensor(np.array(x[0:d.max_size])))\n", 267 | " d.dataY = Variable(torch.Tensor(np.array(y[0:d.max_size])))\n", 268 | "\n", 269 | " d.trainX = Variable(torch.Tensor(np.array(x[0:d.train_size]))).to(device)\n", 270 | " d.trainY = Variable(torch.Tensor(np.array(y[0:d.train_size]))).to(device)\n", 271 | " train_data = TensorDataset(d.trainX, d.trainY)\n", 272 | " d.train_loader = DataLoader(train_data, shuffle=False, batch_size=batch_size) #primary\n", 273 | "\n", 274 | " d.testX = Variable(torch.Tensor(np.array(x[d.train_size:d.max_size]))).to(device)\n", 275 | " d.testY = Variable(torch.Tensor(np.array(y[d.train_size:d.max_size]))).to(device)\n", 276 | " #test_data = TensorDataset(testX, testY)\n", 277 | " test_data = TensorDataset(d.dataX, d.dataY)\n", 278 | " d.test_loader = DataLoader(test_data, shuffle=False, batch_size=batch_size) #primary\n", 279 | " return d\n", 280 | "data = Data()\n", 281 | "params = Parameters()\n", 282 | "generateData(training_set, data, params)\n", 283 | "print(data.trainX.shape)\n", 284 | "print(data.trainY.shape)\n", 285 | "\n" 286 | ] 287 | }, 288 | { 289 | "cell_type": "code", 290 | "execution_count": 14, 291 | "metadata": {}, 292 | "outputs": [ 293 | { 294 | "ename": "IndexError", 295 | "evalue": "index -1 is out of bounds for dimension 0 with size 0", 296 | "output_type": "error", 297 | "traceback": [ 298 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 299 | "\u001b[0;31mIndexError\u001b[0m Traceback (most recent call last)", 300 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 32\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mglobal_naive\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mglobal_mean\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlocal_naive\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlocal_mean\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 33\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 34\u001b[0;31m \u001b[0mnaives\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mgenerateNaive\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mparams\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 35\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtestX\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 36\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtestY\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 301 | "\u001b[0;32m\u001b[0m in \u001b[0;36mgenerateNaive\u001b[0;34m(d, params)\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mmean\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0md\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtrainY\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmean\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mmean_forecasts\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfull\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0md\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtestY\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmean\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitem\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0mnaive_forecasts\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfull\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0md\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtestY\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0md\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtrainX\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitem\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# always predicts last provided\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 7\u001b[0m \u001b[0mfour_naive_forecasts\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mones\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0md\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtestY\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mrow\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mfour_naive_forecasts\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 302 | "\u001b[0;31mIndexError\u001b[0m: index -1 is out of bounds for dimension 0 with size 0" 303 | ] 304 | } 305 | ], 306 | "source": [ 307 | "## Generate Naive Examples\n", 308 | "\n", 309 | "def generateNaive(d, params):\n", 310 | " mean = d.trainY.mean()\n", 311 | " mean_forecasts = np.full(d.testY.shape, mean.item())\n", 312 | " naive_forecasts = np.full(d.testY.shape, d.trainX[-1][-1].item()) # always predicts last provided\n", 313 | " four_naive_forecasts = np.ones(d.testY.shape)\n", 314 | " for row in four_naive_forecasts:\n", 315 | " for i in range(params.pred_len):\n", 316 | " row[i] = d.testX[i][-1].item()\n", 317 | " four_mean_forecasts = np.ones(d.testY.shape)\n", 318 | " for row, test_row in zip(four_mean_forecasts, d.testX):\n", 319 | " for i in range(params.pred_len):\n", 320 | " row[i] = np.mean(test_row.numpy())\n", 321 | "\n", 322 | " #naive_forecasts = naive_forecasts.reshape(-1, 1)\n", 323 | " #mean_forecasts = mean_forecasts.reshape(-1, 1)\n", 324 | "\n", 325 | " denormalize=False\n", 326 | "\n", 327 | " if denormalize:\n", 328 | " naive_forecasts = sc.inverse_transform(naive_forecasts)\n", 329 | " mean_forecasts = sc.inverse_transform(mean_forecasts)\n", 330 | " four_naive_forecasts = sc.inverse_transform(four_naive_forecasts)\n", 331 | " four_mean_forecasts = sc.inverse_transform(four_mean_forecasts)\n", 332 | "\n", 333 | "\n", 334 | " global_naive = naive_forecasts.reshape(naive_forecasts.shape[:-2] + (-1,))\n", 335 | " global_mean = mean_forecasts.reshape(mean_forecasts.shape[:-2] + (-1,))\n", 336 | " local_naive = four_naive_forecasts.reshape(four_naive_forecasts.shape[:-2] + (-1,))\n", 337 | " local_mean = four_mean_forecasts.reshape(four_mean_forecasts.shape[:-2] + (-1,))\n", 338 | " return (global_naive, global_mean, local_naive, local_mean)\n", 339 | "\n", 340 | "naives = generateNaive(data, params)\n", 341 | "print(data.testX.shape)\n", 342 | "print(data.testY.shape)\n" 343 | ] 344 | }, 345 | { 346 | "cell_type": "code", 347 | "execution_count": 29, 348 | "metadata": { 349 | "colab": {}, 350 | "colab_type": "code", 351 | "id": "d3dTo7J9PWI5" 352 | }, 353 | "outputs": [], 354 | "source": [ 355 | "class LSTM(nn.Module):\n", 356 | " def __init__(self, output_size, input_size, hidden_dim, n_layers, drop_prob=0):\n", 357 | " super(LSTM, self).__init__()\n", 358 | " self.output_size = output_size\n", 359 | " self.n_layers = n_layers\n", 360 | " self.hidden_dim = hidden_dim\n", 361 | " \n", 362 | " self.lstm = nn.LSTM(input_size, hidden_dim, n_layers, dropout=drop_prob, batch_first=True)\n", 363 | " self.dropout = nn.Dropout(drop_prob)\n", 364 | " self.fc = nn.Linear(hidden_dim, output_size)\n", 365 | " \n", 366 | " def forward(self, x, hidden):\n", 367 | " batch_size = x.size(0)\n", 368 | " #x = x.long()\n", 369 | " lstm_out, hidden = self.lstm(x, hidden)\n", 370 | " #print(lstm_out.shape)\n", 371 | " lstm_out = lstm_out.contiguous().view(-1, self.hidden_dim)\n", 372 | " \n", 373 | " #out = self.dropout(lstm_out)\n", 374 | " #print(lstm_out.shape)\n", 375 | " #out = self.fc(lstm_out) # linear transform from hidden dims to output_size\n", 376 | " #print(out.shape)\n", 377 | " #out = out.view(batch_size, -1) #-1 means size will be infered\n", 378 | " #print(out.shape)\n", 379 | " #out = out[:,-2]\n", 380 | " #print(out.shape)\n", 381 | " #print(hidden[0][-1].shape)\n", 382 | " h_out = hidden[0][-1].view(-1, self.hidden_dim)\n", 383 | " out = self.fc(h_out)\n", 384 | " #print(out.shape)\n", 385 | " return out, hidden\n", 386 | " \n", 387 | " def init_hidden(self, batch_size):\n", 388 | " weight = next(self.parameters()).data\n", 389 | " hidden = (weight.new(self.n_layers, batch_size, self.hidden_dim).zero_().to(device),\n", 390 | " weight.new(self.n_layers, batch_size, self.hidden_dim).zero_().to(device))\n", 391 | " return hidden" 392 | ] 393 | }, 394 | { 395 | "cell_type": "markdown", 396 | "metadata": { 397 | "colab_type": "text", 398 | "id": "9AO0JvNKPZcE" 399 | }, 400 | "source": [ 401 | "Training" 402 | ] 403 | }, 404 | { 405 | "cell_type": "code", 406 | "execution_count": 41, 407 | "metadata": { 408 | "colab": {}, 409 | "colab_type": "code", 410 | "id": "9ARlW89KPanR" 411 | }, 412 | "outputs": [ 413 | { 414 | "name": "stderr", 415 | "output_type": "stream", 416 | "text": [ 417 | "/home/rayan/.local/lib/python3.8/site-packages/torch/nn/modules/rnn.py:47: UserWarning: dropout option adds dropout after all but last recurrent layer, so non-zero dropout expects num_layers greater than 1, but got dropout=1 and num_layers=1\n", 418 | " warnings.warn(\"dropout option adds dropout after all but last \"\n" 419 | ] 420 | }, 421 | { 422 | "name": "stdout", 423 | "output_type": "stream", 424 | "text": [ 425 | "Epoch: 0, loss: 151.96112\n", 426 | "Epoch: 10, loss: 44.12098\n" 427 | ] 428 | } 429 | ], 430 | "source": [ 431 | "class Model:\n", 432 | " def __init__(self, lstm, h, criterion):\n", 433 | " self.lstm, self.h, self.criterion = lstm, h, criterion\n", 434 | "\n", 435 | "def train(d, params):\n", 436 | " num_epochs = params.num_epochs#30 # seems to stabilize here, higher and it seems to overfit\n", 437 | " learning_rate = params.learning_rate#0.01\n", 438 | "\n", 439 | " input_size = 50 # required for this time series (value)\n", 440 | " hidden_size = params.hidden_size#2 # hyper parameter\n", 441 | " num_layers = params.num_layers#1 # hyper parameter\n", 442 | "\n", 443 | " lstm = LSTM(params.pred_len, input_size, hidden_size, num_layers, params.dropout)\n", 444 | " lstm.to(device)\n", 445 | "\n", 446 | " criterion = torch.nn.MSELoss() # mean-squared error for regression\n", 447 | " #criterion = torch.nn.BCELoss()\n", 448 | " optimizer = torch.optim.Adam(lstm.parameters(), lr=learning_rate)\n", 449 | " #optimizer = torch.optim.SGD(lstm.parameters(), lr=learning_rate)\n", 450 | "\n", 451 | " h = lstm.init_hidden(params.batch_size)\n", 452 | "\n", 453 | " # Train the model\n", 454 | " for epoch in range(num_epochs):\n", 455 | " for x, y in d.train_loader:\n", 456 | " #x = x.to(device)\n", 457 | " #y = y.to(device)\n", 458 | " h = tuple([e.data for e in h])\n", 459 | " outputs, h = lstm(x, h)\n", 460 | " optimizer.zero_grad() # remove stored gradient\n", 461 | "\n", 462 | " # obtain the loss function\n", 463 | " #print(outputs.shape)\n", 464 | " #print(outputs.shape)\n", 465 | " #print(y.shape)\n", 466 | " loss = criterion(outputs, y) #.squeeze()\n", 467 | " #print(outputs)\n", 468 | "\n", 469 | " loss.backward()\n", 470 | "\n", 471 | " optimizer.step()\n", 472 | " if epoch % 10 == 0:\n", 473 | " print(\"Epoch: %d, loss: %1.5f\" % (epoch, loss.item()))\n", 474 | " #pass\n", 475 | " \n", 476 | " model = Model(lstm, h, criterion)\n", 477 | " return model\n", 478 | " \n", 479 | "model = train(data, params)" 480 | ] 481 | }, 482 | { 483 | "cell_type": "markdown", 484 | "metadata": { 485 | "colab_type": "text", 486 | "id": "aUVXq6eYPbnx" 487 | }, 488 | "source": [ 489 | "Testing" 490 | ] 491 | }, 492 | { 493 | "cell_type": "code", 494 | "execution_count": 31, 495 | "metadata": { 496 | "colab": {}, 497 | "colab_type": "code", 498 | "id": "nc8WL0XuPcxa" 499 | }, 500 | "outputs": [], 501 | "source": [ 502 | "def test(model, d, params, show_plot=False):\n", 503 | " model.lstm.eval()\n", 504 | " test_predict = np.zeros((data.max_size, params.pred_len))\n", 505 | " test_losses = []\n", 506 | "\n", 507 | " for i, (x, y) in enumerate(d.test_loader):\n", 508 | " model.h = tuple([each.data for each in model.h])\n", 509 | " x, y = x.to(device), y.to(device)\n", 510 | " output, model.h = model.lstm(x, model.h)\n", 511 | " test_loss = model.criterion(output.squeeze(), y)\n", 512 | " test_losses.append(test_loss.item())\n", 513 | " for j in range(params.batch_size):\n", 514 | " #test_predict.append(output[j].item())\n", 515 | " #test_predict[i*100+j] = output[j].item()\n", 516 | " for k in range(params.pred_len):\n", 517 | " test_predict[j+i*100][k] = output[j][k].item()\n", 518 | "\n", 519 | "\n", 520 | " #print(test_predict)\n", 521 | "\n", 522 | " #data_predict = test_predict.reshape(-1, 1)#test_predict.data.numpy()\n", 523 | " data_predict = test_predict\n", 524 | " dataY_plot = d.dataY.data.numpy()\n", 525 | " \n", 526 | " data_predict_transform = d.sc.inverse_transform(data_predict)\n", 527 | " dataY_plot_transform = d.sc.inverse_transform(dataY_plot)\n", 528 | " \n", 529 | " if show_plot:\n", 530 | " plt.figure(figsize=(20, 4))\n", 531 | " plt.axvline(x=d.train_size, c='r', linestyle='--') # data shift from train to test\n", 532 | " plt.plot(dataY_plot_transform)\n", 533 | " plt.plot(data_predict_transform)\n", 534 | " plt.suptitle('Time-Series Prediction')\n", 535 | " plt.show()\n", 536 | "\n", 537 | " #print(data_predict_transform)\n", 538 | " #print(dataY_plot_transform)\n", 539 | " return (data_predict[d.train_size:], dataY_plot[d.train_size:])\n", 540 | "\n", 541 | "preds, labels = test(model, data, params)\n" 542 | ] 543 | }, 544 | { 545 | "cell_type": "markdown", 546 | "metadata": { 547 | "colab_type": "text", 548 | "id": "8GYO9JliaG2g" 549 | }, 550 | "source": [ 551 | "Image is deceptive. Try ~100 samples to see a closer fit" 552 | ] 553 | }, 554 | { 555 | "cell_type": "markdown", 556 | "metadata": { 557 | "colab_type": "text", 558 | "id": "JAA4fI6vaLvg" 559 | }, 560 | "source": [ 561 | "Accuracy Calculations" 562 | ] 563 | }, 564 | { 565 | "cell_type": "code", 566 | "execution_count": 32, 567 | "metadata": { 568 | "colab": {}, 569 | "colab_type": "code", 570 | "id": "rISXuL-3I1Bl" 571 | }, 572 | "outputs": [ 573 | { 574 | "ename": "ValueError", 575 | "evalue": "operands could not be broadcast together with shapes (215000,) (600,) ", 576 | "output_type": "error", 577 | "traceback": [ 578 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 579 | "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", 580 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 60\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mnaive\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mnaives\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 61\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 62\u001b[0;31m \u001b[0mprint_errors\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnaive\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlabels\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 581 | "\u001b[0;32m\u001b[0m in \u001b[0;36mprint_errors\u001b[0;34m(preds, labels, prnt)\u001b[0m\n\u001b[1;32m 53\u001b[0m \u001b[0merr_results\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 54\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0merror\u001b[0m \u001b[0;32min\u001b[0m \u001b[0merrors\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 55\u001b[0;31m \u001b[0merr_results\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0merror\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpreds\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlabels\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mprnt\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 56\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0merr_results\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 57\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", 582 | "\u001b[0;32m\u001b[0m in \u001b[0;36mmae\u001b[0;34m(preds, labels, prnt)\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[0mpreds\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpreds\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mflatten\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 25\u001b[0m \u001b[0mlabels\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlabels\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mflatten\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 26\u001b[0;31m \u001b[0merr\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msum\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mabsolute\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpreds\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0mlabels\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0mpreds\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 27\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mprnt\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"MAE - {}\"\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0merr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 28\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 583 | "\u001b[0;31mValueError\u001b[0m: operands could not be broadcast together with shapes (215000,) (600,) " 584 | ] 585 | } 586 | ], 587 | "source": [ 588 | "eps = 1e-5\n", 589 | "# Mean Average Percent Error\n", 590 | "def mape(preds, labels, prnt=False):\n", 591 | " preds = preds.flatten()\n", 592 | " labels = labels.flatten()\n", 593 | " err = 0\n", 594 | " for i, (pred, label) in enumerate(zip(preds, labels)):\n", 595 | " denum = np.absolute(label) if np.round(label) !=0 else 50#np.max(labels) # this might be wrong\n", 596 | " err += (np.absolute(pred-label) / denum)\n", 597 | " \n", 598 | " err /= preds.shape[0]\n", 599 | " if prnt: print(\"MAPE - {}\".format(err))\n", 600 | " return err\n", 601 | " \n", 602 | "# Brier Score or Mean Squared Error\n", 603 | "def mse(preds, labels, prnt=False):\n", 604 | " preds = preds.flatten()\n", 605 | " labels = labels.flatten()\n", 606 | " err = np.sum(np.power(preds-labels, 2)) / preds.shape[0]\n", 607 | " if prnt: print(\"MSE - {}\".format(err))\n", 608 | " return err\n", 609 | " \n", 610 | "def mae(preds, labels, prnt=False):\n", 611 | " preds = preds.flatten()\n", 612 | " labels = labels.flatten()\n", 613 | " err = (np.sum(np.absolute(preds-labels))) / preds.shape[0]\n", 614 | " if prnt: print(\"MAE - {}\".format(err))\n", 615 | " return err\n", 616 | " \n", 617 | "# Root Mean Squared Error\n", 618 | "def rmse(preds, labels, prnt=False):\n", 619 | " err = np.power(mse(preds, labels), 0.5)\n", 620 | " if prnt: print(\"RMSE - {}\".format(err))\n", 621 | " return err\n", 622 | "\n", 623 | "# Symmetric Mean Absolute Percentage Error\n", 624 | "# some issues in bias, but commonly used\n", 625 | "def smape(preds, labels, prnt=False):\n", 626 | " preds = preds.flatten()\n", 627 | " labels = labels.flatten()\n", 628 | " err = 0\n", 629 | " for (pred, label) in zip(preds, labels):\n", 630 | " denum = np.absolute(pred)+np.absolute(label) if np.absolute(pred)+np.absolute(label) !=0 else np.max(labels) #check!!\n", 631 | " err += (np.absolute(pred-label) / denum)\n", 632 | " err /= preds.shape[0] # in textbook, also multiply by 200 but this might be for percentage?\n", 633 | " if prnt: print(\"SMAPE - {}\".format(err))\n", 634 | " return err\n", 635 | "\n", 636 | "#errors = [mape, mse, rmse, smape]\n", 637 | "errors = [mae, rmse, mape]\n", 638 | "\n", 639 | "def print_errors(preds, labels, prnt=False):\n", 640 | " err_results = []\n", 641 | " for error in errors:\n", 642 | " err_results.append(error(preds, labels, prnt))\n", 643 | " return err_results\n", 644 | " \n", 645 | "print_errors(preds, labels)\n", 646 | "\n", 647 | "for naive in naives:\n", 648 | "\n", 649 | " print_errors(naive, labels)" 650 | ] 651 | }, 652 | { 653 | "cell_type": "code", 654 | "execution_count": 53, 655 | "metadata": { 656 | "scrolled": true 657 | }, 658 | "outputs": [ 659 | { 660 | "name": "stdout", 661 | "output_type": "stream", 662 | "text": [ 663 | "using state ND.csv with id 0\n", 664 | "(1072, 3)\n", 665 | "Epoch: 0, loss: 150.68330\n", 666 | "Epoch: 10, loss: 13.03061\n", 667 | "Epoch: 20, loss: 2.67542\n", 668 | "Epoch: 30, loss: 2.42016\n", 669 | "Epoch: 40, loss: 2.41325\n", 670 | "0\n", 671 | "using state KY.csv with id 1\n", 672 | "(1072, 3)\n", 673 | "Epoch: 0, loss: 38.53774\n", 674 | "Epoch: 10, loss: 0.98634\n", 675 | "Epoch: 20, loss: 0.90574\n", 676 | "Epoch: 30, loss: 0.90399\n", 677 | "Epoch: 40, loss: 0.90436\n", 678 | "1\n", 679 | "using state RI.csv with id 2\n", 680 | "(1072, 3)\n", 681 | "Epoch: 0, loss: 122.97905\n", 682 | "Epoch: 10, loss: 47.82233\n", 683 | "Epoch: 20, loss: 46.19347\n", 684 | "Epoch: 30, loss: 46.17688\n", 685 | "Epoch: 40, loss: 36.93348\n", 686 | "2\n", 687 | "using state CA.csv with id 3\n", 688 | "(1072, 3)\n", 689 | "Epoch: 0, loss: 313.55908\n", 690 | "Epoch: 10, loss: 147.62901\n", 691 | "Epoch: 20, loss: 124.51994\n", 692 | "Epoch: 30, loss: 121.54853\n", 693 | "Epoch: 40, loss: 121.18435\n", 694 | "3\n", 695 | "using state DE.csv with id 4\n", 696 | "(1072, 3)\n", 697 | "Epoch: 0, loss: 460.85693\n", 698 | "Epoch: 10, loss: 222.34993\n", 699 | "Epoch: 20, loss: 165.13432\n", 700 | "Epoch: 30, loss: 152.42097\n", 701 | "Epoch: 40, loss: 149.85263\n", 702 | "4\n", 703 | "using state OK.csv with id 5\n", 704 | "(1072, 3)\n", 705 | "Epoch: 0, loss: 215.63779\n", 706 | "Epoch: 10, loss: 142.03969\n", 707 | "Epoch: 20, loss: 134.06017\n", 708 | "Epoch: 30, loss: 96.63786\n", 709 | "Epoch: 40, loss: 60.21392\n", 710 | "5\n", 711 | "using state NE.csv with id 6\n", 712 | "(1072, 3)\n", 713 | "Epoch: 0, loss: 243.72206\n", 714 | "Epoch: 10, loss: 79.80406\n", 715 | "Epoch: 20, loss: 56.62109\n", 716 | "Epoch: 30, loss: 54.26127\n", 717 | "Epoch: 40, loss: 54.08880\n", 718 | "6\n", 719 | "using state MD.csv with id 7\n", 720 | "(1072, 3)\n", 721 | "Epoch: 0, loss: 3959.74561\n", 722 | "Epoch: 10, loss: 3215.46313\n", 723 | "Epoch: 20, loss: 2767.78418\n", 724 | "Epoch: 30, loss: 2473.28125\n", 725 | "Epoch: 40, loss: 2279.97974\n", 726 | "7\n", 727 | "using state MA.csv with id 8\n", 728 | "(1072, 3)\n", 729 | "Epoch: 0, loss: 114.79352\n", 730 | "Epoch: 10, loss: 61.08534\n", 731 | "Epoch: 20, loss: 60.80964\n", 732 | "Epoch: 30, loss: 45.07748\n", 733 | "Epoch: 40, loss: 30.49099\n", 734 | "8\n", 735 | "using state ID.csv with id 9\n", 736 | "(1072, 3)\n", 737 | "Epoch: 0, loss: 213.31918\n", 738 | "Epoch: 10, loss: 131.20918\n", 739 | "Epoch: 20, loss: 107.49468\n", 740 | "Epoch: 30, loss: 41.61065\n", 741 | "Epoch: 40, loss: 19.14070\n", 742 | "9\n", 743 | "using state VA.csv with id 10\n", 744 | "(1072, 3)\n", 745 | "Epoch: 0, loss: 2.54596\n", 746 | "Epoch: 10, loss: 22.73453\n", 747 | "Epoch: 20, loss: 53.95797\n", 748 | "Epoch: 30, loss: 72.14917\n", 749 | "Epoch: 40, loss: 81.35642\n", 750 | "10\n", 751 | "using state TX.csv with id 11\n", 752 | "(1072, 3)\n", 753 | "Epoch: 0, loss: 1867.50024\n", 754 | "Epoch: 10, loss: 1305.24634\n", 755 | "Epoch: 20, loss: 1038.77148\n", 756 | "Epoch: 30, loss: 903.91833\n", 757 | "Epoch: 40, loss: 836.48505\n", 758 | "11\n", 759 | "using state CT.csv with id 12\n", 760 | "(1072, 3)\n", 761 | "Epoch: 0, loss: 677.68494\n", 762 | "Epoch: 10, loss: 460.92737\n", 763 | "Epoch: 20, loss: 409.16669\n", 764 | "Epoch: 30, loss: 396.24713\n", 765 | "Epoch: 40, loss: 314.09744\n", 766 | "12\n", 767 | "using state MO.csv with id 13\n", 768 | "(1072, 3)\n", 769 | "Epoch: 0, loss: 192.40056\n", 770 | "Epoch: 10, loss: 74.53628\n", 771 | "Epoch: 20, loss: 52.99356\n", 772 | "Epoch: 30, loss: 49.47045\n", 773 | "Epoch: 40, loss: 48.91344\n", 774 | "13\n", 775 | "using state GA.csv with id 14\n", 776 | "(1072, 3)\n", 777 | "Epoch: 0, loss: 1172.70850\n", 778 | "Epoch: 10, loss: 889.80865\n", 779 | "Epoch: 20, loss: 787.23199\n", 780 | "Epoch: 30, loss: 750.91718\n", 781 | "Epoch: 40, loss: 738.34302\n", 782 | "14\n", 783 | "using state IL.csv with id 15\n", 784 | "(1072, 3)\n", 785 | "Epoch: 0, loss: 149.11670\n", 786 | "Epoch: 10, loss: 105.35435\n", 787 | "Epoch: 20, loss: 88.18155\n", 788 | "Epoch: 30, loss: 61.84451\n", 789 | "Epoch: 40, loss: 48.79196\n", 790 | "15\n", 791 | "using state NJ.csv with id 16\n", 792 | "(1072, 3)\n", 793 | "Epoch: 0, loss: 1562.44666\n", 794 | "Epoch: 10, loss: 1222.52966\n", 795 | "Epoch: 20, loss: 1101.22510\n", 796 | "Epoch: 30, loss: 1059.06506\n", 797 | "Epoch: 40, loss: 1044.38916\n", 798 | "16\n", 799 | "using state AZ.csv with id 17\n", 800 | "(1072, 3)\n", 801 | "Epoch: 0, loss: 728.98303\n", 802 | "Epoch: 10, loss: 629.38275\n", 803 | "Epoch: 20, loss: 621.11206\n", 804 | "Epoch: 30, loss: 573.14001\n", 805 | "Epoch: 40, loss: 507.36209\n", 806 | "17\n", 807 | "using state AL.csv with id 18\n", 808 | "(1072, 3)\n", 809 | "Epoch: 0, loss: 87.51850\n", 810 | "Epoch: 10, loss: 74.69196\n", 811 | "Epoch: 20, loss: 70.00854\n", 812 | "Epoch: 30, loss: 57.72423\n", 813 | "Epoch: 40, loss: 44.95239\n", 814 | "18\n", 815 | "using state AR.csv with id 19\n", 816 | "(1072, 3)\n", 817 | "Epoch: 0, loss: 106.87318\n", 818 | "Epoch: 10, loss: 67.88434\n", 819 | "Epoch: 20, loss: 55.13638\n", 820 | "Epoch: 30, loss: 35.27405\n", 821 | "Epoch: 40, loss: 28.64886\n", 822 | "19\n", 823 | "using state WV.csv with id 20\n", 824 | "(1072, 3)\n", 825 | "Epoch: 0, loss: 991.78400\n", 826 | "Epoch: 10, loss: 564.91223\n", 827 | "Epoch: 20, loss: 383.94708\n", 828 | "Epoch: 30, loss: 306.40320\n", 829 | "Epoch: 40, loss: 274.71710\n", 830 | "20\n", 831 | "using state MI.csv with id 21\n", 832 | "(1072, 3)\n", 833 | "Epoch: 0, loss: 229.64537\n", 834 | "Epoch: 10, loss: 71.98681\n", 835 | "Epoch: 20, loss: 51.54762\n", 836 | "Epoch: 30, loss: 49.27250\n", 837 | "Epoch: 40, loss: 49.02810\n", 838 | "21\n", 839 | "using state NY.csv with id 22\n", 840 | "(1072, 3)\n", 841 | "Epoch: 0, loss: 366.69055\n", 842 | "Epoch: 10, loss: 141.58015\n", 843 | "Epoch: 20, loss: 87.72676\n", 844 | "Epoch: 30, loss: 86.40914\n", 845 | "Epoch: 40, loss: 95.08479\n", 846 | "22\n", 847 | "using state TN.csv with id 23\n", 848 | "(1072, 3)\n", 849 | "Epoch: 0, loss: 336.39896\n", 850 | "Epoch: 10, loss: 178.38094\n", 851 | "Epoch: 20, loss: 156.09909\n", 852 | "Epoch: 30, loss: 153.21811\n", 853 | "Epoch: 40, loss: 152.77963\n", 854 | "23\n", 855 | "using state AK.csv with id 24\n", 856 | "(1072, 3)\n", 857 | "Epoch: 0, loss: 2207.61230\n", 858 | "Epoch: 10, loss: 1358.48523\n", 859 | "Epoch: 20, loss: 826.00940\n", 860 | "Epoch: 30, loss: 482.66705\n", 861 | "Epoch: 40, loss: 268.46317\n", 862 | "24\n", 863 | "using state OR.csv with id 25\n", 864 | "(1072, 3)\n", 865 | "Epoch: 0, loss: 445.54007\n", 866 | "Epoch: 10, loss: 356.07941\n", 867 | "Epoch: 20, loss: 333.89703\n", 868 | "Epoch: 30, loss: 279.61722\n", 869 | "Epoch: 40, loss: 253.68886\n", 870 | "25\n", 871 | "using state NV.csv with id 26\n", 872 | "(1072, 3)\n", 873 | "Epoch: 0, loss: 4325.15967\n", 874 | "Epoch: 10, loss: 3244.65332\n", 875 | "Epoch: 20, loss: 2456.90918\n", 876 | "Epoch: 30, loss: 1843.98718\n", 877 | "Epoch: 40, loss: 1370.25610\n", 878 | "26\n", 879 | "using state KS.csv with id 27\n", 880 | "(1072, 3)\n", 881 | "Epoch: 0, loss: 61.25449\n", 882 | "Epoch: 10, loss: 31.72603\n", 883 | "Epoch: 20, loss: 31.85670\n", 884 | "Epoch: 30, loss: 31.67803\n", 885 | "Epoch: 40, loss: 30.37113\n", 886 | "27\n", 887 | "using state NC.csv with id 28\n", 888 | "(1072, 3)\n", 889 | "Epoch: 0, loss: 3885.39258\n", 890 | "Epoch: 10, loss: 3089.87793\n", 891 | "Epoch: 20, loss: 2625.81885\n", 892 | "Epoch: 30, loss: 2342.19604\n", 893 | "Epoch: 40, loss: 2167.16064\n", 894 | "28\n", 895 | "using state ME.csv with id 29\n", 896 | "(1072, 3)\n", 897 | "Epoch: 0, loss: 123.38239\n", 898 | "Epoch: 10, loss: 73.97655\n", 899 | "Epoch: 20, loss: 73.01733\n", 900 | "Epoch: 30, loss: 73.86558\n", 901 | "Epoch: 40, loss: 73.79018\n", 902 | "29\n", 903 | "using state WY.csv with id 30\n", 904 | "(1072, 3)\n", 905 | "Epoch: 0, loss: 117.26199\n", 906 | "Epoch: 10, loss: 16.33590\n", 907 | "Epoch: 20, loss: 12.38945\n", 908 | "Epoch: 30, loss: 12.34836\n", 909 | "Epoch: 40, loss: 12.34048\n", 910 | "30\n", 911 | "using state MN.csv with id 31\n", 912 | "(1072, 3)\n", 913 | "Epoch: 0, loss: 3542.01050\n", 914 | "Epoch: 10, loss: 2562.97729\n", 915 | "Epoch: 20, loss: 1942.95447\n", 916 | "Epoch: 30, loss: 1497.83618\n", 917 | "Epoch: 40, loss: 1177.14331\n", 918 | "31\n", 919 | "using state VT.csv with id 32\n", 920 | "(1072, 3)\n", 921 | "Epoch: 0, loss: 176.13931\n", 922 | "Epoch: 10, loss: 127.03709\n", 923 | "Epoch: 20, loss: 98.37129\n", 924 | "Epoch: 30, loss: 60.76028\n", 925 | "Epoch: 40, loss: 53.36376\n", 926 | "32\n", 927 | "using state WA.csv with id 33\n", 928 | "(1072, 3)\n", 929 | "Epoch: 0, loss: 323.65942\n", 930 | "Epoch: 10, loss: 106.61323\n", 931 | "Epoch: 20, loss: 46.15316\n", 932 | "Epoch: 30, loss: 32.57630\n", 933 | "Epoch: 40, loss: 12.41098\n", 934 | "33\n", 935 | "using state NH.csv with id 34\n", 936 | "(1072, 3)\n", 937 | "Epoch: 0, loss: 122.54185\n", 938 | "Epoch: 10, loss: 41.88740\n", 939 | "Epoch: 20, loss: 45.35485\n", 940 | "Epoch: 30, loss: 50.76578\n", 941 | "Epoch: 40, loss: 52.12760\n", 942 | "34\n", 943 | "using state CO.csv with id 35\n", 944 | "(1072, 3)\n", 945 | "Epoch: 0, loss: 273.32294\n", 946 | "Epoch: 10, loss: 195.18814\n", 947 | "Epoch: 20, loss: 192.85912\n", 948 | "Epoch: 30, loss: 192.83170\n", 949 | "Epoch: 40, loss: 192.83920\n", 950 | "35\n", 951 | "using state MT.csv with id 36\n", 952 | "(1072, 3)\n", 953 | "Epoch: 0, loss: 125.15608\n", 954 | "Epoch: 10, loss: 62.74366\n", 955 | "Epoch: 20, loss: 60.65171\n", 956 | "Epoch: 30, loss: 60.20601\n", 957 | "Epoch: 40, loss: 55.03458\n", 958 | "36\n", 959 | "using state NM.csv with id 37\n", 960 | "(1072, 3)\n", 961 | "Epoch: 0, loss: 187.18834\n", 962 | "Epoch: 10, loss: 60.34159\n", 963 | "Epoch: 20, loss: 40.72130\n", 964 | "Epoch: 30, loss: 37.79882\n", 965 | "Epoch: 40, loss: 37.27078\n", 966 | "37\n", 967 | "using state SD.csv with id 38\n", 968 | "(1072, 3)\n", 969 | "Epoch: 0, loss: 5878.42236\n", 970 | "Epoch: 10, loss: 4561.66016\n", 971 | "Epoch: 20, loss: 3617.08008\n", 972 | "Epoch: 30, loss: 2882.16138\n", 973 | "Epoch: 40, loss: 2304.55225\n", 974 | "38\n", 975 | "using state MS.csv with id 39\n", 976 | "(1072, 3)\n", 977 | "Epoch: 0, loss: 46.37638\n", 978 | "Epoch: 10, loss: 0.60019\n", 979 | "Epoch: 20, loss: 0.59633\n", 980 | "Epoch: 30, loss: 0.59322\n", 981 | "Epoch: 40, loss: 0.59284\n", 982 | "39\n", 983 | "using state IA.csv with id 40\n", 984 | "(1072, 3)\n", 985 | "Epoch: 0, loss: 99.70940\n", 986 | "Epoch: 10, loss: 32.10049\n", 987 | "Epoch: 20, loss: 31.88604\n", 988 | "Epoch: 30, loss: 31.89997\n", 989 | "Epoch: 40, loss: 29.17747\n", 990 | "40\n", 991 | "using state OH.csv with id 41\n", 992 | "(1072, 3)\n", 993 | "Epoch: 0, loss: 77.08321\n", 994 | "Epoch: 10, loss: 28.49914\n", 995 | "Epoch: 20, loss: 28.50876\n", 996 | "Epoch: 30, loss: 28.51362\n", 997 | "Epoch: 40, loss: 28.53220\n", 998 | "41\n", 999 | "using state PA.csv with id 42\n", 1000 | "(1072, 3)\n", 1001 | "Epoch: 0, loss: 650.95270\n", 1002 | "Epoch: 10, loss: 491.24945\n", 1003 | "Epoch: 20, loss: 460.68283\n", 1004 | "Epoch: 30, loss: 455.09427\n", 1005 | "Epoch: 40, loss: 454.00565\n", 1006 | "42\n", 1007 | "using state HI.csv with id 43\n", 1008 | "(1072, 3)\n", 1009 | "Epoch: 0, loss: 346.25104\n", 1010 | "Epoch: 10, loss: 120.43610\n", 1011 | "Epoch: 20, loss: 78.20177\n", 1012 | "Epoch: 30, loss: 72.54398\n", 1013 | "Epoch: 40, loss: 72.13769\n", 1014 | "43\n", 1015 | "using state IN.csv with id 44\n", 1016 | "(1072, 3)\n", 1017 | "Epoch: 0, loss: 2426.91943\n", 1018 | "Epoch: 10, loss: 1633.79395\n", 1019 | "Epoch: 20, loss: 1175.59534\n", 1020 | "Epoch: 30, loss: 892.70160\n", 1021 | "Epoch: 40, loss: 720.68121\n", 1022 | "44\n", 1023 | "using state WI.csv with id 45\n", 1024 | "(1072, 3)\n", 1025 | "Epoch: 0, loss: 1117.76929\n", 1026 | "Epoch: 10, loss: 660.60468\n", 1027 | "Epoch: 20, loss: 458.01068\n", 1028 | "Epoch: 30, loss: 377.14993\n", 1029 | "Epoch: 40, loss: 346.79745\n", 1030 | "45\n", 1031 | "using state FL.csv with id 46\n", 1032 | "(1072, 3)\n", 1033 | "Epoch: 0, loss: 509.20251\n", 1034 | "Epoch: 10, loss: 366.02621\n", 1035 | "Epoch: 20, loss: 345.30341\n", 1036 | "Epoch: 30, loss: 342.55408\n" 1037 | ] 1038 | }, 1039 | { 1040 | "name": "stdout", 1041 | "output_type": "stream", 1042 | "text": [ 1043 | "Epoch: 40, loss: 331.77246\n", 1044 | "46\n", 1045 | "using state UT.csv with id 47\n", 1046 | "(1072, 3)\n", 1047 | "Epoch: 0, loss: 2415.67578\n", 1048 | "Epoch: 10, loss: 1702.83655\n", 1049 | "Epoch: 20, loss: 1299.95361\n", 1050 | "Epoch: 30, loss: 1056.56775\n", 1051 | "Epoch: 40, loss: 913.46002\n", 1052 | "47\n", 1053 | "using state LA.csv with id 48\n", 1054 | "(1072, 3)\n", 1055 | "Epoch: 0, loss: 117.05021\n", 1056 | "Epoch: 10, loss: 50.56598\n", 1057 | "Epoch: 20, loss: 42.95673\n", 1058 | "Epoch: 30, loss: 28.42779\n", 1059 | "Epoch: 40, loss: 26.35994\n", 1060 | "48\n", 1061 | "using state SC.csv with id 49\n", 1062 | "(1072, 3)\n", 1063 | "Epoch: 0, loss: 840.85248\n", 1064 | "Epoch: 10, loss: 560.76440\n", 1065 | "Epoch: 20, loss: 481.92490\n", 1066 | "Epoch: 30, loss: 460.05231\n", 1067 | "Epoch: 40, loss: 454.32501\n", 1068 | "49\n", 1069 | "(50, 9)\n" 1070 | ] 1071 | } 1072 | ], 1073 | "source": [ 1074 | "params = Parameters()\n", 1075 | "params.num_epochs=50\n", 1076 | "params.num_layers=2\n", 1077 | "params.dropout=0.5\n", 1078 | "Parameters(2, 20, 100, 6, 3, 50, 0.01, 0)\n", 1079 | "\n", 1080 | "columns = ['MAE', 'RMSE', 'MAPE', 'MEAN_MAE', 'MEAN_RMSE', 'MEAN_MAPE', 'NAIVE_MAE', 'NAIVE_RMSE', 'NAIVE_MAPE']\n", 1081 | "df = pd.DataFrame(columns = columns, dtype=np.float64)\n", 1082 | " \n", 1083 | "for i, state in enumerate(listdir(\"samples/\")):\n", 1084 | " training_set = readData(\"samples/\"+state, freq=1)\n", 1085 | " data = Data()\n", 1086 | " generateData(state, data, params)\n", 1087 | " #naives = generateNaive(data, params)\n", 1088 | " model = train(data, params)\n", 1089 | " preds, labels = test(model, data, params)\n", 1090 | " #print(\"----- {} Results -----\".format(state.replace(\".csv\", \"\")))\n", 1091 | " err_results = print_errors(preds, labels)\n", 1092 | " #print(a_row.values)\n", 1093 | "\n", 1094 | " #for naive in naives:\n", 1095 | " # err_results.extend(print_errors(naive, labels)) \n", 1096 | " err_results.extend([0, 0, 0, 0, 0, 0])\n", 1097 | " \n", 1098 | " row_df = pd.DataFrame([err_results], index = [state.replace(\".csv\", \"\")], columns = columns, dtype=np.float64)\n", 1099 | " df = pd.concat([row_df, df])\n", 1100 | " print(i)\n", 1101 | " \n", 1102 | " \n", 1103 | "print(df.shape)\n", 1104 | "df.to_csv(\"lstm-out/concur-{}.csv\".format(params))\n" 1105 | ] 1106 | }, 1107 | { 1108 | "cell_type": "code", 1109 | "execution_count": null, 1110 | "metadata": {}, 1111 | "outputs": [], 1112 | "source": [] 1113 | } 1114 | ], 1115 | "metadata": { 1116 | "colab": { 1117 | "collapsed_sections": [], 1118 | "name": "CPU_LSTM.ipynb", 1119 | "provenance": [] 1120 | }, 1121 | "kernelspec": { 1122 | "display_name": "Python 3", 1123 | "language": "python", 1124 | "name": "python3" 1125 | }, 1126 | "language_info": { 1127 | "codemirror_mode": { 1128 | "name": "ipython", 1129 | "version": 3 1130 | }, 1131 | "file_extension": ".py", 1132 | "mimetype": "text/x-python", 1133 | "name": "python", 1134 | "nbconvert_exporter": "python", 1135 | "pygments_lexer": "ipython3", 1136 | "version": "3.8.2" 1137 | } 1138 | }, 1139 | "nbformat": 4, 1140 | "nbformat_minor": 1 1141 | } 1142 | --------------------------------------------------------------------------------