{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"language_info": {
"name": "python"
}
},
"cells": [
{
"cell_type": "code",
"source": [],
"metadata": {
"id": "pLjFKWlSzdqV"
},
"execution_count": 2,
"outputs": []
},
{
"cell_type": "code",
"source": [
"import os\n",
"import numpy as np\n",
"import pandas as pd\n",
"import matplotlib.pyplot as plt\n",
"import seaborn as sns\n",
"from sklearn.preprocessing import MinMaxScaler\n",
"from sklearn.metrics import mean_squared_error, mean_absolute_percentage_error\n",
"from statsmodels.tsa.arima.model import ARIMA\n",
"import joblib\n",
"import tensorflow as tf\n",
"from tensorflow.keras.models import Sequential\n",
"from tensorflow.keras.layers import LSTM, Dense, Dropout\n",
"from tqdm import tqdm\n",
"import math"
],
"metadata": {
"id": "3iWsmvlBzeYS"
},
"execution_count": 3,
"outputs": []
},
{
"cell_type": "code",
"source": [
"df = pd.read_csv(\"AAPL.csv\", parse_dates=[\"Date\"])\n",
"df = df.sort_values(\"Date\").reset_index(drop=True)\n",
"df = df[[\"Date\", \"Close\"]].dropna()\n",
"df.head()"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 206
},
"id": "eJyekwToztb0",
"outputId": "a6def601-8d25-490e-a66c-48c3f28d56f3"
},
"execution_count": 4,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" Date Close\n",
"0 2005-10-17 6.60\n",
"1 2005-10-18 6.45\n",
"2 2005-10-19 6.78\n",
"3 2005-10-20 6.93\n",
"4 2005-10-21 6.87"
],
"text/html": [
"\n",
"
\n",
"
\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" Date | \n",
" Close | \n",
"
\n",
" \n",
" \n",
" \n",
" | 0 | \n",
" 2005-10-17 | \n",
" 6.60 | \n",
"
\n",
" \n",
" | 1 | \n",
" 2005-10-18 | \n",
" 6.45 | \n",
"
\n",
" \n",
" | 2 | \n",
" 2005-10-19 | \n",
" 6.78 | \n",
"
\n",
" \n",
" | 3 | \n",
" 2005-10-20 | \n",
" 6.93 | \n",
"
\n",
" \n",
" | 4 | \n",
" 2005-10-21 | \n",
" 6.87 | \n",
"
\n",
" \n",
"
\n",
"
\n",
"
\n",
"
\n"
],
"application/vnd.google.colaboratory.intrinsic+json": {
"type": "dataframe",
"variable_name": "df",
"summary": "{\n \"name\": \"df\",\n \"rows\": 3732,\n \"fields\": [\n {\n \"column\": \"Date\",\n \"properties\": {\n \"dtype\": \"date\",\n \"min\": \"2005-10-17 00:00:00\",\n \"max\": \"2020-08-13 00:00:00\",\n \"num_unique_values\": 3732,\n \"samples\": [\n \"2017-03-10 00:00:00\",\n \"2015-09-21 00:00:00\",\n \"2012-06-14 00:00:00\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Close\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 79.18974349598857,\n \"min\": 6.26,\n \"max\": 460.04,\n \"num_unique_values\": 3202,\n \"samples\": [\n 152.03,\n 17.8,\n 34.14\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n }\n ]\n}"
}
},
"metadata": {},
"execution_count": 4
}
]
},