added chatgpt bilstm notebook to seuqneuutially predict data more accurately

This commit is contained in:
2026-07-22 23:00:06 -04:00
parent fb3173e4ab
commit 300871633f

906
bilstm_sequential.ipynb Normal file
View File

@@ -0,0 +1,906 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "21ce2b41",
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"import numpy as np\n",
"\n",
"from sklearn.model_selection import train_test_split\n",
"from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score\n",
"\n",
"import tensorflow as tf\n",
"from tensorflow.keras.models import Sequential\n",
"from tensorflow.keras.layers import (\n",
" LSTM,\n",
" Bidirectional,\n",
" Dense,\n",
" Dropout,\n",
" Masking\n",
")\n",
"\n",
"from tensorflow.keras.callbacks import (\n",
" EarlyStopping,\n",
" ReduceLROnPlateau\n",
")\n",
"\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "7b5e2a73",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>match_id</th>\n",
" <th>delivery_number</th>\n",
" <th>legal_ball</th>\n",
" <th>over_ball</th>\n",
" <th>score</th>\n",
" <th>wickets</th>\n",
" <th>target_score</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>1001349</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0.1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>168</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>1001349</td>\n",
" <td>2</td>\n",
" <td>2</td>\n",
" <td>0.2</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>168</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>1001349</td>\n",
" <td>3</td>\n",
" <td>3</td>\n",
" <td>0.3</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>168</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>1001349</td>\n",
" <td>4</td>\n",
" <td>4</td>\n",
" <td>0.4</td>\n",
" <td>3</td>\n",
" <td>0</td>\n",
" <td>168</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>1001349</td>\n",
" <td>5</td>\n",
" <td>5</td>\n",
" <td>0.5</td>\n",
" <td>3</td>\n",
" <td>0</td>\n",
" <td>168</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" match_id delivery_number legal_ball over_ball score wickets \\\n",
"0 1001349 1 1 0.1 0 0 \n",
"1 1001349 2 2 0.2 0 0 \n",
"2 1001349 3 3 0.3 1 0 \n",
"3 1001349 4 4 0.4 3 0 \n",
"4 1001349 5 5 0.5 3 0 \n",
"\n",
" target_score \n",
"0 168 \n",
"1 168 \n",
"2 168 \n",
"3 168 \n",
"4 168 "
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df = pd.read_csv(\n",
" \"data/run_prediction_dataset_raw.csv\"\n",
")\n",
"\n",
"df.head()"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "4b258bec",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>match_id</th>\n",
" <th>delivery_number</th>\n",
" <th>legal_ball</th>\n",
" <th>over_ball</th>\n",
" <th>score</th>\n",
" <th>wickets</th>\n",
" <th>target_score</th>\n",
" <th>runs_this_ball</th>\n",
" <th>previous_score</th>\n",
" <th>last_6_runs</th>\n",
" <th>last_12_runs</th>\n",
" <th>boundaries</th>\n",
" <th>last_12_boundaries</th>\n",
" <th>dots</th>\n",
" <th>last_12_dots</th>\n",
" <th>balls_remaining</th>\n",
" <th>run_rate</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>514915</th>\n",
" <td>211028</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0.1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>179</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0</td>\n",
" <td>0.0</td>\n",
" <td>1</td>\n",
" <td>0.0</td>\n",
" <td>119</td>\n",
" <td>0.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>514916</th>\n",
" <td>211028</td>\n",
" <td>2</td>\n",
" <td>2</td>\n",
" <td>0.2</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>179</td>\n",
" <td>1.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0</td>\n",
" <td>0.0</td>\n",
" <td>0</td>\n",
" <td>0.0</td>\n",
" <td>118</td>\n",
" <td>3.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>514917</th>\n",
" <td>211028</td>\n",
" <td>3</td>\n",
" <td>3</td>\n",
" <td>0.3</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>179</td>\n",
" <td>0.0</td>\n",
" <td>1.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0</td>\n",
" <td>0.0</td>\n",
" <td>1</td>\n",
" <td>0.0</td>\n",
" <td>117</td>\n",
" <td>2.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>514918</th>\n",
" <td>211028</td>\n",
" <td>4</td>\n",
" <td>4</td>\n",
" <td>0.4</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>179</td>\n",
" <td>0.0</td>\n",
" <td>1.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0</td>\n",
" <td>0.0</td>\n",
" <td>1</td>\n",
" <td>0.0</td>\n",
" <td>116</td>\n",
" <td>1.5</td>\n",
" </tr>\n",
" <tr>\n",
" <th>514919</th>\n",
" <td>211028</td>\n",
" <td>5</td>\n",
" <td>5</td>\n",
" <td>0.5</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>179</td>\n",
" <td>0.0</td>\n",
" <td>1.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0</td>\n",
" <td>0.0</td>\n",
" <td>1</td>\n",
" <td>0.0</td>\n",
" <td>115</td>\n",
" <td>1.2</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" match_id delivery_number legal_ball over_ball score wickets \\\n",
"514915 211028 1 1 0.1 0 0 \n",
"514916 211028 2 2 0.2 1 0 \n",
"514917 211028 3 3 0.3 1 0 \n",
"514918 211028 4 4 0.4 1 0 \n",
"514919 211028 5 5 0.5 1 0 \n",
"\n",
" target_score runs_this_ball previous_score last_6_runs \\\n",
"514915 179 0.0 0.0 0.0 \n",
"514916 179 1.0 0.0 0.0 \n",
"514917 179 0.0 1.0 0.0 \n",
"514918 179 0.0 1.0 0.0 \n",
"514919 179 0.0 1.0 0.0 \n",
"\n",
" last_12_runs boundaries last_12_boundaries dots last_12_dots \\\n",
"514915 0.0 0 0.0 1 0.0 \n",
"514916 0.0 0 0.0 0 0.0 \n",
"514917 0.0 0 0.0 1 0.0 \n",
"514918 0.0 0 0.0 1 0.0 \n",
"514919 0.0 0 0.0 1 0.0 \n",
"\n",
" balls_remaining run_rate \n",
"514915 119 0.0 \n",
"514916 118 3.0 \n",
"514917 117 2.0 \n",
"514918 116 1.5 \n",
"514919 115 1.2 "
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df = df.sort_values(\n",
" [\n",
" \"match_id\",\n",
" \"delivery_number\"\n",
" ]\n",
")\n",
"\n",
"\n",
"# runs scored this ball\n",
"df[\"runs_this_ball\"] = (\n",
" df.groupby(\"match_id\")[\"score\"]\n",
" .diff()\n",
" .fillna(\n",
" df[\"score\"]\n",
" )\n",
")\n",
"\n",
"\n",
"# previous score\n",
"df[\"previous_score\"] = (\n",
" df[\"score\"]\n",
" -\n",
" df[\"runs_this_ball\"]\n",
")\n",
"\n",
"\n",
"# rolling scoring form\n",
"\n",
"df[\"last_6_runs\"] = (\n",
" df.groupby(\"match_id\")\n",
" [\"runs_this_ball\"]\n",
" .rolling(6)\n",
" .sum()\n",
" .reset_index(level=0,drop=True)\n",
" .fillna(0)\n",
")\n",
"\n",
"\n",
"df[\"last_12_runs\"] = (\n",
" df.groupby(\"match_id\")\n",
" [\"runs_this_ball\"]\n",
" .rolling(12)\n",
" .sum()\n",
" .reset_index(level=0,drop=True)\n",
" .fillna(0)\n",
")\n",
"\n",
"\n",
"df[\"boundaries\"] = (\n",
" df[\"runs_this_ball\"] >= 4\n",
").astype(int)\n",
"\n",
"\n",
"df[\"last_12_boundaries\"] = (\n",
" df.groupby(\"match_id\")\n",
" [\"boundaries\"]\n",
" .rolling(12)\n",
" .sum()\n",
" .reset_index(level=0,drop=True)\n",
" .fillna(0)\n",
")\n",
"\n",
"\n",
"df[\"dots\"] = (\n",
" df[\"runs_this_ball\"] == 0\n",
").astype(int)\n",
"\n",
"\n",
"df[\"last_12_dots\"] = (\n",
" df.groupby(\"match_id\")\n",
" [\"dots\"]\n",
" .rolling(12)\n",
" .sum()\n",
" .reset_index(level=0,drop=True)\n",
" .fillna(0)\n",
")\n",
"\n",
"# Existing features above...\n",
"\n",
"\n",
"# New features\n",
"df[\"balls_remaining\"] = 120 - df[\"legal_ball\"]\n",
"\n",
"df[\"run_rate\"] = (\n",
" df[\"score\"] / (df[\"legal_ball\"] / 6)\n",
").replace(\n",
" [float(\"inf\"), -float(\"inf\")],\n",
" 0\n",
").fillna(0)\n",
"\n",
"df.head()"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "1fc0e0b9",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(440081, 17)\n"
]
}
],
"source": [
"df = df[\n",
" df[\"legal_ball\"] >= 30\n",
"]\n",
"\n",
"\n",
"print(\n",
" df.shape\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "370d0cfb",
"metadata": {},
"outputs": [],
"source": [
"FEATURES = [\n",
" \"score\",\n",
" \"wickets\",\n",
" \"legal_ball\",\n",
" \"runs_this_ball\",\n",
" \"last_6_runs\",\n",
" \"last_12_runs\",\n",
" \"last_12_boundaries\",\n",
" \"last_12_dots\",\n",
" \"run_rate\",\n",
" \"balls_remaining\"\n",
"]\n",
"\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "d43f7fc0",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Training matches: 3686\n",
"Testing matches : 922\n",
"Training rows: 352215\n",
"Testing rows : 87866\n"
]
}
],
"source": [
"from sklearn.model_selection import train_test_split\n",
"\n",
"\n",
"# ==========================================\n",
"# Split by MATCH, not by sequence\n",
"# ==========================================\n",
"\n",
"all_matches = df[\"match_id\"].unique()\n",
"\n",
"\n",
"train_matches, test_matches = train_test_split(\n",
" all_matches,\n",
" test_size=0.2,\n",
" random_state=42\n",
")\n",
"\n",
"\n",
"train_df = df[\n",
" df[\"match_id\"].isin(train_matches)\n",
"].copy()\n",
"\n",
"\n",
"test_df = df[\n",
" df[\"match_id\"].isin(test_matches)\n",
"].copy()\n",
"\n",
"\n",
"print(\"Training matches:\", len(train_matches))\n",
"print(\"Testing matches :\", len(test_matches))\n",
"\n",
"print(\"Training rows:\", len(train_df))\n",
"print(\"Testing rows :\", len(test_df))"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "55e46374",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0\n"
]
}
],
"source": [
"print(\n",
" len(\n",
" set(train_matches)\n",
" &\n",
" set(test_matches)\n",
" )\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "66f4ae4e",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Train sequences: 241635\n",
"Test sequences: 60206\n"
]
}
],
"source": [
"def create_sequences(data):\n",
"\n",
" X = []\n",
" y = []\n",
"\n",
" for match_id, innings in data.groupby(\"match_id\"):\n",
"\n",
" innings = innings.sort_values(\n",
" \"legal_ball\"\n",
" )\n",
"\n",
" sequence = innings[FEATURES].values\n",
"\n",
" target = innings[\"target_score\"].iloc[0]\n",
"\n",
"\n",
" for i in range(30, len(sequence)):\n",
"\n",
" X.append(\n",
" sequence[:i+1]\n",
" )\n",
"\n",
" y.append(\n",
" target\n",
" )\n",
"\n",
" return X, y\n",
"\n",
"\n",
"\n",
"X_train_sequences, y_train_targets = create_sequences(train_df)\n",
"\n",
"X_test_sequences, y_test_targets = create_sequences(test_df)\n",
"\n",
"\n",
"print(\n",
" \"Train sequences:\",\n",
" len(X_train_sequences)\n",
")\n",
"\n",
"print(\n",
" \"Test sequences:\",\n",
" len(X_test_sequences)\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "1aa07812",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Train: (241635, 120, 10) (241635,)\n",
"Test : (60206, 120, 10) (60206,)\n"
]
}
],
"source": [
"from tensorflow.keras.preprocessing.sequence import pad_sequences\n",
"import numpy as np\n",
"\n",
"\n",
"# X_train_sequences and X_test_sequences\n",
"# should already be created from separate match splits\n",
"\n",
"X_train = pad_sequences(\n",
" X_train_sequences,\n",
" maxlen=120,\n",
" dtype=\"float32\",\n",
" padding=\"pre\"\n",
")\n",
"\n",
"X_test = pad_sequences(\n",
" X_test_sequences,\n",
" maxlen=120,\n",
" dtype=\"float32\",\n",
" padding=\"pre\"\n",
")\n",
"\n",
"\n",
"y_train = np.array(y_train_targets)\n",
"y_test = np.array(y_test_targets)\n",
"\n",
"\n",
"print(\"Train:\", X_train.shape, y_train.shape)\n",
"print(\"Test :\", X_test.shape, y_test.shape)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "e470e33f",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/keshav/code/cricket-dls/.venv/lib/python3.12/site-packages/keras/src/layers/core/masking.py:48: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead.\n",
" super().__init__(**kwargs)\n"
]
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">Model: \"sequential\"</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1mModel: \"sequential\"\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
"┃<span style=\"font-weight: bold\"> Layer (type) </span>┃<span style=\"font-weight: bold\"> Output Shape </span>┃<span style=\"font-weight: bold\"> Param # </span>┃\n",
"┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
"│ masking (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Masking</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">120</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">10</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ bidirectional (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Bidirectional</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">11,008</span> │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dropout (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dropout</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">2,080</span> │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_1 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">1</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">33</span> │\n",
"└─────────────────────────────────┴────────────────────────┴───────────────┘\n",
"</pre>\n"
],
"text/plain": [
"┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
"┃\u001b[1m \u001b[0m\u001b[1mLayer (type) \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m Param #\u001b[0m\u001b[1m \u001b[0m┃\n",
"┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
"│ masking (\u001b[38;5;33mMasking\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m120\u001b[0m, \u001b[38;5;34m10\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ bidirectional (\u001b[38;5;33mBidirectional\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m64\u001b[0m) │ \u001b[38;5;34m11,008\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dropout (\u001b[38;5;33mDropout\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m64\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m32\u001b[0m) │ \u001b[38;5;34m2,080\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_1 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1\u001b[0m) │ \u001b[38;5;34m33\u001b[0m │\n",
"└─────────────────────────────────┴────────────────────────┴───────────────┘\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Total params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">13,121</span> (51.25 KB)\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1m Total params: \u001b[0m\u001b[38;5;34m13,121\u001b[0m (51.25 KB)\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">13,121</span> (51.25 KB)\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m13,121\u001b[0m (51.25 KB)\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Non-trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> (0.00 B)\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"model = Sequential([\n",
"\n",
" Masking(\n",
" mask_value=0.,\n",
" input_shape=(120,len(FEATURES))\n",
" ),\n",
"\n",
" Bidirectional(\n",
" LSTM(32)\n",
" ),\n",
"\n",
" Dropout(0.25),\n",
"\n",
" Dense(\n",
" 32,\n",
" activation=\"relu\"\n",
" ),\n",
"\n",
" Dense(1)\n",
"\n",
"])\n",
"\n",
"model.compile(\n",
" optimizer=tf.keras.optimizers.Adam(\n",
" learning_rate=0.001\n",
" ),\n",
"\n",
" loss=\"mse\",\n",
"\n",
" metrics=[\n",
" \"mae\"\n",
" ]\n",
")\n",
"\n",
"\n",
"model.summary()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "495daca8",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 1/100\n",
"\u001b[1m118/118\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m32s\u001b[0m 254ms/step - loss: 19128.5391 - mae: 131.3299 - val_loss: 12421.8320 - val_mae: 103.6737 - learning_rate: 0.0010\n",
"Epoch 2/100\n",
"\u001b[1m118/118\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m38s\u001b[0m 321ms/step - loss: 6210.3130 - mae: 65.5333 - val_loss: 1969.1512 - val_mae: 33.6969 - learning_rate: 0.0010\n",
"Epoch 3/100\n",
"\u001b[1m118/118\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m38s\u001b[0m 321ms/step - loss: 1224.2498 - mae: 24.7959 - val_loss: 525.3225 - val_mae: 15.5029 - learning_rate: 0.0010\n",
"Epoch 4/100\n",
"\u001b[1m118/118\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m38s\u001b[0m 322ms/step - loss: 610.5830 - mae: 17.7209 - val_loss: 320.0849 - val_mae: 12.2769 - learning_rate: 0.0010\n",
"Epoch 5/100\n",
"\u001b[1m118/118\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m38s\u001b[0m 322ms/step - loss: 483.1981 - mae: 16.2305 - val_loss: 249.6277 - val_mae: 11.1048 - learning_rate: 0.0010\n",
"Epoch 6/100\n",
"\u001b[1m118/118\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m41s\u001b[0m 345ms/step - loss: 434.6412 - mae: 15.6104 - val_loss: 226.9275 - val_mae: 10.6671 - learning_rate: 0.0010\n",
"Epoch 7/100\n",
"\u001b[1m118/118\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m40s\u001b[0m 341ms/step - loss: 414.1877 - mae: 15.3427 - val_loss: 211.9790 - val_mae: 10.3182 - learning_rate: 0.0010\n",
"Epoch 8/100\n",
"\u001b[1m118/118\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m39s\u001b[0m 331ms/step - loss: 395.6093 - mae: 15.0844 - val_loss: 207.4465 - val_mae: 10.3751 - learning_rate: 0.0010\n",
"Epoch 9/100\n",
"\u001b[1m118/118\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m44s\u001b[0m 376ms/step - loss: 385.9764 - mae: 14.9372 - val_loss: 198.0012 - val_mae: 10.2073 - learning_rate: 0.0010\n",
"Epoch 10/100\n",
"\u001b[1m118/118\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m47s\u001b[0m 395ms/step - loss: 374.2676 - mae: 14.7318 - val_loss: 194.2088 - val_mae: 10.1279 - learning_rate: 0.0010\n",
"Epoch 11/100\n",
"\u001b[1m118/118\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m46s\u001b[0m 392ms/step - loss: 367.1200 - mae: 14.5911 - val_loss: 188.0659 - val_mae: 9.9135 - learning_rate: 0.0010\n",
"Epoch 12/100\n",
"\u001b[1m118/118\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m49s\u001b[0m 412ms/step - loss: 362.3481 - mae: 14.5265 - val_loss: 188.1493 - val_mae: 9.9198 - learning_rate: 0.0010\n",
"Epoch 13/100\n",
"\u001b[1m 27/118\u001b[0m \u001b[32m━━━━\u001b[0m\u001b[37m━━━━━━━━━━━━━━━━\u001b[0m \u001b[1m41s\u001b[0m 451ms/step - loss: 357.6455 - mae: 14.4617"
]
}
],
"source": [
"callbacks = [\n",
"\n",
" EarlyStopping(\n",
" patience=10,\n",
" restore_best_weights=True\n",
" ),\n",
"\n",
" ReduceLROnPlateau(\n",
" patience=5,\n",
" factor=0.5\n",
" )\n",
"\n",
"]\n",
"\n",
"\n",
"history = model.fit(\n",
"\n",
" X_train,\n",
" y_train,\n",
"\n",
" validation_data=(\n",
" X_test,\n",
" y_test\n",
" ),\n",
"\n",
" epochs=100,\n",
"\n",
" batch_size=2048,\n",
"\n",
" callbacks=callbacks,\n",
"\n",
" verbose=1\n",
")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv (3.14.6)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.13"
}
},
"nbformat": 4,
"nbformat_minor": 5
}