
{
"cell_type": "code",
"source": [],
"metadata": {
"id": "UabNmIv4BUzp"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [],
"metadata": {
"id": "iYYOcd45BW0A"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"plt.figure(figsize=(12,4))\n",
"plt.plot(df.Date, df.Close)\n",
"plt.title(\"Daily Close Price\")\n",
"plt.xlabel(\"Date\")\n",
"plt.ylabel(\"Close\")\n",
"plt.show()\n"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 303
},
"id": "7kvQp1eAz_Ys",
"outputId": "5a1d218f-b6a4-473a-acbc-83bf62dfbfd0"
},
"execution_count": 5,
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
""
],
"image/png": "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JCenvP88sle/AQDIL4J2AADs6OTJk4qNjbUJbO+++26tXbtW48ePV+vWreXp6SmLxaJ+/frJYrEU+B7Dhg3TO++8o99++0333Xefvv/+e91yyy3y8fG56nWNGzeWJO3cuVPdunUr8H2zXGsrNZPJpHnz5mn9+vX6888/tWjRIj344IN67733tH79euvzBwQE2MwYyM7f3z9ffenevbs1e3xeCprF/2rs1W8AAPKLoB0AADv69ttvJUmhoaGSpAsXLmjp0qV67bXXNHHiRGu9gwcPFvoezZs3V5s2bTR79mwFBwfr+PHj+vjjj6953a233qrJkyfru+++K1TQXqtWLVksFh08eFBNmjSxlkdGRiomJka1atWyqd+pUyd16tRJb775pr7//nsNGTJEc+bM0UMPPaR69eppyZIl6tKli12D6utRr149bdiwQWlpaXJ2ds6zTmnrNwCgfGNNOwAAdrJs2TJNmjRJderUsWZxz9p33bgiS/zUqVOv615Dhw7VP//8o6lTp8rPz0/9+/e/5jUhISHq16+fvvzyS/322285zqempurZZ5/N8/qbb75ZUs6+v//++5KkAQMGSMr8ouLK523durUkWbeGu/vuu5WRkaFJkybluE96erpiYmKu+Tz2NnjwYEVHR+t///tfjnNZz1Ma+w0AKN8YaQcAoBD+/vtv7du3T+np6YqMjNSyZcu0ePFi1apVS3/88YdcXV0lZa4j7969u6ZMmaK0tDRVr15d//zzj3Uf8cK6//779dxzz+nXX3/VY489lufI8JW++eYb9e3bV4MGDdKtt96qG2+8UR4eHjp48KDmzJmjM2fO5LlXe6tWrTR8+HB9/vnniomJUY8ePbRx40bNmjVLAwcOtG6lNmvWLH3yySe64447VK9ePcXHx+uLL76Qt7e3NfDv0aOHRo8ercmTJ2vbtm3q27evnJ2ddfDgQc2dO1cffvih7rzzzuv6HRXUsGHD9M0332jcuHHauHGjunXrpsTERC1ZskSPP/64br/99lLZbwBA+UbQDgBAIWRNdXdxcVHlypXVokULTZ06VSNHjsyRnf3777/XE088oWnTpskwDPXt21d///23qlWrVuj7BwYGqm/fvlqwYEGB9l339/fX2rVr9cknn+jHH3/Uiy++qNTUVNWqVUu33Xabnnrqqate/+WXX6pu3bqaOXOmfv31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TZw4UXv37tWff/6pm266yd59BAAAAAAUs792nJFUPAG1PfZ8L68KNdIuSd26ddPixYvt2RcAAAAAQCkQn5ymDeHnJUkX7LhX+w21K9mslce1FerrjBMnTujkyZPW440bN+rpp5/W559/breOAQAAAABKxuqD0dbPaRmG3dp9Y2ALu7VVURQqaL///vu1fPlySVJERIT69OmjjRs36sUXX9Trr79u1w4CAAAAAIpXeHRikbRryH5fAFQUhQrad+3apQ4dOkiSfvrpJ7Vo0UJr167V7NmzNXPmTHv2DwAAAABQzLIH7T7u9sscz9r1givUbywtLU1ms1mStGTJEt12222SpMaNG+vMmTP26x0AAAAAoNgt2Hk5rnu0u/32aK9bxcNubVUUhQramzVrpk8//VSrV6/W4sWL1a9fP0nS6dOn5efnZ9cOAgAAAACKT1JqupJSM7d7+/7hjmoR7GO3tk0mk0Z0rm099jQ7adHT3e3WfnlUqKD97bff1meffaaePXvqvvvuU6tWrSRJf/zxh3XaPAAAAACg7Nl7Jt76uVWwr93bd3IwWT//NDpEjYK87H6P8qRQW7717NlT0dHRiouLU6VKlazljzzyiNzd3e3WOQAAAABA8dly/IIGT18rSerZyF8e5kLvEp4nR8fLQbtjtgAeuSv0G3B0dFR6errWrFkjSWrUqJFq165tr34BAAAAAIrZnI3HrZ9r+xXN+nNnh8sTvslLd22F+hUlJibqwQcfVNWqVdW9e3d1795d1apV06hRo5SUlGTvPgIAAAAAikHipbXsktSveVCR3CP76LqDiZH2aylU0D5u3DitXLlSf/75p2JiYhQTE6Pff/9dK1eu1H/+8x979xEAAAAAUAySLwXtt7Ssqk51iybJePY17UyPv7ZCTY//+eefNW/ePPXs2dNadvPNN8vNzU133323pk+fbq/+AQAAAECJMwxD6Raj3O8znpU1vm+zohlll2zXtDPSfm2F+icuKSlJgYGBOcoDAgKYHg8AAACg3Hl27g51eHOJohNSSrorRcYwDG0/GSNJ8na1fwK6LEHertbPDoy0X1OhgvaQkBC98sorSk5OtpZdvHhRr732mkJCQuzWOQAAAAAoDX7eclIXktL0x7bTJd2VIvPOov3WkfYqnuYiu089f0/rZ0dG2q+pUF+ffPjhhwoNDVVwcLB1j/bt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V16R2Wwu6a7gOvAeywfeY/nAeywfeI/lA++xfOA9lg+8x6JFIjoAAAAAAEopRtoBAAAAACilCNoBAAAAACilCNoBAAAAACilCNoBAAAAACilCNpLscmTJ+uGG26Ql5eXAgICNHDgQO3fv9+mTnJyssaMGSM/Pz95enpq8ODBioyMtKlz/PhxDRgwQO7u7goICND48eOVnp5uUyclJUUvvviiatWqJbPZrNq1a+vrr78u8mesCIrzPc6ePVutWrWSu7u7qlatqgcffFDnzp0r8mesCOz1Hp988km1a9dOZrNZrVu3zvVeO3bsULdu3eTq6qoaNWpoypQpRfVYFU5xvccVK1bo9ttvV9WqVeXh4aHWrVtr9uzZRfloFU5x/juZ5dChQ/Ly8pKvr6+dn6ZiKs53aBiG3n33XTVs2FBms1nVq1fXm2++WVSPVuEU57tctGiROnXqJC8vL/n7+2vw4ME6evRoET1ZxWKP97h9+3bdd999qlGjhtzc3NSkSRN9+OGHOe61YsUKtW3bVmazWfXr19fMmTOL+vHKNIL2UmzlypUaM2aM1q9fr8WLFystLU19+/ZVYmKitc4zzzyjP//8U3PnztXKlSt1+vRpDRo0yHo+IyNDAwYMUGpqqtauXatZs2Zp5syZmjhxos297r77bi1dulRfffWV9u/frx9++EGNGjUqtmctz4rrPf77778aNmyYRo0apd27d2vu3LnauHGjHn744WJ93vLKHu8xy4MPPqh77rkn1/vExcWpb9++qlWrlsLCwvTOO+/o1Vdf1eeff15kz1aRFNd7XLt2rVq2bKmff/5ZO3bs0MiRIzVs2DDNnz+/yJ6toimud5klLS1N9913n7p162b3Z6moivMdPvXUU/ryyy/17rvvat++ffrjjz/UoUOHInmuiqi43mV4eLhuv/129e7dW9u2bdOiRYsUHR2dazsoOHu8x7CwMAUEBOi7777T7t279eKLL2rChAn63//+Z60THh6uAQMGqFevXtq2bZuefvppPfTQQ1q0aFGxPm+ZYqDMiIqKMiQZK1euNAzDMGJiYgxnZ2dj7ty51jp79+41JBnr1q0zDMMwFixYYDg4OBgRERHWOtOnTze8vb2NlJQUwzAM4++//zZ8fHyMc+fOFePTVFxF9R7feecdo27dujb3+uijj4zq1asX9SNVSIV5j9m98sorRqtWrXKUf/LJJ0alSpWs79UwDOO///2v0ahRI/s/BIrsPebm5ptvNkaOHGmXfiOnon6Xzz33nPHAAw8YM2bMMHx8fOzdfRhF9w737NljODk5Gfv27SuyvsNWUb3LuXPnGk5OTkZGRoa17I8//jBMJpORmppq/wep4K73PWZ5/PHHjV69elmPn3vuOaNZs2Y2de655x4jNDTUzk9QfjDSXobExsZKkipXriwp85ustLQ09enTx1qncePGqlmzptatWydJWrdunVq0aKHAwEBrndDQUMXFxWn37t2SpD/++EPt27fXlClTVL16dTVs2FDPPvusLl68WFyPVqEU1XsMCQnRiRMntGDBAhmGocjISM2bN08333xzcT1ahVKY95gf69atU/fu3eXi4mItCw0N1f79+3XhwgU79R5Ziuo95nWvrPvA/oryXS5btkxz587VtGnT7Ndh5FBU7/DPP/9U3bp1NX/+fNWpU0e1a9fWQw89pPPnz9v3AWBVVO+yXbt2cnBw0IwZM5SRkaHY2Fh9++236tOnj5ydne37ELDbe7zyv3/r1q2zaUPK/Fvnev87W54RtJcRFotFTz/9tLp06aLmzZtLkiIiIuTi4pJjbV1gYKAiIiKsdbIHelnns85J0pEjR7RmzRrt2rVLv/76q6ZOnap58+bp8ccfL+KnqniK8j126dJFs2fP1j333CMXFxcFBQXJx8eHPzKLQGHfY37k513DPoryPV7pp59+0qZNmzRy5Mjr6TLyUJTv8ty5cxoxYoRmzpwpb29ve3Yb2RTlOzxy5IiOHTumuXPn6ptvvtHMmTMVFhamO++8056PgEuK8l3WqVNH//zzj1544QWZzWb5+vrq5MmT+umnn+z5CJD93uPatWv1448/6pFHHrGW5fW3TlxcHIOGeSBoLyPGjBmjXbt2ac6cOXZv22KxyGQyafbs2erQoYNuvvlmvf/++5o1axb/4thZUb7HPXv26KmnntLEiRMVFhamhQsX6ujRo3r00Uftfq+KrijfI4pPcb3H5cuXa+TIkfriiy/UrFmzIr1XRVWU7/Lhhx/W/fffr+7du9u9bVxW1H/npKSk6JtvvlG3bt3Us2dPffXVV1q+fHmOJFu4fkX5LiMiIvTwww9r+PDh2rRpk1auXCkXFxfdeeedMgzD7veryOzxHnft2qXbb79dr7zyivr27WvH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SqmpqXkG7QkJCXJ0dFRYWJgcHR1tznl6ehbHIwAAUKYRtAMAgFwtW7ZMO3fu1DPPPKOwsDBZLBa99957cnDITInz008/2dR3cXFRRkaGTVmbNm2UkZGhqKgodevWrdj6DgBAeUHQDgAAlJKSooiICGVkZCgyMlILFy7U5MmTdcstt2jYsGHatWuX0tLS9PHHH+vWW2/Vv//+q08//dSmjdq1ayshIUFLly5Vq1at5O7uroYNG2rIkCEaNmyY3nvvPbVp00Znz57V0qVL1bJlSw0YMKCEnhgAgLKB7PEAAEALFy5U1apVVbt2bfXr10/Lly/XRx99pN9//12Ojo5q1aqV3n//fb399ttq3ry5Zs+ercmTJ9u00blzZz366KO655575O/vrylTpkiSZsyYoWHDhuk///mPGjVqpIEDB2rTpk2qWbNmSTwqAABlCtnjAQAAAAAopRhpBwAAAACglCJoBwAAAACglCJoBwAAAACglCJoBwAAAACglCJoBwAAAACglCJoBwAAAACglCJoBwAAAACglCJoBwAAAACglCJoBwAAAACglCJoBwAAAACglCJoBwAAAACglPp/sLZszXRQl68AAAAASUVORK5CYII=\n"
},
"metadata": {}
}
]
},
{
"cell_type": "code",
"source": [
"def train_val_test_split_by_date(df, val_size=0.1, test_size=0.1):\n",
" n = len(df)\n",
" test_n = int(n * test_size)\n",
" val_n = int(n * val_size)\n",
" train = df.iloc[: n - val_n - test_n].copy()\n",
" val = df.iloc[n - val_n - test_n: n - test_n].copy()\n",
" test = df.iloc[n - test_n:].copy()\n",
" return train, val, test\n",
"\n",
"def scale_series(train_series, val_series=None, test_series=None):\n",
" scaler = MinMaxScaler()\n",
" train_scaled = scaler.fit_transform(train_series.values.reshape(-1,1)).flatten()\n",
" result = {'scaler': scaler, 'train': train_scaled}\n",
" if val_series is not None:\n",
" result['val'] = scaler.transform(val_series.values.reshape(-1,1)).flatten()\n",
" if test_series is not None:\n",
" result['test'] = scaler.transform(test_series.values.reshape(-1,1)).flatten()\n",
" return result"
],
"metadata": {
"id": "QB1cBsh90USz"
},
"execution_count": 6,
"outputs": []
},
{
"cell_type": "code",
"source": [
"def rmse(y_true, y_pred):\n",
" return math.sqrt(mean_squared_error(y_true, y_pred))\n",
"\n",
"def mape(y_true, y_pred):\n",
" # sklearn's MAPE expects non-zero y_true; add tiny epsilon to avoid division by zero\n",
" return mean_absolute_percentage_error(y_true, y_pred)"
],
"metadata": {
"id": "UdWqkn-Y0bF3"
},
"execution_count": 7,
"outputs": []
},
{
"cell_type": "code",
"source": [
"def rolling_forecast(df_dates, series, model_forecast_func, window_size, horizon, step=1):\n",
" \"\"\"\n",
" df_dates: list/dates (for indexing)\n",
" series: 1D np.array of the full series (unscaled or scaled — be consistent)\n",
" model_forecast_func: function(history_array, horizon) -> forecast_array (length=horizon)\n",
" window_size: number of points used for fitting each step\n",
" horizon: forecast horizon\n",
" step: sliding step\n",
" Returns: dict with predictions, truths, indices\n",
" \"\"\"\n",
" preds = []\n",
" truths = []\n",
" indices = [] # index of start of truth\n",
" n = len(series)\n",
" # we forecast for times where we have at least window_size history and horizon future\n",
" start = window_size\n",
" end = n - horizon + 1\n",
" for t in range(start, end, step):\n",
" history = series[t-window_size:t]\n",
" y_true = series[t:t+horizon]\n",
" y_pred = model_forecast_func(history, horizon)\n",
" preds.append(y_pred)\n",
" truths.append(y_true)\n",
" indices.append(t)\n",
" preds = np.array(preds)\n",
" truths = np.array(truths)\n",
" return {'preds': preds, 'truths': truths, 'indices': indices}\n"
],
"metadata": {
"id": "T5sr7p5T0gPr"
},
"execution_count": 8,
"outputs": []
},
{
"cell_type": "code",
"source": [
"from statsmodels.tools.sm_exceptions import ConvergenceWarning\n",
"import warnings\n",
"warnings.simplefilter('ignore', ConvergenceWarning)\n",
"warnings.filterwarnings(\"ignore\")\n",
"\n",
"def arima_forecast(history, horizon, order=(5,1,0)):\n",
" # history: 1D numpy array (not scaled inverse needed outside)\n",
" try:\n",
" model = ARIMA(history, order=order)\n",
" model_fit = model.fit()\n",
" fc = model_fit.forecast(steps=horizon)\n",
" return np.array(fc)\n",
" except Exception as e:\n",
" # fallback: naive persistence (last value)\n",
" last = history[-1]\n",
" return np.array([last]*horizon)"
],
"metadata": {
"id": "MD8jTBHV0gtN"
},
"execution_count": 9,
"outputs": []
},
{
"cell_type": "code",
"source": [
"def create_sequences(arr, seq_len=30, horizon=1):\n",
" X, y = [], []\n",
" for i in range(len(arr) - seq_len - horizon + 1):\n",
" X.append(arr[i:i+seq_len])\n",
" y.append(arr[i+seq_len:i+seq_len+horizon])\n",
" X = np.array(X)\n",
" y = np.array(y)\n",
" # reshape X for LSTM: (samples, seq_len, features)\n",
" X = X.reshape((X.shape[0], X.shape[1], 1))\n",
" return X, y\n",
"\n",
"def build_lstm(seq_len=30, horizon=1, hidden_units=64, dropout=0.1):\n",
" model = Sequential([\n",
" LSTM(hidden_units, input_shape=(seq_len,1)),\n",
" Dropout(dropout),\n",
" Dense(horizon)\n",
" ])\n",
" model.compile(optimizer='adam', loss='mse')\n",
" return model"
],
"metadata": {
"id": "cQ8Uf9vz1NHU"
},
"execution_count": 10,
"outputs": []
},
{
"cell_type": "code",
"source": [
"def lstm_forecast(history, horizon, seq_len=30, epochs=50, verbose=0):\n",
" \"\"\"\n",
" history: 1D numpy array (scaled between 0-1 ideally)\n",
" We'll use the last portion of history to create training sequences.\n",
" For speed in rolling eval, reduce epochs like 5-20.\n",
" \"\"\"\n",
" if len(history) < seq_len + horizon + 1:\n",
" # fallback to persistence\n",
" last = history[-1]\n",
" return np.array([last]*horizon)\n",
" X, y = create_sequences(history, seq_len=seq_len, horizon=horizon)\n",
" # if only one sample, fallback\n",
" if X.shape[0] < 5:\n",
" # not enough data to train; return persistence\n",
" return np.array([history[-1]]*horizon)\n",
" model = build_lstm(seq_len=seq_len, horizon=horizon, hidden_units=64)\n",
" # early stop lightly\n",
" model.fit(X, y, epochs=epochs, batch_size=16, verbose=verbose)\n",
" # prepare input: last seq_len values\n",
" input_seq = history[-seq_len:].reshape((1, seq_len, 1))\n",
" pred = model.predict(input_seq, verbose=0).flatten()\n",
" return pred\n"
],
"metadata": {
"id": "MFICh0_f0i6Y"
},
"execution_count": 11,
"outputs": []
},
{
"cell_type": "code",
"source": [
"train, val, test = train_val_test_split_by_date(df, val_size=0.1, test_size=0.1)\n",
"full_series = df['Close'].values\n",
"dates = df['Date'].values\n",
"\n",
"# scaler fit on train\n",
"scaler = MinMaxScaler()\n",
"scaler.fit(train[['Close']])\n",
"full_scaled = scaler.transform(df[['Close']]).flatten()\n",
"\n",
"# define indices for test start\n",
"test_start_idx = df.index[df['Date'] == test['Date'].iloc[0]][0]\n",
"print(\"test starts at index\", test_start_idx)\n"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "6FNVyBDu1R9U",
"outputId": "fdb90086-6117-4315-f6d2-afe17d70de5d"
},
"execution_count": 12,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"test starts at index 3359\n"
]
}
]
},
{
"cell_type": "code",
"source": [
"window_size = 252\n",
"horizon = 5\n",
"step = 5 # slide every 5 days to reduce compute\n",
"\n",
"# ARIMA rolling (on original scale)\n",
"def arima_wrapper(history, horizon):\n",
" return arima_forecast(history, horizon, order=(5,1,0))\n",
"\n",
"res_arima = rolling_forecast(dates, full_series, arima_wrapper, window_size=window_size, horizon=horizon, step=step)\n",
"\n",
"# LSTM rolling (on scaled scale)\n",
"def lstm_wrapper_scaled(history, horizon):\n",
" # history comes scaled here\n",
" pred_scaled = lstm_forecast(history, horizon, seq_len=30, epochs=10, verbose=0)\n",
" # inverse scale predictions before returning (history was scaled w/ scaler fitted earlier)\n",
" pred_scaled = np.array(pred_scaled)\n",
" # inverse transform: need reshape\n",
" pred_inv = scaler.inverse_transform(pred_scaled.reshape(-1,1)).flatten()\n",
" return pred_inv\n",
"\n",
"# But rolling_forecast expects one series. We'll feed scaled but keep mapping.\n",
"res_lstm = rolling_forecast(dates, full_scaled,\n",
" model_forecast_func=lambda h, fw: scaler.inverse_transform(lstm_forecast(h, fw, seq_len=30, epochs=10, verbose=0).reshape(-1,1)).flatten(),\n",
" window_size=window_size,\n",
" horizon=horizon,\n",
" step=step)"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "_GjH-fgv1a3q",
"outputId": "fb50c21a-3e34-44cc-aae2-40a4b9d7a978"
},
"execution_count": 13,
"outputs": [
{
"output_type": "stream",
"name": "stderr",
"text": [
"WARNING:tensorflow:5 out of the last 5 calls to .one_step_on_data_distributed at 0x7ba3a086b420> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has reduce_retracing=True option that can avoid unnecessary retracing. For (3), please refer to https://www.tensorflow.org/guide/function#controlling_retracing and https://www.tensorflow.org/api_docs/python/tf/function for more details.\n",
"WARNING:tensorflow:6 out of the last 6 calls to .one_step_on_data_distributed at 0x7ba3832c27a0> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has reduce_retracing=True option that can avoid unnecessary retracing. For (3), please refer to https://www.tensorflow.org/guide/function#controlling_retracing and https://www.tensorflow.org/api_docs/python/tf/function for more details.\n"
]
}
]
},
{
"cell_type": "code",
"source": [
"def evaluate_rolling(result, series, indices, horizon, test_start_idx):\n",
" preds = result['preds']\n",
" truths = result['truths']\n",
" idxs = result['indices']\n",
" # collect only forecasts whose first predicted index >= test_start_idx\n",
" rows = []\n",
" for i, idx in enumerate(idxs):\n",
" if idx >= test_start_idx:\n",
" y_true = truths[i]\n",
" y_pred = preds[i]\n",
" rows.append((idx, y_true, y_pred))\n",
" if not rows:\n",
" raise ValueError(\"No test windows selected, adjust window/horizon/step or check splits.\")\n",
" # flatten and compute metrics for each horizon-step aggregated\n",
" y_true_flat = np.concatenate([r[1] for r in rows])\n",
" y_pred_flat = np.concatenate([r[2] for r in rows])\n",
" return {'RMSE': rmse(y_true_flat, y_pred_flat), 'MAPE': mape(y_true_flat, y_pred_flat)}\n",
"\n",
"arima_metrics = evaluate_rolling(res_arima, full_series, res_arima['indices'], horizon, test_start_idx)\n",
"lstm_metrics = evaluate_rolling(res_lstm, full_series, res_lstm['indices'], horizon, test_start_idx)\n",
"print(\"ARIMA:\", arima_metrics)\n",
"print(\"LSTM:\", lstm_metrics)"
],
"metadata": {
"id": "ZdMKfkRj1c8h",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "201753aa-a724-49fe-a8ea-41a360e3fcbb"
},
"execution_count": 14,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"ARIMA: {'RMSE': 10.558241430720086, 'MAPE': 0.024146145567999763}\n",
"LSTM: {'RMSE': 244.66744217564593, 'MAPE': 143.10247144923565}\n"
]
}
]
},
{
"cell_type": "code",
"source": [
"import pandas as pd\n",
"metrics_df = pd.DataFrame([{\n",
" 'Model': 'ARIMA(5,1,0)',\n",
" 'RMSE': arima_metrics['RMSE'],\n",
" 'MAPE': arima_metrics['MAPE']\n",
"},{\n",
" 'Model': 'LSTM (seq=30, epochs=10)',\n",
" 'RMSE': lstm_metrics['RMSE'],\n",
" 'MAPE': lstm_metrics['MAPE']\n",
"}])\n",
"metrics_df"
],
"metadata": {
"id": "_hZMtNu-1s4p",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 125
},
"outputId": "0049d54a-7500-4ac2-ecad-38f4354a1d10"
},
"execution_count": 15,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" Model RMSE MAPE\n",
"0 ARIMA(5,1,0) 10.558241 0.024146\n",
"1 LSTM (seq=30, epochs=10) 244.667442 143.102471"
],
"text/html": [
"\n",
" \n",
"
\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" Model | \n",
" RMSE | \n",
" MAPE | \n",
"
\n",
" \n",
" \n",
" \n",
" | 0 | \n",
" ARIMA(5,1,0) | \n",
" 10.558241 | \n",
" 0.024146 | \n",
"
\n",
" \n",
" | 1 | \n",
" LSTM (seq=30, epochs=10) | \n",
" 244.667442 | \n",
" 143.102471 | \n",
"
\n",
" \n",
"
\n",
"
\n",
"
\n",
"
\n"
],
"application/vnd.google.colaboratory.intrinsic+json": {
"type": "dataframe",
"variable_name": "metrics_df",
"summary": "{\n \"name\": \"metrics_df\",\n \"rows\": 2,\n \"fields\": [\n {\n \"column\": \"Model\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 2,\n \"samples\": [\n \"LSTM (seq=30, epochs=10)\",\n \"ARIMA(5,1,0)\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"RMSE\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 165.5402033848998,\n \"min\": 10.558241430720086,\n \"max\": 244.66744217564593,\n \"num_unique_values\": 2,\n \"samples\": [\n 244.66744217564593,\n 10.558241430720086\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"MAPE\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 101.17165406303819,\n \"min\": 0.024146145567999763,\n \"max\": 143.10247144923565,\n \"num_unique_values\": 2,\n \"samples\": [\n 143.10247144923565,\n 0.024146145567999763\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n }\n ]\n}"
}
},
"metadata": {},
"execution_count": 15
}
]
},
{
"cell_type": "code",
"source": [
"i = -1\n",
"# find a test window index (last one)\n",
"for j, idx in enumerate(res_arima['indices']):\n",
" if idx >= test_start_idx:\n",
" i = j\n",
"# choose that i\n",
"plt.figure(figsize=(10,4))\n",
"truth = res_arima['truths'][i]\n",
"pred_a = res_arima['preds'][i]\n",
"pred_l = res_lstm['preds'][i]\n",
"x = np.arange(len(truth))\n",
"plt.plot(x, truth, label='Truth')\n",
"plt.plot(x, pred_a, label='ARIMA')\n",
"plt.plot(x, pred_l, label='LSTM')\n",
"plt.legend()\n",
"plt.title(f'Forecast window starting at index {res_arima[\"indices\"][i]} ({df.Date.iloc[res_arima[\"indices\"][i]].date()})')\n",
"plt.show()"
],
"metadata": {
"id": "vw4nFfz31wJm",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 346
},
"outputId": "3aa5d38f-d3d4-4e1c-cb0a-4c40427dd2ff"
},
"execution_count": 16,
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
""
],
"image/png": "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vbts2fDhwwUA8fXXX8vqD0B89913QgjnIaV///6iU6dO4vDhw2LAgAHCx8dHREVFiX/84x8Ox01NTRUjR44UBoNBhIaGihkzZoj//e9/ToPP559/Lp3jZs2aifHjx4tz585J67/++msBQPz222/SsrVr1woA4vbbb5ftq0OHDmLcuHEuz4cQZRdgd9xxhwgPDxc6nU40b95c3HnnnSInJ0cIIRzOLwDpQv/06dNi6tSpol27dkKv14vg4GAxZswYhxBjf49u27ZNTJ06VYSGhorAwEDp/VbxYd++RYsWslBh389PP/0kZs6cKUJCQoTBYBCjRo0SmZmZsmNarVbx4osvisjISOHj4yMGDBggDh8+7LBPVxYsWCASEhJEcHCw0Ov1okePHrILvKrOjTPOQkpycrLw9fUV586dEyNHjhS+vr4iJCREPPHEE8Jisci2z87OFsnJySIgIEAYjUYxceJEceDAAafB58iRI2L06NEiKChI6HQ60bNnT9l7PCMjQ4SEhIj+/fsLm80mLT927JgwGAxVvm9cGT58uAgPD6+0THFxsQgMDBQDBgxwa5933HGHCA4OrrJcx44dRatWrdza58SJE0XLli3dKiuEEMHBweKOO+6Qnufm5gq1Wi2eeuopWTmz2Sz8/PzEAw88UOU+e/ToIXr06CFbFhYWJsaOHetQtl27dmLgwIFV7vOpp54SKpVKFsaEEGLevHkCgPR5XVhYKACIadOmycrl5+cLpVIpZs2aVeWxxo4dK8LDwx2C4uTJk4XBYBDFxcUut7UHtDlz5jisy8nJEQqFQrz11ltV1oGosWNXN6I6kpubi0uXLsmWhYSEAAA2b96MYcOGoXXr1pgzZw6Kiorw7rvv4sYbb8T+/fvRsmVL2Xb2bh7z5s2DEAIA8Oqrr+L555/HuHHj8OCDD+LixYt499130a9fPxw4cEDqprRp0yYMHz4ckZGRmD59OiIiInDkyBGsX78e06dPl8qcPHkS9913HyIiInD48GH861//wuHDh/Hzzz9DoVAAAKZMmYK1a9fikUceQXx8PC5fvoyffvoJR44cQY8ePfDss88iNzcX586dw9tvvw0A8PPzc3mO+vbti6+//homkwkBAQEQQmDnzp1QKpX48ccfpa4VP/74I5RKJW688cZKz3l2djaGDh2KO+64A+PGjcPatWsxa9YsdOnSBcOGDQMAFBUVYeDAgTh79iwee+wxREVFYcWKFfjhhx8c9rd8+XLcd999+Nvf/ob58+cjIyMD77zzDnbu3Cmd45tuugkKhQI7duxA165dZfX96aefpH1dvHgRR48exSOPPOKy/iUlJUhMTITZbMajjz6KiIgInD9/HuvXr0dOTg6MRiNWrFiBBx98EL169ZK6L7Vp0wZA2b0Lu3btwl133YXo6GicPn0aixcvxoABA/DHH3/AYDDIjvfwww8jNDQUL7zwAgoKCjBs2DD89ddf+PTTT/H2229L79fQ0NBKz/ujjz6KoKAgvPjiizh9+jQWLlyIRx55BJ999plUZvbs2Xj99dcxYsQIJCYm4rfffkNiYiKKi4sr3bfdO++8g9tuuw3jx49HSUkJVq9ejbFjx2L9+vVISkoCgErPjSesVisSExPRu3dvvPHGG9i8eTPefPNNtGnTBlOnTgUACCEwcuRI/PTTT5gyZQo6duyIdevWITk52WF/hw8fxo033ojmzZvjmWeega+vLz7//HOMGjUKX3zxBW6//XaEhYVh8eLFGDt2LN5991089thjsNlsmDRpEvz9/fH++++7VfeCggIUFRUhNzcX33zzDTZs2IA777yz0m2+++475OTkYPz48W4dIz09XXpvuHLgwAEcOXIEzz77rFv73LVrF3r06OFW2fz8fOTn58vqcPDgQVgsFlx//fWyslqtFt26dcOBAwcq3acQAhkZGejUqZO07Pz588jMzHTYJwD06tUL3333XZV1PXDgANq1a4eAgACH7YGy7nkxMTHSvT/Lly9HQkIC+vbti5ycHLz88ssICgqSdVWs7Fg9evRw6I7aq1cv/Otf/8Jff/2FLl26ON3WPqCEs/eA0WhEmzZtsHPnTsycObPKehA1ag2bu4i8j/1bcGcPu27duomwsDBx+fJladlvv/0mlEqlmDhxorTM/g18xW4Kp0+fFiqVSrz66quy5QcPHhRqtVpabrFYRKtWrUSLFi1Edna2rGz5b5ULCwsdXsenn34qAIgdO3ZIy4xGo8M3khV50tVt7969spac33//XQAQY8eOFb1795bK3XbbbbKWIVctPgDEf/7zH2mZ2WwWERERYvTo0dKyhQsXCgDi888/l5YVFBSIuLg42T5LSkpEWFiY6Ny5sygqKpLKrl+/XgAQL7zwgrSsU6dOsm/ke/To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ZKHHvo+QkBD06tULH330EYQQLvdhNpthMplkDyIiIiIiInd53OKzevVq7N+/H3v37q2y7KVLl/Dyyy9j8uTJsuVz587FLbfcAoPBgO+//x4PP/ww8vPz8dhjjzndz/z58/HSSy95WlUiIiIiIiIAgEJU1tRSQWpqKq6//nps2rRJurdnwIAB6NatGxYuXCgrazKZMHjwYAQHB+Obb76BRqNxud8XXngBy5YtQ2pqqtP1ZrMZZrNZtu+YmBipNYmIiIiIiK5NJpMJRqOxymzgUfD56quvcPvtt0OlUknLrFYrFAoFlEolzGYzVCoV8vLykJiYCIPBgPXr10Ov11e632+//RbDhw9HcXExdDpdrb04IiIiIiLybu5mA4+6ug0cOBAHDx6ULbvvvvvQoUMHzJo1CyqVCiaTCYmJidDpdPjmm2+qDD0AkJKSgqCgILdCDxERERERkac8Cj7+/v7o3LmzbJmvry+aNWuGzp07w2QyYciQISgsLMQnn3wiG4ggNDQUKpUK//3vf5GRkYE+ffpAr9dj06ZNmDdvHp588snae1VERERERETlVHseH2f279+PPXv2AADi4uJk606dOoWWLVtCo9Fg0aJFmDlzJoQQiIuLw1tvvYWHHnqoNqtCREREREQk8egen8aC9/gQERERERHgfjao1jw+RERERERETQmDDxEREREReT0GHyIiIiIi8noMPkRERERE5PUYfIiIiIiIyOsx+BARERERkddj8CEiIiIiIq/H4ENERERERF6PwYeIiIiIiLwegw8REREREXk9Bh8iIiIiIvJ6DD5EREREROT1GHyIiIiIiMjrMfgQEREREZHXY/AhIiIiIiKvx+BDRERERERej8GHiIiIiIi8HoMPERERERF5PQYfIiIiIiLyegw+RERERETk9Rh8iIiIiIjI6zH4EBERERGR12PwISIiIiIir8fgQ0REREREXo/Bh4iIiIiIvB6DDxEREREReT0GHyIiIiIi8noMPkRERERE5PUYfIiIiIiIyOupG7oCRERERERNjdVqRWlpaUNX45qg0WigUqlqvB8GHyIiIiIiNwkhkJ6ejpycnIauyjUlMDAQERERUCgU1d5HjYLPa6+9htmzZ2P69OlYuHAhAKC4uBhPPPEEVq9eDbPZjMTERLz//vsIDw+Xtjt79iymTp2KrVu3ws/PD8nJyZg/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q1FQUODRa6kOdZ0fgYiIiIjIW5UWAvOiGubY/3cB0Pq6XXzp0qW49957AQBDhw5Fbm4utm/fLrsH54YbboBSqURhYSGEEOjZsycGDhxY5b6HDx+OKVOmYMeOHejZsyc+//xz/PTTT/joo4+c1uOuu+6CSqVC586d0bp1a6xZswaTJk1y+7VUB1t8iIiIiIi83J9//olffvkFd999NwBArVbjzjvvdOhm9tlnn+HAgQP44osvEBcXh+XLl0Oj0VS5f41Gg3vvvRfLli3DmjVr0K5dO3Tt2tWhXE5ODr788kspgAHAvffeWy/d3djiQ0RERERUXRpDWctLQx3bTUuXLoXFYkFU1NXWKSEEdDod3nvvPWlZTEwM2rZti7Zt28JiseD222/HoUOHoNPpqjzG/fffj969e+PQoUO4//77nZZZtWoViouL0bt3b1k9bDYb/vrrL7Rr187t1+QptvgQEREREVWXQlHW3awhHgqFW1W0WCz4z3/+gzfffBMpKSnS47fffkNUVBQ+/fRTp9uNGTMGarUa77//vlvH6dSpEzp16oRDhw7hnnvucVpm6dKleOKJJxzq0bdvX6fd4moTgw8RERERkRdbv349srOz8cADD6Bz586yx+jRo112M1MoFHjsscfw2muvobCw0K1j/fDDD0hLS0NgYKDDupSUFOzfvx8PPvigQz3uvvtufPzxx7BYLDV5qZVi8CEiIiIi8mJLly7FoEGDYDQaHdaNHj0av/76K0wmk9Ntk5OTUVpaKusOVxlfX1+nocdej/j4eHTo0MFh3e23347MzEx89913bh2nOhTC1Rh2jZjJZILRaERubi4CAgIaujpEREREdA0oLi7GqVOn0KpVK+j1+oauzjWlsnPvbjZgiw8REREREXk9Bh8iIiIiIvJ6DD5EREREROT1GHyIiIiIiMjrMfgQEREREZHXY/AhIiIiIiKv51HwWbx4Mbp27YqAgAAEBAQgISEBGzZsAACcPn0aCoXC6WPNmjXSPpytX716de2+KiIiIiIionLUnhSOjo7Ga6+9hrZt20IIgY8//hgjR47EgQMH0KFDB6SlpcnK/+tf/8KCBQswbNgw2fJly5Zh6NCh0nNXkxwRERERERHVBo+Cz4gRI2TPX331VSxevBg///wzOnXqhIiICNn6devWYdy4cfDz85MtDwwMdChLRERERERUV6p9j4/VasXq1atRUFCAhIQEh/X79u1DSkoKHnjgAYd106ZNQ0hICHr16oWPPvoIQohKj2U2m2EymWQPIiIiIiIid3kcfA4ePAg/Pz/odDpMmTIF69atQ3x8vEO5pUuXomPHjrjhhhtky+fOnYvPP/8cmzZtwujRo/Hwww/j3XffrfSY8+fPh9FolB4xMTGeVpuIiIiI6Jo1adIkjBo1yum63377DbfddhvCwsKg1+vRsmVL3HnnncjMzMScOXNc3sdvf9j3r1AoMGXKFIf9T5s2DQqFApMmTarDV1g1j4NP+/btkZKSgj179mDq1KlITk7GH3/8IStTVFSEVatWOW3tef7553HjjTeie/fumDVrFp5++mksWLCg0mPOnj0bubm50iM1NdXTahMRERERUQUXL17EwIEDERwcjI0bN+LIkSNYtmwZoqKiUFBQgCeffBJpaWnSIzo6GnPnzpUts4uJicHq1atRVFQkLSsuLsaqVasQGxvbEC9PxqN7fABAq9UiLi4OANCzZ0/s3bsX77zzDpYsWSKVWbt2LQoLCzFx4sQq99e7d2+8/PLLMJvN0Ol0TsvodDqX64iIiIiIqHp27tyJ3NxcfPjhh1Cry6JBq1atcPPNN0tlyt+vr1Kp4O/v7/R+/R49euDEiRP48ssvMX78eADAl19+idjYWLRq1aqOX0nVajyPj81mg9lsli1bunQpbrvtNoSGhla5fUpKCoKCghhsiIiIiKjJEUKgsLSwQR5V3SfvjoiICFgsFqxbt65W9nf//fdj2bJl0vOPPvoI9913X433Wxs8avGZPXs2hg0bhtjYWOTl5WHVqlXYtm0bNm7cKJU5fvw4duzYge+++85h+//+97/IyMhAnz59oNfrsWnTJsybNw9PPvlkzV8JEREREVE9K7IUofeq3g1y7D337IFBY6jRPvr06YP/+7//wz333IMpU6agV69euOWWWzBx4kSEh4d7vL97770Xs2fPxpkzZwCUtSitXr0a27Ztq1E9a4NHwSczMxMTJ05EWloajEYjunbtio0bN2Lw4MFSmY8++gjR0dEYMmSIw/YajQaLFi3CzJkzIYRAXFwc3nrrLTz00EM1fyVEREREROSxV199FY8//jh++OEH7NmzBx988AHmzZuHHTt2oEuXLh7tKzQ0FElJSVi+fDmEEEhKSkJISEgd1dwzHgWfpUuXVllm3rx5mDdvntN1Q4cOlU1cSkRERETUlPmofbDnnj0Nduza0qxZM4wdOxZjx47FvHnz0L17d7zxxhv4+OOPPd7X/fffj0ceeQQAsGjRolqrY015PLgBERERERGVUSgUNe5u1thotVq0adMGBQUF1dp+6NChKCkpgUKhQGJiYi3XrvoYfIiIiIiIrgG5ublISUmRLTt48CA2btyIu+66C+3atYMQAv/973/x3XffyQYp8IRKpcKRI0ek3xsLBh8iIiIiomvAtm3b0L17d9mym2++GXFxcXjiiSeQmpoKnU6Htm3b4sMPP8SECROqfayAgICaVrfWKURtjFtXz0wmE4xGI3JzcxvlSSUiIiIi71NcXIxTp06hVatW0Ov1DV2da0pl597dbFDjeXyIiIiIiIgaOwYfIiIiIiLyegw+RERERETk9Rh8iIiIiIjI6zH4EBERERGR12PwISIiIiLyQBMcFLnJq41zzuBDREREROQGjUYDACgsLGzgmlx77Ofc/jeoDk5gSkRERETkBpVKhcDAQGRmZgIADAYDFApFA9fKuwkhUFhYiMzMTAQGBkKlUlV7Xww+RERERERuioiIAAAp/FD9CAwMlM59dTH4EBERERG5SaFQIDIyEmFhYSgtLW3o6lwTNBpNjVp67Bh8iIiIiIg8pFKpauVinOoPBzcgIiIiIiKvx+BDRERERERej8GHiIiIiIi8HoMPERERERF5PQYfIiIiIiLyegw+RERERETk9Rh8iIiIiIjI6zH4EBERERGR12PwISIiIiIir8fgQ0REREREXo/Bh4iIiIiIvB6DDxEREREReT0GHyIiIiIi8noMPkRERERE5PUYfIiIiIiIyOsx+BARERERkddj8CEiIiIiIq/nUfBZvHgxunbtioCAAAQEBCAhIQEbNmyQ1g8YMAAKhUL2mDJlimwfZ8+eRVJSEgwGA8LCwvDUU0/BYrHUzqshIiIiIiJyQu1J4ejoaLz22mto27YthBD4+OOPMXLkSBw4cACdOnUCADz00EOYO3eutI3BYJB+t1qtSEpKQkREBHbt2oW0tDRMnDgRGo0G8+bNq6WXREREREREJKcQQoia7CA4OBgLFizAAw88gAEDBqBbt25YuHCh07IbNmzA8OHDceHCBYSHhwMAPvjgA8yaNQsXL16EVqt165gmkwlGoxG5ubkICAioSfWJiIiIiKgJczcbVPseH6vVitWrV6OgoAAJCQnS8pUrVyIkJASdO3fG7NmzUVhYKK3bvXs3unTpIoUeAEhMTITJZMLhw4ddHstsNsNkMskeRERERERE7vKoqxsAHDx4EAkJCSguLoafnx/WrVuH+Ph4AMA999yDFi1aICoqCr///jtmzZqFP//8E19++SUAID09XRZ6AEjP09PTXR5z/vz5eOmllzytKhEREREREYBqBJ/27dsjJSUFubm5WLt2LZKTk7F9+3bEx8dj8uTJUrkuXbogMjISAwcOxIkTJ9CmTZtqV3L27Nl4/PHHpecmkwkxMTHV3h8REREREV1bPO7qptVqERcXh549e2L+/Pm47rrr8M477zgt27t3bwDA8ePHAQARERHIyMiQlbE/j4iIcHlMnU4njSRnfxAREREREbmrxvP42Gw2mM1mp+tSUlIAAJGRkQCAhIQEHDx4EJmZmVKZTZs2ISAgQOouR0REREREVNs86uo2e/ZsDBs2DLGxscjLy8OqVauwbds2bNy4ESdOnMCqVatw6623olmzZvj9998xc+ZM9OvXD127dgUADBkyBPHx8ZgwYQJef/11pKen47nnnsO0adOg0+nq5AUSERERERF5FHwyMzMxceJEpKWlwWg0omvXrti4cSMGDx6M1NRUbN68GQsXLkRBQQFiYmIwevRoPPfcc9L2KpUK69evx9SpU5GQkABfX18kJyfL5v0hIiIiIiKqbTWex6chcB4fIiIiIiIC6mEeHyIiIiIioqaCwYeIiIiIiLwegw8REREREXk9Bh8iIiIiIvJ6DD5EREREROT1GHyIiIiIiMjrMfgQEREREZHXY/AhIiIiIiKvx+BDRERERERej8GHiIiIiIi8HoMPERERERF5PQYfIiIiIiLyegw+RERERETk9Rh8iIiIiIjI6zH4EBERERGR12PwISIiIiIir8fgQ0REREREXo/Bh4iIiIiIvB6DDxEREREReT0GHyIiIiIi8noMPkRERERE5PUYfIiIiIiIyOsx+BARERERkddj8CEiIiIiIq/H4ENERERERF6PwYeIiIiIiLwegw8REREREXk9Bh8iIiIiIvJ6DD5EREREROT1GHyIiIiIiMjrMfgQEREREZHX8yj4LF68GF27dkVAQAACAgKQkJCADRs2AACysrLw6KOPon379vDx8UFs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BQCxfft2l2X4GVx97pxffgbXTFBQkPjwww+druN7t+YqO79873ouLy9PtG3bVmzatEn0799fTJ8+3WXZpvL+ZYtPJUpKSrBv3z4MGjRIWqZUKjFo0CDs3r3b6Ta7d++WlQeAxMREl+WvZdU5vwCQn5+PFi1aICYmpspvd8gzfP/Wj27duiEyMhKDBw/Gzp07G7o6TUZubi4AIDg42GUZvoerz53zC/AzuDqsVitWr16NgoICJCQkOC3D9271uXN+Ab53PTVt2jQkJSU5vC+daSrvXwafSly6dAlWqxXh4eGy5eHh4S775Kenp3tU/lpWnfPbvn17fPTRR/j666/xySefwGaz4YYbbsC5c+fqo8pez9X712QyoaioqIFq5T0iIyPxwQcf4IsvvsAXX3yBmJgYDBgwAPv372/oqjV6NpsNM2bMwI033ojOnTu7LMfP4Opx9/zyM9gzBw8ehJ+fH3Q6HaZMmYJ169YhPj7eaVm+dz3nyfnle9czq1evxv79+zF//ny3yjeV96+6oStA5ImEhATZtzk33HADOnbsiCVLluDll19uwJoRVa19+/Zo37699PyGG27AiRMn8Pbbb2PFihUNWLPGb9q0aTh06BB++umnhq6KV3L3/PIz2DPt27dHSkoKcnNzsXbtWiQnJ2P79u0uL87JM56cX7533Zeamorp06dj06ZNXjcABINPJUJCQqBSqZCRkSFbnpGRgYiICKfbREREeFT+Wlad81uRRqNB9+7dcfz48bqo4jXH1fs3ICAAPj4+DVQr79arVy9ezFfhkUcewfr167Fjxw5ER0dXWpafwZ7z5PxWxM/gymm1WsTFxQEAevbsib179+Kdd97BkiVLHMryves5T85vRXzvurZv3z5kZmaiR48e0jKr1YodO3bgvffeg9lshkqlkm3TVN6/7OpWCa1Wi549e2LLli3SMpvNhi1btrjsQ5qQkCArDwCbNm2qtM/ptao657ciq9WKgwcPIjIysq6qeU3h+7f+paSk8P3rghACjzzyCNatW4cffvgBrVq1qnIbvofdV53zWxE/gz1js9lgNpudruN7t+YqO78V8b3r2sCBA3Hw4EGkpKRIj+uvvx7jx49HSkqKQ+gBmtD7t6FHV2jsVq9eLXQ6nVi+fLn4448/xOTJk0VgYKBIT08XQggxYcIE8cwzz0jld+7cKdRqtXjjjTfEkSNHxIsvvig0Go04ePBgQ72ERs3T8/vSSy+JjRs3ihMnToh9+/aJu+66S+j1enH48OGGegmNWl5enjhw4IA4cOCAACDeeustceDAAXHmzBkhhBDPPPOMmDBhglT+5MmTwmAwiKeeekocOXJELFq0SKhUKvG///2voV5Co+bp+X377bfFV199JY4dOyYOHjwopk+fLpRKpdi8eXNDvYRGberUqcJoNIpt27aJtLQ06VFYWCiV4Wdw9VXn/PIz2H3PPPOM2L59uzh16pT4/fffxTPPPCMUCoX4/vvvhRB879aUp+eX792aqTiqW1N9/zL4uOHdd98VsbGxQqvVil69eomff/5ZWte/f3+RnJwsK//555+Ldu3aCa1WKzp16iS+/fbbeq5x0+LJ+Z0xY4ZUNjw8XNx6661i//79DVDrpsE+fHLFh/2cJicni/79+zts061bN6HVakXr1q3FsmXL6r3eTYWn5/cf//iHaNOmjdDr9SI4OFgMGDBA/PDDDw1T+SbA2bkFIHtP8jO4+qpzfvkZ7L77779ftGjRQmi1WhEaGioGDhwoXZQLwfduTXl6fvnerZmKwaepvn8VQghRf+1LRERERERE9Y/3+BARERERkddj8CEiIiIiIq/H4ENERERERF6PwYeIiIiIiLwegw8REREREXk9Bh8iIiIiIvJ6DD5EREREROT1GHyIiIiIiMjrMfgQEREREZHXY/AhIiIiIiKvx+BDRERERERej8GHiIiIiIi83v8DLJxzV3LWn8UAAAAASUVORK5CYII=\n"
},
"metadata": {}
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "3bb27c2a"
},
"source": [
"# DataSynthis ML JobTask\n",
"\n",
"This repository contains the code and artifacts for the DataSynthis ML JobTask.\n",
"\n",
"## Models\n",
"\n",
"- ARIMA(5,1,0)\n",
"- LSTM (seq=30, epochs=10)\n",
"\n",
"## Artifacts\n",
"\n",
"- `scaler.joblib`: MinMaxScaler fitted on the training data."
]
}
]
}