model-training/POET_Training.ipynb

1532 lines
163 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## General Information"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This notebook is used to train a simple neural network model to predict the chemistry in the barite benchmark (50x50 grid). The training data is stored in the repository using **git large file storage** and can be downloaded after the installation of git lfs using the `git lfs pull` command.\n",
"\n",
"It is then recommended to create a Python environment using miniconda. The necessary dependencies are contained in `environment.yml` and can be installed using `conda env create -f environment.yml`.\n",
"\n",
"The data set is divided into a design and result part and consists of the iterations of a reference simulation. The design part of the data set contains the chemical concentrations at time $t$ and the result part at time $t+1$, which are to be learned by the model."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Setup Libraries"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2025-01-23 14:37:53.766781: I tensorflow/core/util/port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n",
"2025-01-23 14:37:53.786741: I tensorflow/core/platform/cpu_feature_guard.cc:210] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.\n",
"To enable the following instructions: SSE4.1 SSE4.2 AVX AVX2 AVX_VNNI FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Running Keras in version 3.8.0\n"
]
}
],
"source": [
"import keras\n",
"import h5py\n",
"import numpy as np\n",
"import pandas as pd\n",
"import time\n",
"import sklearn.model_selection as sk\n",
"import matplotlib.pyplot as plt\n",
"from sklearn.cluster import KMeans\n",
"from sklearn.pipeline import Pipeline, make_pipeline\n",
"from sklearn.preprocessing import StandardScaler, MinMaxScaler\n",
"from imblearn.over_sampling import SMOTE\n",
"from imblearn.under_sampling import RandomUnderSampler\n",
"from imblearn.over_sampling import RandomOverSampler\n",
"from collections import Counter\n",
"import os\n",
"from preprocessing import *\n",
"from sklearn import set_config\n",
"from importlib import reload\n",
"set_config(transform_output = \"pandas\")"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"%load_ext autoreload\n",
"%autoreload 2"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Define parameters"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {},
"outputs": [],
"source": [
"dtype = \"float32\"\n",
"activation = \"relu\"\n",
"\n",
"lr = 0.001\n",
"batch_size = 512\n",
"epochs = 50 # default 400 epochs\n",
"\n",
"lr_schedule = keras.optimizers.schedules.ExponentialDecay(\n",
" initial_learning_rate=lr,\n",
" decay_steps=2000,\n",
" decay_rate=0.9,\n",
" staircase=True\n",
")\n",
"\n",
"optimizer_simple = keras.optimizers.Adam(learning_rate=lr_schedule)\n",
"optimizer_large = keras.optimizers.Adam(learning_rate=lr_schedule)\n",
"optimizer_paper = keras.optimizers.Adam(learning_rate=lr_schedule)\n",
"\n",
"\n",
"loss = keras.losses.MeanSquaredError()\n",
"\n",
"sample_fraction = 0.8"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Setup the model"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [
{
"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_2\"</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1mModel: \"sequential_2\"\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",
"│ dense_7 (<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\">128</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">1,664</span> │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_8 (<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\">128</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">16,512</span> │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_9 (<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\">12</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">1,548</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",
"│ dense_7 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m128\u001b[0m) │ \u001b[38;5;34m1,664\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_8 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m128\u001b[0m) │ \u001b[38;5;34m16,512\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_9 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m12\u001b[0m) │ \u001b[38;5;34m1,548\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\">19,724</span> (77.05 KB)\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1m Total params: \u001b[0m\u001b[38;5;34m19,724\u001b[0m (77.05 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\">19,724</span> (77.05 KB)\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m19,724\u001b[0m (77.05 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": [
"# small model\n",
"model_simple = keras.Sequential(\n",
" [\n",
" keras.Input(shape = (12,), dtype = \"float32\"),\n",
" keras.layers.Dense(units = 128, activation = \"relu\", dtype = \"float32\"),\n",
" keras.layers.Dense(units = 128, activation = \"relu\", dtype = \"float32\"),\n",
" keras.layers.Dense(units = 12, dtype = \"float32\")\n",
" ]\n",
")\n",
"\n",
"model_simple.compile(optimizer=optimizer_simple, loss = loss)\n",
"model_simple.summary()"
]
},
{
"cell_type": "code",
"execution_count": 87,
"metadata": {},
"outputs": [
{
"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_5\"</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1mModel: \"sequential_5\"\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",
"│ dense_20 (<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\">512</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">6,656</span> │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_21 (<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\">1024</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">525,312</span> │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_22 (<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\">512</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">524,800</span> │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_23 (<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\">12</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">6,156</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",
"│ dense_20 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m512\u001b[0m) │ \u001b[38;5;34m6,656\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_21 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1024\u001b[0m) │ \u001b[38;5;34m525,312\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_22 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m512\u001b[0m) │ \u001b[38;5;34m524,800\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_23 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m12\u001b[0m) │ \u001b[38;5;34m6,156\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\">1,062,924</span> (4.05 MB)\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1m Total params: \u001b[0m\u001b[38;5;34m1,062,924\u001b[0m (4.05 MB)\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\">1,062,924</span> (4.05 MB)\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m1,062,924\u001b[0m (4.05 MB)\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": [
"# large model\n",
"model_large = keras.Sequential(\n",
" [keras.layers.Input(shape=(12,), dtype=dtype),\n",
" keras.layers.Dense(512, activation='relu', dtype=dtype),\n",
" keras.layers.Dense(1024, activation='relu', dtype=dtype),\n",
" keras.layers.Dense(512, activation='relu', dtype=dtype),\n",
" keras.layers.Dense(12, dtype=dtype)\n",
" ])\n",
"\n",
"model_large.compile(optimizer=optimizer_large, loss = loss)\n",
"model_large.summary()\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"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_6\"</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1mModel: \"sequential_6\"\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",
"│ dense_24 (<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\">128</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">1,664</span> │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_25 (<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\">256</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">33,024</span> │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_26 (<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\">512</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">131,584</span> │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_27 (<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\">256</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">131,328</span> │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_28 (<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\">12</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">3,084</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",
"│ dense_24 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m128\u001b[0m) │ \u001b[38;5;34m1,664\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_25 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m256\u001b[0m) │ \u001b[38;5;34m33,024\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_26 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m512\u001b[0m) │ \u001b[38;5;34m131,584\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_27 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m256\u001b[0m) │ \u001b[38;5;34m131,328\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_28 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m12\u001b[0m) │ \u001b[38;5;34m3,084\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\">300,684</span> (1.15 MB)\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1m Total params: \u001b[0m\u001b[38;5;34m300,684\u001b[0m (1.15 MB)\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\">300,684</span> (1.15 MB)\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m300,684\u001b[0m (1.15 MB)\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 from paper\n",
"# (see https://doi.org/10.1007/s11242-022-01779-3 model for the complex chemistry)\n",
"model_paper = keras.Sequential(\n",
" [keras.layers.Input(shape=(12,), dtype=dtype),\n",
" keras.layers.Dense(128, activation='relu', dtype=dtype),\n",
" keras.layers.Dense(256, activation='relu', dtype=dtype),\n",
" keras.layers.Dense(512, activation='relu', dtype=dtype),\n",
" keras.layers.Dense(256, activation='relu', dtype=dtype),\n",
" keras.layers.Dense(12, dtype=dtype)\n",
" ])\n",
"\n",
"model_paper.compile(optimizer=optimizer_paper, loss = loss)\n",
"model_paper.summary()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Define transformer functions"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"def Safelog(val):\n",
" # get range of vector\n",
" if val > 0:\n",
" return np.log10(val)\n",
" elif val < 0:\n",
" return -np.log10(-val)\n",
" else:\n",
" return 0\n",
"\n",
"def Safeexp(val):\n",
" if val > 0:\n",
" return -10 ** -val\n",
" elif val < 0:\n",
" return 10 ** val\n",
" else:\n",
" return 0"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"# ? Why does the charge is using another logarithm than the other species\n",
"\n",
"func_dict_in = {\n",
" \"H\" : np.log1p,\n",
" \"O\" : np.log1p,\n",
" \"Charge\" : Safelog,\n",
" \"H_0_\" : np.log1p,\n",
" \"O_0_\" : np.log1p,\n",
" \"Ba\" : np.log1p,\n",
" \"Cl\" : np.log1p,\n",
" \"S_2_\" : np.log1p,\n",
" \"S_6_\" : np.log1p,\n",
" \"Sr\" : np.log1p,\n",
" \"Barite\" : np.log1p,\n",
" \"Celestite\" : np.log1p,\n",
"}\n",
"\n",
"func_dict_out = {\n",
" \"H\" : np.expm1,\n",
" \"O\" : np.expm1,\n",
" \"Charge\" : Safeexp,\n",
" \"H_0_\" : np.expm1,\n",
" \"O_0_\" : np.expm1,\n",
" \"Ba\" : np.expm1,\n",
" \"Cl\" : np.expm1,\n",
" \"S_2_\" : np.expm1,\n",
" \"S_6_\" : np.expm1,\n",
" \"Sr\" : np.expm1,\n",
" \"Barite\" : np.expm1,\n",
" \"Celestite\" : np.expm1,\n",
"}\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Read data from `.h5` file and convert it to a `pandas.DataFrame`"
]
},
{
"cell_type": "code",
"execution_count": 59,
"metadata": {},
"outputs": [],
"source": [
"# os.chdir('/mnt/beegfs/home/signer/projects/model-training')\n",
"data_file = h5py.File(\"Barite_50_Data_training.h5\")\n",
"\n",
"design = data_file[\"design\"]\n",
"results = data_file[\"result\"]\n",
"\n",
"df_design = pd.DataFrame(np.array(design[\"data\"]).transpose(), columns = np.array(design[\"names\"].asstr()))\n",
"df_results = pd.DataFrame(np.array(results[\"data\"]).transpose(), columns = np.array(results[\"names\"].asstr()))\n",
"\n",
"data_file.close()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Preprocess Data\n",
"\n",
"The data are preprocessed in the following way:\n",
"\n",
"1. Label data points in the `design` dataset with `reactive` and `non-reactive` labels using kmeans clustering\n",
"2. Transform `design` and `results` data set into log-scaled data.\n",
"3. Split data into training and test sets.\n",
"4. Learn scaler on training data for `design` and `results` together (option `global`) or individual (option `individual`).\n",
"5. Transform training and test data.\n",
"6. Split training data into training and validation dataset."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/hannessigner/miniforge3/envs/ai/lib/python3.12/site-packages/sklearn/base.py:1474: ConvergenceWarning: Number of distinct clusters (1) found smaller than n_clusters (2). Possibly due to duplicate points in X.\n",
" return fit_method(estimator, *args, **kwargs)\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Amount class 0 before: 0.9879169719169719\n",
"Amount class 1 before: 0.012083028083028084\n"
]
}
],
"source": [
"X_train, X_val, X_test, y_train, y_val, y_test, scaler_X, scaler_y = preprocessing_training(df_design, df_results, func_dict_in, func_dict_out, \"over\", 'individual', 0.1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Custom Loss function"
]
},
{
"cell_type": "code",
"execution_count": 164,
"metadata": {},
"outputs": [],
"source": [
"def custom_loss_H20(df_design_log, df_result_log, data_min_log, data_max_log, func_dict_out, postprocess):\n",
" df_result = postprocess(df_result_log, func_dict_out, data_min_log, data_max_log) \n",
" return keras.losses.Huber + np.sum(((df_result['H'] / df_result['O']) - 2)**2)\n",
"\n",
"def loss_wrapper(data_min_log, data_max_log, func_dict_out, postprocess):\n",
" def loss(df_design_log, df_result_log):\n",
" return custom_loss_H20(df_design_log, df_result_log, data_min_log, data_max_log, func_dict_out, postprocess)\n",
" return loss"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Train the model"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 1/20\n",
"\u001b[1m7823/7823\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m14s\u001b[0m 2ms/step - loss: 0.0018 - val_loss: 3.6601e-05\n",
"Epoch 2/20\n",
"\u001b[1m7823/7823\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m13s\u001b[0m 2ms/step - loss: 3.6899e-05 - val_loss: 3.6822e-05\n",
"Epoch 3/20\n",
"\u001b[1m7823/7823\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m13s\u001b[0m 2ms/step - loss: 3.5005e-05 - val_loss: 3.5655e-05\n",
"Epoch 4/20\n",
"\u001b[1m7823/7823\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m13s\u001b[0m 2ms/step - loss: 3.4032e-05 - val_loss: 3.3455e-05\n",
"Epoch 5/20\n",
"\u001b[1m7823/7823\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m14s\u001b[0m 2ms/step - loss: 3.3279e-05 - val_loss: 3.3064e-05\n",
"Epoch 6/20\n",
"\u001b[1m7823/7823\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m14s\u001b[0m 2ms/step - loss: 3.3023e-05 - val_loss: 3.3338e-05\n",
"Epoch 7/20\n",
"\u001b[1m7823/7823\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m14s\u001b[0m 2ms/step - loss: 3.2532e-05 - val_loss: 3.2765e-05\n",
"Epoch 8/20\n",
"\u001b[1m7823/7823\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m13s\u001b[0m 2ms/step - loss: 3.2749e-05 - val_loss: 3.2730e-05\n",
"Epoch 9/20\n",
"\u001b[1m7823/7823\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m13s\u001b[0m 2ms/step - loss: 3.2961e-05 - val_loss: 3.2593e-05\n",
"Epoch 10/20\n",
"\u001b[1m7823/7823\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m14s\u001b[0m 2ms/step - loss: 3.2573e-05 - val_loss: 3.2576e-05\n",
"Epoch 11/20\n",
"\u001b[1m7823/7823\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m13s\u001b[0m 2ms/step - loss: 3.2442e-05 - val_loss: 3.2507e-05\n",
"Epoch 12/20\n",
"\u001b[1m7823/7823\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m14s\u001b[0m 2ms/step - loss: 3.2135e-05 - val_loss: 3.2548e-05\n",
"Epoch 13/20\n",
"\u001b[1m7823/7823\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m14s\u001b[0m 2ms/step - loss: 3.2451e-05 - val_loss: 3.2482e-05\n",
"Epoch 14/20\n",
"\u001b[1m7823/7823\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m14s\u001b[0m 2ms/step - loss: 3.2296e-05 - val_loss: 3.2475e-05\n",
"Epoch 15/20\n",
"\u001b[1m7823/7823\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m14s\u001b[0m 2ms/step - loss: 3.2081e-05 - val_loss: 3.2470e-05\n",
"Epoch 16/20\n",
"\u001b[1m7823/7823\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m14s\u001b[0m 2ms/step - loss: 3.2440e-05 - val_loss: 3.2471e-05\n",
"Epoch 17/20\n",
"\u001b[1m7823/7823\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m14s\u001b[0m 2ms/step - loss: 3.2050e-05 - val_loss: 3.2460e-05\n",
"Epoch 18/20\n",
"\u001b[1m7823/7823\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m14s\u001b[0m 2ms/step - loss: 3.2444e-05 - val_loss: 3.2452e-05\n",
"Epoch 19/20\n",
"\u001b[1m7823/7823\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m15s\u001b[0m 2ms/step - loss: 3.2259e-05 - val_loss: 3.2452e-05\n",
"Epoch 20/20\n",
"\u001b[1m7823/7823\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m15s\u001b[0m 2ms/step - loss: 3.2442e-05 - val_loss: 3.2448e-05\n",
"Training took 276.5459449291229 seconds\n"
]
}
],
"source": [
"model_training(model_simple)"
]
},
{
"cell_type": "code",
"execution_count": 69,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[1m32/32\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 1ms/step \n"
]
},
{
"data": {
"image/png": "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bNkymzZtmvl8PrvmmmuCwogkO++886xdu3Y2Z84cW758uX3++edmZjZ06FB78cUXLSsry7Kysuyxxx6zqKiowPvmRHVUFmbee+89q127tnXs2NHmzZtnCxcutPT0dPN4PDZ37txAv/Iw06JFC7vnnnvsnXfesRdeeMHq1atnV199daBfbm6uRUZGWvfu3W3hwoX23nvv2WuvvWaDBw+uEHzx74UwA+fk5eWZJBswYMBx+916660myXbu3HnMPq1btw7MOpxIaWmpJSQkWNu2ba20tDTQXlRUZI0bN7YuXboE2soDwaRJk4K2MWLECIuMjAx8wLz//vsmycaPH3/M/W7dutXCw8PtnnvuCWovKioyv99vt9xyS6BtyJAhJsn++te/BvXt3bu3tWrVKvD4hx9+MEn28MMPV9hfee0PPfTQcUbjZyUlJbZv3z6LiYkJCl9/+9vfTJKtWLGiwnOODjPlwerosZo3b55Jsueeey7QVj4j9O233wbaDh48aPXr17dhw4Ydt9Znn3220rF56qmnTJItXbrUzMx27dplERER9sADDwT1u+WWWyw+Pt5++uknMzN7/fXXTZLNnz8/qF9OTo5JshkzZgTVHRYWZl9++eVxayx3dJgxM7vooossLS2tQt/MzEyrVauW5eTkBLX//e9/N0n21ltvBdokmc/nsx9//PG4+y8tLbWffvrJHn30UWvQoEFQIDpWHZWFmcsuu8waN25sRUVFgbaSkhJLSUmxpk2bBrZbHmZGjBgRtM1JkyaZJNuxY0fQMX366afHrR//fjgBGOcsM5MkeTyeKtnel19+qe+//16DBw9WrVr/96dTp04d3Xjjjfr444914MCBoOf86le/Cnrcrl07HTp0SPn5+ZKkt99+W5I0cuTIY+73nXfeUUlJiW6//XaVlJQElsjISKWlpVU4idfj8ahfv34V9vvtt9+e0vHeeOONFdr27dunsWPH6oILLlB4eLjCw8NVp04d7d+/X1988cUpbb/c8uXLJf18Bc+Rbr75ZsXExOjdd98Nam/fvr2aNWsWeBwZGalf/OIXJzy+5cuXKyYmRjfddFNQe/l+y/fToEED9evXT7Nnz1ZZWZkkac+ePVq0aJFuv/32wPlZixcvVt26ddWvX7+g16V9+/by+/0VXpd27drpF7/4xYkH5BQtXrxYKSkpat++fVAdPXr0kMfjqVDHNddco3r16lXYzvLly9WtWzf5fD6FhYWpdu3aeuihh7R79+7A+/VU7N+/X6tXr9ZNN90UdGVWWFiYBg8erO3bt+vLL78Mek5lfy+SAq9t+/btFRERobvuukuzZ8/WN998c8p14dxEmIFzGjZsqOjoaOXm5h6335YtWxQdHa369esfs0+zZs30ww8/aP/+/Sfc7+7duyX9fNXG0RISElRWVqY9e/YEtTdo0CDosdfrlfTzyZ+S9MMPPygsLEx+v/+Y+925c6ck6ZJLLlHt2rWDlnnz5mnXrl1B/aOjoxUZGVlhv4cOHTrhMR6psuMcOHCgpk+frt/+9rd65513tGbNGuXk5KhRo0aBYzpVu3fvVnh4uBo1ahTU7vF45Pf7A+Ne7ugxlX4+vhPtf/fu3fL7/RXCbePGjRUeHh60nzvvvFPfffedsrKyJEmvv/66iouLgwLXzp07tXfvXkVERFR4XfLy8iq8LpWNZ1XYuXOnPvvsswo1xMbGysxOqo41a9YoPT1dkvT888/ro48+Uk5OjsaPHy9Jp/Xa7tmzR2Z2zL8XSSd8bY/+ezn//PO1bNkyNW7cWCNHjtT555+v888/X9OmTTvl+nBu4WomOCcsLExXX321lixZou3btwddgVRu+/btWrdunXr16qWwsLBjbqtHjx5aunSp/vGPf2jAgAHH3W/5P7Q7duyosO77779XrVq1Kv0/3uNp1KiRSktLlZeXd8wPu4YNG0qS/v73vyspKemUtn8mjv7QLygo0OLFi/Xwww/r/vvvD7QXFxfrxx9/PO39NGjQQCUlJfrhhx+CAo2ZKS8vT5dccslpb/vo/axevVpmFnRs+fn5KikpCYyz9PP7IiEhQbNmzVKPHj00a9Yspaamqk2bNoE+DRs2VIMGDbRkyZJK9xcbGxv0uKpmCI/WsGFDRUVF6aWXXjrm+hPVMXfuXNWuXVuLFy8OCsILFy487brq1aunWrVqHfPvpbLaTsaVV16pK6+8UqWlpVq7dq3+/Oc/KyMjQ/Hx8Sf8G8a5i5kZOGncuHEyM40YMUKlpaVB60pLS3X33XfLzDRu3Ljjbuc3v/mN/H6/xowZo++++67SPgsWLJAktWrVSuedd57mzJkT+ApL+nk6ff78+ercufMpX77cq1cvSdLMmTOP2adHjx4KDw/X119/rU6dOlW6nKqj/4/3ZHg8HplZ4LnlXnjhhQqvwals/9prr5Ukvfrqq0Ht8+fP1/79+wPrz9S1116rffv2VfiA/stf/hJUh/R/X4UsXLhQH3zwgdauXas777wz6Hl9+/bV7t27VVpaWulr0qpVqyqpu9yxZp/69u2rr7/+Wg0aNKi0jpO5QaHH41F4eHhQ8D948KBeeeWVk67jaDExMUpNTdWCBQuC+peVlenVV19V06ZNz+hrt7CwMKWmpuqZZ56RJK1fv/60twX3MTMDJ11++eWaOnWqMjIydMUVV2jUqFFq1qyZtm7dqmeeeUarV6/W1KlT1aVLl+Nux+fzadGiRerbt686dOigUaNGqXPnzoqIiNDmzZv16quv6p///Kf69++vWrVqadKkSRo0aJD69u2rYcOGqbi4WH/84x+1d+9ePfnkk6d8HFdeeaUGDx6sxx9/XDt37lTfvn3l9Xr1ySefKDo6Wvfcc4+aN2+uRx99VOPHj9c333yjnj17ql69etq5c6fWrFmjmJgYPfLII6e039jYWCUlJWnRokW69tprVb9+fTVs2PC4H3xxcXG66qqr9Mc//jHQNzs7Wy+++KLq1q0b1DclJUWS9Nxzzyk2NlaRkZFKTk6u9Cui7t27q0ePHho7dqwKCwt1+eWX67PPPtPDDz+sDh06aPDgwad0bMdy++2365lnntGQIUO0ZcsWtW3bVh9++KEmTpyo3r17q1u3bkH977zzTj311FMaOHCgoqKidOuttwatHzBggF577TX17t1bo0eP1qWXXqratWtr+/btWrFiha677jrdcMMNVVK7JLVt21Zz587VvHnz1KJFC0VGRqpt27bKyMjQ/PnzddVVV+l3v/ud2rVrp7KyMm3dulVLly7V73//e6Wmph5323369NGUKVM0cOBA3XXXXdq9e7cmT55cIbger47KZGZmqnv37rr66qt13333KSIiQjNmzNDnn3+u119//ZRnq5599lktX75cffr0UbNmzXTo0KHAjNTRrx/+zYTs1GOgCqxatcpuuukmi4+Pt/DwcGvcuLH179+/wn1fTiQvL8/Gjh1rF110kUVHR5vX67ULLrjAhg0bZhs2bAjqu3DhQktNTbXIyEiLiYmxa6+91j766KOgPuVXBJVfrlyu/KqN3NzcQFtpaan96U9/spSUFIuIiDCfz2edO3e2f/zjHxX2e/XVV1tcXJx5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3XXW6gBwdoWHugAAOJHDhw8rIiLitJ/fqFGjKqwGQE3DzAyAajF06FBlZ2dr2rRp8ng88ng82rJliyRp06ZN6t27t+rUqaP4+HgNHjxYu3btCjy3a9euGjVqlO699141bNhQ3bt3lyRNmTJFbdu2VUxMjBITEzVixAjt27dPkvTee+/pjjvuUEFBQWB/EyZMkFTxa6atW7fquuuuU506dRQXF6dbbrlFO3fuDKyfMGGC2rdvr1deeUXNmzeXz+fTgAEDVFRUVL2DBuC0EGYAVItp06apc+fO+o//+A/t2LFDO3bsUGJionbs2KG0tDS1b99ea9eu1ZIlS7Rz507dcsstQc+fPXu2wsPD9dFHH+m///u/JUm1atXS008/rc8//1yzZ8/W8uXLNWbMGElSly5dNHXqVMXFxQX2d99991Woy8x0/fXX68cff1R2draysrL09ddf69Zbbw3q9/XXX2vhwoVavHixFi9erOzsbD355JPVNFoAzgRfMwGoFj6fTxEREYqOjpbf7w+0z5w5UxdffLEmTpwYaHvppZeUmJior776Sr/4xS8kSRdccIEmTZoUtM0jz79JTk7WY489prvvvlszZsxQRESEfD6fPB5P0P6OtmzZMn322WfKzc1VYmKiJOmVV17RRRddpJycHF1yySWSpLKyMr388suKjY2VJA0ePFjvvvuunnjiiTMbGABVjpkZAGfVunXrtGLFCtWpUyewtG7dWtLPsyHlOnXqVOG5K1asUPfu3XXeeecpNjZWt99+u3bv3q39+/ef9P6/+OILJSYmBoKMJLVp00Z169bVF198EWhr3rx5IMhIUpMmTZSfn39Kxwrg7GBmBsBZVVZWpn79+umpp56qsK5JkyaB/46JiQla9+2336p3794aPny4HnvsMdWvX18ffvihfvOb3+inn3466f2bmTwezwnba9euHbTe4/GorKzspPcD4OwhzACoNhERESotLQ1qu/jiizV//nw1b95c4eEn/0/Q2rVrVVJSov/6r/9SrVo/Tyr/9a9/PeH+jtamTRtt3bpV27ZtC8zObNq0SQUFBbrwwgtPuh4ANQdfMwGoNs2bN9fq1au1ZcsW7dq1S2VlZRo5cqR+/PFH3XbbbVqzZo2++eYbLV26VHfeeedxg8j555+vkpIS/fnPf9Y333yjV155Rc8++2yF/e3bt0/vvvuudu3apQMHDlTYTrdu3dSuXTsNGjRI69ev15o1a3T77bcrLS2t0q+2ANR8hBkA1ea+++5TWFiY2rRpo0aNGmnr1q1KSEjQRx99pNLSUvXo0UMpKSkaPXq0fD5fYMalMu3bt9eUKVP01FNPKSUlRa+99poyMzOD+nTp0kXDhw/XrbfeqkaNGlU4gVj6+euihQsXql69errqqqvUrVs3tWjRQvPmzavy4wdwdnjMzEJdBAAAwOliZgYAADiNMAMAAJxGmAEAAE4jzAAAAKcRZgAAgNMIMwAAwGmEGQAA4DTCDAAAcBphBgAAOI0wAwAAnEaYAQAATiPMAAAAp/1/7MgGXoPfaWQAAAAASUVORK5CYII=",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAh8AAAGsCAYAAAB968WXAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAJJVJREFUeJzt3XtU1HXi//HXyGUUZabQEBA0UpMMUVfTUEszNc3KatduhppWa5ul+au8VF+rXYVqa7fditR2Oe3pwh5Tyzorm61CF6+orKSVlpom4KVwIExQeP/+cJ2aQHIA3zD6fJzD+crn8573vOet7Ty/M58BhzHGCAAAwJJmjb0AAABwdiE+AACAVcQHAACwivgAAABWER8AAMAq4gMAAFhFfAAAAKuIDwAAYBXxAQAArCI+AACAVU06Pj788ENde+21iomJkcPh0Ntvv33a73Pv3r26/fbb1bp1a4WFhalHjx7asGFDneebM2eO+vXrp7CwMJ1zzjmndJvFixfrqquuUps2beRwOJSXl1dtzPz58zVo0CC5XC45HA4dOnSo2pji4mKlpKTI7XbL7XYrJSWl2rgpU6aoV69ecjqd6tGjR7U5srOzNWrUKEVHR6tly5bq0aOHXn/99ZOu/ZNPPlFwcHCNc9Vm165dmjhxouLj49WiRQt17NhRs2fPVkVFhV/zAACaviYdH2VlZerevbteeOEFK/dXXFys/v37KyQkRMuWLdPWrVv17LPP1hoN559/vrKzs096vqKiQqNHj9Y999xzyusoKytT//79lZaWdtIxhw8f1vDhwzVr1qyTjrntttuUl5enrKwsZWVlKS8vTykpKT5jjDGaMGGCbr755hrnWLVqlZKSkrRo0SJt3rxZEyZM0NixY/Xuu+9WG+vxeDR27FhdeeWVp/hIf/T555+rqqpK8+bN05YtW/SnP/1JL7/8cq2PDwAQoEyAkGSWLFnic6y8vNw89NBDJiYmxoSFhZk+ffqYlStX1vk+pk+fbgYMGODXbTp06HBK95mRkWHcbrdfc+/cudNIMps2bTrpmJUrVxpJpri42Of41q1bjSSzZs0a77HVq1cbSebzzz+vNs/s2bNN9+7dT2ldV199tbnjjjuqHb/55pvNo48+etK5/v73v5uEhATjdDpNly5dzIsvvljr/Tz99NMmPj7+lNYEAAgcTfqVj19yxx136JNPPlFmZqY2b96s0aNHa/jw4dq+fXud5lu6dKl69+6t0aNHKzIyUj179tSCBQsaeNV2rF69Wm63W3379vUeu/TSS+V2u7Vq1ap6ze3xeBQREeFzLCMjQ1999ZVmz55d420WLFigRx55RHPmzNFnn32muXPn6rHHHtOrr77q1/0AAAJfwMbHV199pTfffFMLFy7UZZddpo4dO+rBBx/UgAEDlJGRUac5d+zYofT0dHXu3Fn//ve/NWnSJN1///36xz/+0cCrP/2KiooUGRlZ7XhkZKSKiorqPO9bb72l9evX64477vAe2759u2bMmKHXX39dwcHBNd7u97//vZ599lndeOONio+P14033qgHHnhA8+bNq3H8V199pb/+9a+aNGlSndcKAGiaan6mCAAbN26UMUYXXnihz/Hy8nK1bt1a0vGLGOPj42ud59577/VeU1JVVaXevXtr7ty5kqSePXtqy5YtSk9P19ixYyVJkyZN0muvvea9/eHDhzVixAgFBQV5j23dulXt27ev/4OsJ4fDUe2YMabG46ciOztb48eP14IFC3TxxRdLkiorK3XbbbfpiSeeqPZ3ccKBAwe0Z88eTZw4UXfddZf3+LFjx+R2u6uNLygo0PDhwzV69GjdeeeddVorAKDpCtj4qKqqUlBQkDZs2ODzxC9JrVq1kiS1a9dOn332Wa3znHvuud4/R0dHq2vXrj7nL7roIi1atMj7/ZNPPqkHH3zQ+/2gQYP01FNP+by9ERMT4/8DamBRUVHat29fteMHDhxQ27Zt/Z4vJydH1157rZ577jlviElSaWmpcnNztWnTJk2ePFnS8b8bY4yCg4P1/vvve0NlwYIFPvskqdrfXUFBga644golJydr/vz5fq8TAND0BWx89OzZU5WVldq/f78uu+yyGseEhIQoISHhlOfs37+/vvjiC59j27ZtU4cOHbzfR0ZG+rydERwcrHbt2qlTp05+PoLTKzk5WR6PR+vWrVOfPn0kSWvXrpXH41G/fv38mis7O1vXXHONnnrqKd19990+51wul/Lz832OvfTSS1qxYoXeeustxcfHq2XLlmrXrp127NihMWPGnPR+9u7dqyuuuEK9evVSRkaGmjUL2HcFAQC1aNLx8f333+vLL7/0fr9z507l5eUpIiJCF154ocaMGaOxY8fq2WefVc+ePXXw4EGtWLFC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AKwiPgAAgFXEBwAAsIr4AAAAVhEfAADAKuIDAABYRXwAAACriA8AAGAV8QEAAKwiPgAAgFXEBwAAsMqv+EhPT1dSUpJcLpdcLpeSk5O1bNky73ljjB5//HHFxMSoRYsWGjRokLZs2dLgiwYAAIHLr/iIjY1VWlqacnNzlZubq8GDB2vUqFHewHj66af13HPP6YUXXtD69esVFRWloUOHqrS09LQsHgAABB6HMcbUZ4KIiAg988wzmjBhgmJiYjR16lRNnz5dklReXq62bdvqqaee0m9/+9tTmq+kpERut1sej0cul6s+SwMAAJb48/xd52s+KisrlZmZqbKyMiUnJ2vnzp0qKirSsGHDvGOcTqcGDhyoVatWnXSe8vJylZSU+HwBAIAzl9/xkZ+fr1atWsnpdGrSpElasmSJunbtqqKiIklS27Ztfca3bdvWe64mqampcrvd3q+4uDh/lwQAAAKI3/HRpUsX5eXlac2aNbrnnns0btw4bd261Xve4XD4jDfGVDv2UzNnzpTH4/F+7dmzx98lAQCAABLs7w1CQ0PVqVMnSVLv3r21fv16Pf/8897rPIqKihQdHe0dv3///mqvhvyU0+mU0+n0dxkAACBA1fvnfBhjVF5ervj4eEVFRWn58uXecxUVFcrJyVG/fv3qezcAAOAM4dcrH7NmzdKIESMUFxen0tJSZWZmKjs7W1lZWXI4HJo6darmzp2rzp07q3Pnzpo7d67CwsJ02223na71AwCAAONXfOzbt08pKSkqLCyU2+1WUlKSsrKyNHToUEnSww8/rB9++EG/+93vVFxcrL59++r9999XeHj4aVk8AAAIPPX+OR8NjZ/zAQBA4LHycz4AAADqgvgAAABWER8AAMAq4gMAAFhFfAAAAKuIDwAAYBXxAQAArCI+AACAVcQHAACwivgAAABWER8AAMAq4gMAAFhFfAAAAKuIDwAAYBXxAQAArCI+AACAVcQHAACwivgAAABWER8AAMAq4gMAAFhFfAAAAKuIDwAAYBXxAQAArCI+AACAVcQHAACwivgAAABWER8AAMAq4gMAAFhFfAAAAKuIDwAAYBXxAQAArCI+AACAVcQHAACwivgAAABWER8AAMAq4gMAAFhFfAAAAKuIDwAAYBXxAQAArCI+AACAVcQHAACwivgAAABWER8AAMAq4gMAAFhFfAAAAKuI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Wnk8nvrve70uVw0QJz5q+7e//c1s3brVTJ061bRs2dLs2rWrsZcWMO655x7jdrtNdna2KSws9H4dPnzYOyYtLc243W6zePFik5+fb2699dYaP9oVGxtrPvjgA7Nx40YzePDgs/rjcqfip592MYZ9bijr1q0zwcHBZs6cOWb79u3m9ddfN2FhYea1117zjmGv62/cuHGmXbt23o/aLl682LRp08Y8/PDD3jHss/9KS0vNpk2bzKZNm4wk89xzz5lNmzZ5f4REQ+3p8OHDTVJSklm9erVZvXq16datGx+19ceLL75oOnToYEJDQ82vfvUr70dEcWok1fiVkZHhHVNVVWVmz55toqKijNPpNJdffrnJz8/3meeHH34wkydPNhEREaZFixbmmmuuMbt377b8aALLz+ODfW447777rklMTDROp9MkJCSY+fPn+5xnr+uvpKTETJkyxbRv3940b97cXHDBBeaRRx4x5eXl3jHss/9WrlxZ4/8mjxs3zhjTcHv67bffmjFjxpjw8HATHh5uxowZY4qLi+u9focxxtTvtRMAAIBTd8Zf8wEAAJoW4gMAAFhFfAAAAKuIDwAAYBXxAQAArCI+AACAVcQHAACwivgAAABWER8AAMAq4gMAAFhFfAAAAKuIDwAAYNX/BxJdbIcUM2/sAAAAAElFTkSuQmCC",
"text/plain": [
"<matplotlib.image.AxesImage at 0x7fa3db2b7010>"
]
},
"execution_count": 69,
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "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/XrwwQdVVVUliXW60fDwsGpqanT16lXdcccdOn78uO6///70L0/W6Evd3d364IMPNDAwMGMf/z0tzJKN0HW3+jXh+Apr9pW9e/fq7Nmzev/992fsY52k++67T0NDQ/r888/1t7/9Tbt27VIkEknvZ42kaDSqffv2qaenR2vWrJnzONZqfpbsn+Ny/ZpwSMFgUJJYs3979tln9eabb+q9995TWVlZepx1+kpRUZHuvfdebdmyReFwWJs2bdJLL73EGt3g9OnTGhsb0+bNm1VQUKCCggJFIhH95je/UUFBQXo9WKv5WbIRuvFrwm/U29ur2tpao1ktbRUVFQoGgxlrNjExoUgkclutmXNOe/fu1bFjx/Tuu++qoqIiYz/rNDfnnFKpFGt0g23btml4eFhDQ0PpbcuWLdq5c6eGhoZ0zz33sFYLYXdPxM0t5GvCV6pkMunOnDnjzpw54yS5zs5Od+bMGXfhwgXnnHOHDh1yfr/fHTt2zA0PD7sf//jHbuPGjS6RSBjP/OvzzDPPOL/f706ePOkuXryY3r744ov0MayTc62tra6vr8+Njo66s2fPuueff96tWrXK9fT0OOdYo2xuvDvOOdZqIZZ0hJxz7re//a27++67XVFRkfvud7+bvs32dvXee+/N+l3uu3btcs59ebvoCy+84ILBoPN6ve7hhx92w8PDtpP+ms22PpLca6+9lj6GdXLuqaeeSv+/9a1vfctt27YtHSDnWKNs/jNCrNX88VUOAAAzS/Y1IQDAykeEAABmiBAAwAwRAgCYIUIAADNECABghggBAMwQIQCAGSIEADBDhAAAZogQAMAMEQIAmPl/qGKdNepT4hUAAAAASUVORK5CYII=",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import matplotlib.pyplot as plt\n",
"\n",
"species = \"O\"\n",
"iterations = 1000\n",
"cell_offset = 60\n",
"y_design = []\n",
"y_results = []\n",
"y_differences = []\n",
"\n",
"\n",
"df_design_transformed_scaled = scaler_X.transform(FuncTransform(func_dict_in, func_dict_out).fit_transform(df_design))\n",
"df_results_transformed_scaled = scaler_X.transform(FuncTransform(func_dict_in, func_dict_out).fit_transform(df_results))\n",
"\n",
"for i in range(0,iterations):\n",
" idx = i*50*50 + cell_offset -1\n",
" y_design.append(df_design_transformed_scaled.iloc[idx, :])\n",
" y_results.append(df_results_transformed_scaled.iloc[idx,:])\n",
" \n",
"y_design = pd.DataFrame(y_design)\n",
"y_results = pd.DataFrame(y_results)\n",
"# plt.plot(np.arange(0,iterations), y_design[species], label = \"Design\")\n",
"plt.plot(np.arange(0,iterations), y_results[species], label = \"Results\")\n",
"\n",
"prediction = model_simple.predict(y_design.iloc[:, y_design.columns != \"Class\"])\n",
"prediction = pd.DataFrame(prediction, columns = y_results.columns)\n",
"\n",
"y_results_back = FuncTransform(func_dict_in, func_dict_out).inverse_transform(pd.DataFrame(scaler_X.inverse_transform(y_results), columns=df_results.columns))\n",
"prediction_back = FuncTransform(func_dict_in, func_dict_out).inverse_transform(pd.DataFrame(scaler_X.inverse_transform(prediction), columns=df_results.columns))\n",
"\n",
"plt.plot(np.arange(0,iterations), prediction[species], label = \"Prediction\")\n",
"plt.xlabel('Iteration')\n",
"plt.ylabel(species)\n",
"plt.title(species+' Concentration over Iterations')\n",
"plt.show()\n",
"\n",
"plt.plot(np.arange(0,iterations), y_results_back[species], label = \"Results\")\n",
"plt.plot(np.arange(0,iterations), prediction_back[species], label = \"Prediction\")\n",
"\n",
"plt.show()\n",
"\n",
"timestep = 1000\n",
"plt.imshow(np.array(df_results[\"Barite\"][(timestep*2500):(timestep*2500+2500)]).reshape(50,50), origin='lower')"
]
},
{
"cell_type": "code",
"execution_count": 25,
"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>H</th>\n",
" <th>O</th>\n",
" <th>Charge</th>\n",
" <th>H_0_</th>\n",
" <th>O_0_</th>\n",
" <th>Ba</th>\n",
" <th>Cl</th>\n",
" <th>S_2_</th>\n",
" <th>S_6_</th>\n",
" <th>Sr</th>\n",
" <th>Barite</th>\n",
" <th>Celestite</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>111.012434</td>\n",
" <td>55.508700</td>\n",
" <td>-1.216415e-09</td>\n",
" <td>0.0</td>\n",
" <td>2.217711e-13</td>\n",
" <td>4.495355e-07</td>\n",
" <td>1.532249e-12</td>\n",
" <td>0.0</td>\n",
" <td>0.000621</td>\n",
" <td>0.000620</td>\n",
" <td>0.001000</td>\n",
" <td>1.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>111.012434</td>\n",
" <td>55.508700</td>\n",
" <td>-1.222504e-09</td>\n",
" <td>0.0</td>\n",
" <td>1.312902e-12</td>\n",
" <td>4.500359e-07</td>\n",
" <td>1.044603e-08</td>\n",
" <td>0.0</td>\n",
" <td>0.000621</td>\n",
" <td>0.000620</td>\n",
" <td>0.001000</td>\n",
" <td>1.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>111.012434</td>\n",
" <td>55.508699</td>\n",
" <td>-1.220407e-09</td>\n",
" <td>0.0</td>\n",
" <td>1.614098e-12</td>\n",
" <td>4.500563e-07</td>\n",
" <td>4.907802e-07</td>\n",
" <td>0.0</td>\n",
" <td>0.000621</td>\n",
" <td>0.000620</td>\n",
" <td>0.001000</td>\n",
" <td>1.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>111.012434</td>\n",
" <td>55.508695</td>\n",
" <td>-1.216831e-09</td>\n",
" <td>0.0</td>\n",
" <td>2.293739e-12</td>\n",
" <td>4.504482e-07</td>\n",
" <td>4.772370e-06</td>\n",
" <td>0.0</td>\n",
" <td>0.000620</td>\n",
" <td>0.000622</td>\n",
" <td>0.001000</td>\n",
" <td>1.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>111.012434</td>\n",
" <td>55.508679</td>\n",
" <td>-1.216842e-09</td>\n",
" <td>0.0</td>\n",
" <td>2.641545e-12</td>\n",
" <td>4.534070e-07</td>\n",
" <td>2.200220e-05</td>\n",
" <td>0.0</td>\n",
" <td>0.000616</td>\n",
" <td>0.000626</td>\n",
" <td>0.001000</td>\n",
" <td>1.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>995</th>\n",
" <td>111.012434</td>\n",
" <td>55.506410</td>\n",
" <td>2.170844e-08</td>\n",
" <td>0.0</td>\n",
" <td>4.777415e-11</td>\n",
" <td>1.550089e-04</td>\n",
" <td>9.784038e-02</td>\n",
" <td>0.0</td>\n",
" <td>0.000048</td>\n",
" <td>0.048814</td>\n",
" <td>0.149476</td>\n",
" <td>0.846327</td>\n",
" </tr>\n",
" <tr>\n",
" <th>996</th>\n",
" <td>111.012434</td>\n",
" <td>55.506410</td>\n",
" <td>2.166504e-08</td>\n",
" <td>0.0</td>\n",
" <td>4.808612e-11</td>\n",
" <td>1.559012e-04</td>\n",
" <td>9.785750e-02</td>\n",
" <td>0.0</td>\n",
" <td>0.000048</td>\n",
" <td>0.048821</td>\n",
" <td>0.151708</td>\n",
" <td>0.844093</td>\n",
" </tr>\n",
" <tr>\n",
" <th>997</th>\n",
" <td>111.012434</td>\n",
" <td>55.506409</td>\n",
" <td>2.162167e-08</td>\n",
" <td>0.0</td>\n",
" <td>4.811205e-11</td>\n",
" <td>1.567226e-04</td>\n",
" <td>9.787459e-02</td>\n",
" <td>0.0</td>\n",
" <td>0.000048</td>\n",
" <td>0.048829</td>\n",
" <td>0.153945</td>\n",
" <td>0.841856</td>\n",
" </tr>\n",
" <tr>\n",
" <th>998</th>\n",
" <td>111.012434</td>\n",
" <td>55.506409</td>\n",
" <td>2.157995e-08</td>\n",
" <td>0.0</td>\n",
" <td>4.815004e-11</td>\n",
" <td>1.574812e-04</td>\n",
" <td>9.789167e-02</td>\n",
" <td>0.0</td>\n",
" <td>0.000048</td>\n",
" <td>0.048836</td>\n",
" <td>0.156185</td>\n",
" <td>0.839614</td>\n",
" </tr>\n",
" <tr>\n",
" <th>999</th>\n",
" <td>111.012434</td>\n",
" <td>55.506409</td>\n",
" <td>2.153938e-08</td>\n",
" <td>0.0</td>\n",
" <td>4.815067e-11</td>\n",
" <td>1.581835e-04</td>\n",
" <td>9.790872e-02</td>\n",
" <td>0.0</td>\n",
" <td>0.000048</td>\n",
" <td>0.048844</td>\n",
" <td>0.158428</td>\n",
" <td>0.837370</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>1000 rows × 12 columns</p>\n",
"</div>"
],
"text/plain": [
" H O Charge H_0_ O_0_ Ba \\\n",
"0 111.012434 55.508700 -1.216415e-09 0.0 2.217711e-13 4.495355e-07 \n",
"1 111.012434 55.508700 -1.222504e-09 0.0 1.312902e-12 4.500359e-07 \n",
"2 111.012434 55.508699 -1.220407e-09 0.0 1.614098e-12 4.500563e-07 \n",
"3 111.012434 55.508695 -1.216831e-09 0.0 2.293739e-12 4.504482e-07 \n",
"4 111.012434 55.508679 -1.216842e-09 0.0 2.641545e-12 4.534070e-07 \n",
".. ... ... ... ... ... ... \n",
"995 111.012434 55.506410 2.170844e-08 0.0 4.777415e-11 1.550089e-04 \n",
"996 111.012434 55.506410 2.166504e-08 0.0 4.808612e-11 1.559012e-04 \n",
"997 111.012434 55.506409 2.162167e-08 0.0 4.811205e-11 1.567226e-04 \n",
"998 111.012434 55.506409 2.157995e-08 0.0 4.815004e-11 1.574812e-04 \n",
"999 111.012434 55.506409 2.153938e-08 0.0 4.815067e-11 1.581835e-04 \n",
"\n",
" Cl S_2_ S_6_ Sr Barite Celestite \n",
"0 1.532249e-12 0.0 0.000621 0.000620 0.001000 1.000000 \n",
"1 1.044603e-08 0.0 0.000621 0.000620 0.001000 1.000000 \n",
"2 4.907802e-07 0.0 0.000621 0.000620 0.001000 1.000000 \n",
"3 4.772370e-06 0.0 0.000620 0.000622 0.001000 1.000000 \n",
"4 2.200220e-05 0.0 0.000616 0.000626 0.001000 1.000000 \n",
".. ... ... ... ... ... ... \n",
"995 9.784038e-02 0.0 0.000048 0.048814 0.149476 0.846327 \n",
"996 9.785750e-02 0.0 0.000048 0.048821 0.151708 0.844093 \n",
"997 9.787459e-02 0.0 0.000048 0.048829 0.153945 0.841856 \n",
"998 9.789167e-02 0.0 0.000048 0.048836 0.156185 0.839614 \n",
"999 9.790872e-02 0.0 0.000048 0.048844 0.158428 0.837370 \n",
"\n",
"[1000 rows x 12 columns]"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"FuncTransform(func_dict_in, func_dict_out).inverse_transform(pd.DataFrame(scaler_X.inverse_transform(y_results), columns=df_results.columns))"
]
},
{
"cell_type": "code",
"execution_count": 26,
"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>H</th>\n",
" <th>O</th>\n",
" <th>Charge</th>\n",
" <th>H_0_</th>\n",
" <th>O_0_</th>\n",
" <th>Ba</th>\n",
" <th>Cl</th>\n",
" <th>S_2_</th>\n",
" <th>S_6_</th>\n",
" <th>Sr</th>\n",
" <th>Barite</th>\n",
" <th>Celestite</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>111.012428</td>\n",
" <td>55.508682</td>\n",
" <td>-1.193141e-09</td>\n",
" <td>3.397941e-15</td>\n",
" <td>2.128961e-13</td>\n",
" <td>-0.000012</td>\n",
" <td>0.000021</td>\n",
" <td>-1.191799e-17</td>\n",
" <td>0.000620</td>\n",
" <td>0.000630</td>\n",
" <td>0.000985</td>\n",
" <td>1.000231</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>111.012428</td>\n",
" <td>55.508682</td>\n",
" <td>-1.202185e-09</td>\n",
" <td>2.918474e-15</td>\n",
" <td>1.019832e-12</td>\n",
" <td>-0.000016</td>\n",
" <td>0.000008</td>\n",
" <td>-7.920033e-18</td>\n",
" <td>0.000620</td>\n",
" <td>0.000630</td>\n",
" <td>0.000946</td>\n",
" <td>1.000121</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>111.012428</td>\n",
" <td>55.508682</td>\n",
" <td>-1.203471e-09</td>\n",
" <td>1.785468e-15</td>\n",
" <td>2.398433e-12</td>\n",
" <td>-0.000015</td>\n",
" <td>-0.000013</td>\n",
" <td>-9.158671e-18</td>\n",
" <td>0.000620</td>\n",
" <td>0.000627</td>\n",
" <td>0.000913</td>\n",
" <td>0.999977</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>111.012428</td>\n",
" <td>55.508682</td>\n",
" <td>-1.199235e-09</td>\n",
" <td>1.746077e-15</td>\n",
" <td>2.357316e-12</td>\n",
" <td>-0.000016</td>\n",
" <td>-0.000011</td>\n",
" <td>-9.246642e-18</td>\n",
" <td>0.000619</td>\n",
" <td>0.000629</td>\n",
" <td>0.000916</td>\n",
" <td>0.999936</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>111.012428</td>\n",
" <td>55.508682</td>\n",
" <td>-1.197043e-09</td>\n",
" <td>1.533956e-15</td>\n",
" <td>2.670053e-12</td>\n",
" <td>-0.000019</td>\n",
" <td>0.000003</td>\n",
" <td>-9.144569e-18</td>\n",
" <td>0.000615</td>\n",
" <td>0.000635</td>\n",
" <td>0.000943</td>\n",
" <td>0.999769</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>995</th>\n",
" <td>111.012428</td>\n",
" <td>55.506416</td>\n",
" <td>2.189995e-08</td>\n",
" <td>-3.792428e-15</td>\n",
" <td>4.785985e-11</td>\n",
" <td>0.000279</td>\n",
" <td>0.097642</td>\n",
" <td>1.182626e-16</td>\n",
" <td>0.000051</td>\n",
" <td>0.048738</td>\n",
" <td>0.149016</td>\n",
" <td>0.844585</td>\n",
" </tr>\n",
" <tr>\n",
" <th>996</th>\n",
" <td>111.012428</td>\n",
" <td>55.506416</td>\n",
" <td>2.188781e-08</td>\n",
" <td>-3.910681e-15</td>\n",
" <td>4.822730e-11</td>\n",
" <td>0.000279</td>\n",
" <td>0.097665</td>\n",
" <td>1.169111e-16</td>\n",
" <td>0.000051</td>\n",
" <td>0.048751</td>\n",
" <td>0.151241</td>\n",
" <td>0.842272</td>\n",
" </tr>\n",
" <tr>\n",
" <th>997</th>\n",
" <td>111.012428</td>\n",
" <td>55.506416</td>\n",
" <td>2.184875e-08</td>\n",
" <td>-3.749360e-15</td>\n",
" <td>4.824932e-11</td>\n",
" <td>0.000279</td>\n",
" <td>0.097687</td>\n",
" <td>1.146696e-16</td>\n",
" <td>0.000051</td>\n",
" <td>0.048761</td>\n",
" <td>0.153477</td>\n",
" <td>0.840015</td>\n",
" </tr>\n",
" <tr>\n",
" <th>998</th>\n",
" <td>111.012428</td>\n",
" <td>55.506416</td>\n",
" <td>2.180415e-08</td>\n",
" <td>-3.500642e-15</td>\n",
" <td>4.816323e-11</td>\n",
" <td>0.000279</td>\n",
" <td>0.097710</td>\n",
" <td>1.119656e-16</td>\n",
" <td>0.000051</td>\n",
" <td>0.048770</td>\n",
" <td>0.155720</td>\n",
" <td>0.837773</td>\n",
" </tr>\n",
" <tr>\n",
" <th>999</th>\n",
" <td>111.012428</td>\n",
" <td>55.506416</td>\n",
" <td>2.177183e-08</td>\n",
" <td>-3.375572e-15</td>\n",
" <td>4.822685e-11</td>\n",
" <td>0.000279</td>\n",
" <td>0.097732</td>\n",
" <td>1.095921e-16</td>\n",
" <td>0.000050</td>\n",
" <td>0.048780</td>\n",
" <td>0.157962</td>\n",
" <td>0.835504</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>1000 rows × 12 columns</p>\n",
"</div>"
],
"text/plain": [
" H O Charge H_0_ O_0_ \\\n",
"0 111.012428 55.508682 -1.193141e-09 3.397941e-15 2.128961e-13 \n",
"1 111.012428 55.508682 -1.202185e-09 2.918474e-15 1.019832e-12 \n",
"2 111.012428 55.508682 -1.203471e-09 1.785468e-15 2.398433e-12 \n",
"3 111.012428 55.508682 -1.199235e-09 1.746077e-15 2.357316e-12 \n",
"4 111.012428 55.508682 -1.197043e-09 1.533956e-15 2.670053e-12 \n",
".. ... ... ... ... ... \n",
"995 111.012428 55.506416 2.189995e-08 -3.792428e-15 4.785985e-11 \n",
"996 111.012428 55.506416 2.188781e-08 -3.910681e-15 4.822730e-11 \n",
"997 111.012428 55.506416 2.184875e-08 -3.749360e-15 4.824932e-11 \n",
"998 111.012428 55.506416 2.180415e-08 -3.500642e-15 4.816323e-11 \n",
"999 111.012428 55.506416 2.177183e-08 -3.375572e-15 4.822685e-11 \n",
"\n",
" Ba Cl S_2_ S_6_ Sr Barite Celestite \n",
"0 -0.000012 0.000021 -1.191799e-17 0.000620 0.000630 0.000985 1.000231 \n",
"1 -0.000016 0.000008 -7.920033e-18 0.000620 0.000630 0.000946 1.000121 \n",
"2 -0.000015 -0.000013 -9.158671e-18 0.000620 0.000627 0.000913 0.999977 \n",
"3 -0.000016 -0.000011 -9.246642e-18 0.000619 0.000629 0.000916 0.999936 \n",
"4 -0.000019 0.000003 -9.144569e-18 0.000615 0.000635 0.000943 0.999769 \n",
".. ... ... ... ... ... ... ... \n",
"995 0.000279 0.097642 1.182626e-16 0.000051 0.048738 0.149016 0.844585 \n",
"996 0.000279 0.097665 1.169111e-16 0.000051 0.048751 0.151241 0.842272 \n",
"997 0.000279 0.097687 1.146696e-16 0.000051 0.048761 0.153477 0.840015 \n",
"998 0.000279 0.097710 1.119656e-16 0.000051 0.048770 0.155720 0.837773 \n",
"999 0.000279 0.097732 1.095921e-16 0.000050 0.048780 0.157962 0.835504 \n",
"\n",
"[1000 rows x 12 columns]"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"FuncTransform(func_dict_in, func_dict_out).inverse_transform(pd.DataFrame(scaler_X.inverse_transform(prediction), columns=prediction.columns))"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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16+fU5t3797dbNlgPq+S9NFHHzn1taioSJJ05513trhfMJzXU6dOacCAAVqwYIHL93/729/qhRde0IIFC/TRRx8pOTlZw4cPdzx/05Xi4mJlZ2crJydHu3btUk5OjsaPH69t27b5qxtuaamv1dXV2rFjh2bOnKkdO3Zo9erV+uKLL3Tbbbe1Wm+XLl2cznNZWZliYmL80QWPtHZuJWnkyJFO7S4sLGyxzmA8t5KanJ9XXnlFJpNJY8eObbHejnpu/cZAh3PdddcZkyZNctrWp08fY+rUqS7LP/XUU0afPn2ctj388MPG4MGD/dZGfzl8+LAhydi0aVOzZd59911DknHs2LH2a5gPzJo1yxgwYIDb5UPpvBqGYTz++ONG7969DZvN5vL9YD2vkow1a9Y4XttsNiM5OdmYN2+eY1tNTY0RHx9vLFmypNl6xo8fb4wcOdJp24gRI4y77rrL52321vl9deXDDz80JBlff/11s2VeffVVIz4+3reN8wNX/b3//vuNMWPGeFRPqJzbMWPGGDfffHOLZYLl3PoSI1IdTF1dnbZv366srCyn7VlZWdq6davLfYqLi5uUHzFihD7++GNZrVa/tdUfKisrJUkXXnhhq2WvvvpqpaSk6JZbbtG7777r76b5xP79+5Wamqq0tDTddddd+vLLL5stG0rnta6uTn/5y1/04IMPtvoA72A8r+cqLS1VeXm507mzWCwaNmxYs/+GpebPd0v7dESVlZUymUxKSEhosdzJkyfVq1cvXXzxxfrxj3+skpKS9mmgD7z33nvq3r27rrjiCk2cOFGHDx9usXwonNv/+7//0zvvvKOHHnqo1bLBfG69QZDqYCoqKtTQ0KCkpCSn7UlJSSovL3e5T3l5ucvy9fX1qqio8Ftbfc0wDOXl5emGG25Q//79my2XkpKipUuXatWqVVq9erWuvPJK3XLLLfrXv/7Vjq313KBBg/T6669r/fr1eumll1ReXq4hQ4boyJEjLsuHynmVpLVr1+r48eN64IEHmi0TrOf1fPZ/p578G7bv5+k+HU1NTY2mTp2qe+65p8UH2vbp00fLli3TunXrtHz5csXExOj666/X/v3727G13hk1apTeeOMN/fOf/9Tvf/97ffTRR7r55ptVW1vb7D6hcG5fe+01xcXF6Y477mixXDCfW29FBboBcO38v9oNw2jxL3lX5V1t78geffRRffLJJ9qyZUuL5a688kpdeeWVjteZmZk6ePCgnn/+ed14443+bqbXRo0a5fj+qquuUmZmpnr37q3XXntNeXl5LvcJhfMqSQUFBRo1apRSU1ObLROs57U5nv4b9nafjsJqtequu+6SzWbTokWLWiw7ePBgpwna119/va655hr96U9/0osvvujvprZJdna24/v+/ftr4MCB6tWrl955550WQ0Ywn1tJeuWVV/TTn/601blOwXxuvcWIVAfTrVs3RUZGNvlL5fDhw03+orFLTk52WT4qKkpdu3b1W1t96Ze//KXWrVund999VxdffLHH+w8ePDjo/uLp3LmzrrrqqmbbHQrnVZK+/vprbdy4URMmTPB432A8r/Y7MT35N2zfz9N9Ogqr1arx48ertLRURUVFLY5GuRIREaFrr7026M611DiS2qtXrxbbHsznVpI2b96sffv2efVvOJjPrbsIUh1MdHS0MjIyHHc42RUVFWnIkCEu98nMzGxSfsOGDRo4cKDMZrPf2uoLhmHo0Ucf1erVq/XPf/5TaWlpXtVTUlKilJQUH7fOv2pra7V3795m2x3M5/Vcr776qrp3764f/ehHHu8bjOc1LS1NycnJTueurq5OmzZtavbfsNT8+W5pn47AHqL279+vjRs3ehXyDcPQzp07g+5cS9KRI0d08ODBFtserOfWrqCgQBkZGRowYIDH+wbzuXVboGa5o3krVqwwzGazUVBQYOzZs8eYPHmy0blzZ+Orr74yDMMwpk6dauTk5DjKf/nll0ZsbKwxZcoUY8+ePUZBQYFhNpuNt956K1BdcNsjjzxixMfHG++9955RVlbm+KqurnaUOb+/f/jDH4w1a9YYX3zxhfHpp58aU6dONSQZq1atCkQX3PbEE08Y7733nvHll18aH3zwgfHjH//YiIuLC8nzatfQ0GD07NnTePrpp5u8F8zn9cSJE0ZJSYlRUlJiSDJeeOEFo6SkxHGn2rx584z4+Hhj9erVxu7du427777bSElJMaqqqhx15OTkON2J+/777xuRkZHGvHnzjL179xrz5s0zoqKijA8++KDd+3eulvpqtVqN2267zbj44ouNnTt3Ov0brq2tddRxfl9nz55t/OMf/zD+/e9/GyUlJcbPfvYzIyoqyti2bVsguuikpf6eOHHCeOKJJ4ytW7capaWlxrvvvmtkZmYa3/ve90Lu3NpVVlYasbGxxuLFi13WEUzn1l8IUh3UwoULjV69ehnR0dHGNddc47QcwP33328MGzbMqfx7771nXH311UZ0dLRxySWXNPtD39FIcvn16quvOsqc39/58+cbvXv3NmJiYozExETjhhtuMN555532b7yHsrOzjZSUFMNsNhupqanGHXfcYXz22WeO90PpvNqtX7/ekGTs27evyXvBfF7tSzWc/3X//fcbhtG4BMKsWbOM5ORkw2KxGDfeeKOxe/dupzqGDRvmKG/35ptvGldeeaVhNpuNPn36dIgQ2VJfS0tLm/03/O677zrqOL+vkydPNnr27GlER0cbF110kZGVlWVs3bq1/TvnQkv9ra6uNrKysoyLLrrIMJvNRs+ePY3777/fOHDggFMdoXBu7f785z8bnTp1Mo4fP+6yjmA6t/5iMowzs1cBAADgEeZIAQAAeIkgBQAA4CWCFAAAgJcIUgAAAF4iSAEAAHiJIAUAAOAlghQAAICXCFIAAABeIkgBQDsymUxau3ZtoJsBwEcIUgDCxgMPPCCTydTka+TIkYFuGoAgFRXoBgBAexo5cqReffVVp20WiyVArQEQ7BiRAhBWLBaLkpOTnb4SExMlNV52W7x4sUaNGqVOnTopLS1Nb775ptP+u3fv1s0336xOnTqpa9eu+vnPf66TJ086lXnllVfUr18/WSwWpaSk6NFHH3V6v6KiQj/5yU8UGxuryy+/XOvWrfNvpwH4DUEKAM4xc+ZMjR07Vrt27dK9996ru+++W3v37pUkVVdXa+TIkUpMTNRHH32kN998Uxs3bnQKSosXL9YvfvEL/fznP9fu3bu1bt06XXbZZU7HmDNnjsaPH69PPvlEo0eP1k9/+lMdPXq0XfsJwEcMAAgT999/vxEZGWl07tzZ6evZZ581DMMwJBmTJk1y2mfQoEHGI488YhiGYSxdutRITEw0Tp486Xj/nXfeMSIiIozy8nLDMAwjNTXVmD59erNtkGTMmDHD8frkyZOGyWQy/v73v/usnwDaD3OkAISVH/7wh1q8eLHTtgsvvNDxfWZmptN7mZmZ2rlzpyRp7969GjBggDp37ux4//rrr5fNZtO+fftkMpl06NAh3XLLLS224fvf/77j+86dOysuLk6HDx/2tksAAoggBSCsdO7cucmlttaYTCZJkmEYju9dlenUqZNb9ZnN5ib72mw2j9oEoGNgjhQAnOODDz5o8rpPnz6SpPT0dO3cuVOnTp1yvP/+++8rIiJCV1xxheLi4nTJJZfo//2//9eubQYQOIxIAQgrtbW1Ki8vd9oWFRWlbt26SZLefPNNDRw4UDfccIPeeOMNffjhhyooKJAk/fSnP9WsWbN0//33a/bs2fruu+/0y1/+Ujk5OUpKSpIkzZ49W5MmTVL37t01atQonThxQu+//75++ctftm9HAbQLghSAsPKPf/xDKSkpTtuuvPJKff7555Ia76hbsWKFcnNzlZycrDfeeEPp6emSpNjYWK1fv16PP/64rr32WsXGxmrs2LF64YUXHHXdf//9qqmp0R/+8Af96le/Urdu3TRu3Lj26yCAdmUyDMMIdCMAoCMwmUxas2aNbr/99kA3BUCQYI4UAACAlwhSAAAAXmKOFACcwUwHAJ5iRAoAAMBLBCkAAAAvEaQAAAC8RJACAADwEkEKAADASwQpAAAALxGkAAAAvESQAgAA8NL/D3qRss4b1+VXAAAAAElFTkSuQmCC",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.plot(history.history[\"loss\"], \"o-\", label = \"Training Loss\")\n",
"plt.xlabel(\"Epoch\")\n",
"# plt.yscale('log')\n",
"plt.ylabel(\"Loss (Huber)\")\n",
"plt.grid('on')\n",
"\n",
"plt.savefig(\"loss_all.png\", dpi=300)\n"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.plot(history.history[\"loss\"][1:], \"o-\", label = \"Training Loss\")\n",
"plt.xlabel(\"Epoch\")\n",
"# plt.yscale('log')\n",
"plt.ylabel(\"Loss (Huber)\")\n",
"plt.grid('on')\n",
"plt.savefig(\"loss_1_to_end.png\", dpi=300)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Test the model"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[1m 20/7821\u001b[0m \u001b[37m━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[1m44s\u001b[0m 6ms/step - loss: 5.1914e-06"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[1m7821/7821\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m29s\u001b[0m 4ms/step - loss: 1.0395e-06\n"
]
},
{
"data": {
"text/plain": [
"9.875676596493577e-07"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# test on all test data\n",
"model_large.evaluate(X_test.iloc[:,X_test.columns != \"Class\"], y_test.iloc[:, y_test.columns != \"Class\"])"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[1m7727/7727\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m29s\u001b[0m 4ms/step - loss: 5.4493e-07\n"
]
},
{
"data": {
"text/plain": [
"5.075861508885282e-07"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# test on non-reactive data\n",
"model_large.evaluate(X_test[X_test['Class'] == 0].iloc[:,:-1], y_test[X_test['Class'] == 0].iloc[:,:-1])"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[1m94/94\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 4ms/step - loss: 4.0710e-05\n"
]
}
],
"source": [
"mass_balance = mass_balance(model_simple, X_test, scaler_X, func_dict_in, func_dict_out)"
]
},
{
"cell_type": "code",
"execution_count": 116,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"4.047931361128576e-05"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# test on reactive data\n",
"model_large.evaluate(X_test[X_test['Class'] == 1].iloc[:,:-1], y_test[X_test['Class'] == 1].iloc[:, :-1])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Save the model"
]
},
{
"cell_type": "code",
"execution_count": 53,
"metadata": {},
"outputs": [],
"source": [
"# Save the model\n",
"model.save(\"Barite_50_Model_additional_species.keras\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Legacy Code"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"def log_scale(df_design, df_result, func_dict):\n",
" \n",
" df_design = df_design.copy()\n",
" df_result = df_result.copy()\n",
" \n",
" for key in df_design.keys():\n",
" if key != \"Class\":\n",
" df_design[key] = np.vectorize(func_dict[key])(df_design[key])\n",
" df_result[key] = np.vectorize(func_dict[key])(df_result[key])\n",
" \n",
" return df_design, df_result\n",
"\n",
"# Get minimum and maximum values for each column\n",
"def get_min_max(df_design, df_result):\n",
" \n",
" min_vals_des = df_design.min()\n",
" max_vals_des = df_design.max()\n",
" \n",
" min_vals_res = df_result.min()\n",
" max_vals_res = df_result.max()\n",
"\n",
" # minimum of input and output data to get global minimum/maximum\n",
" data_min = np.minimum(min_vals_des, min_vals_res).to_dict()\n",
" data_max = np.maximum(max_vals_des, max_vals_res).to_dict()\n",
"\n",
" return data_min, data_max\n",
"\n",
"df_design_log, df_results_log = log_scale(df_design, df_results, func_dict_in)\n",
"data_min_log, data_max_log = get_min_max(df_design_log, df_design_log)\n",
"\n",
"train_min_log, train_max_log = get_min_max(X_train_log, y_train_log)\n",
"test_min_log, test_max_log = get_min_max(X_test_log, y_test_log)\n",
"\n",
"X_train_preprocess = preprocess(X_train_log, func_dict_in, train_min_log, train_max_log)\n",
"y_train_preprocess = preprocess(y_train_log, func_dict_in, train_min_log, train_max_log)\n",
"\n",
"X_test_preprocess = preprocess(X_test_log, func_dict_in, test_min_log, test_max_log)\n",
"y_test_preprocess = preprocess(y_test_log, func_dict_in, test_min_log, test_max_log)\n",
"\n",
"X_train_log, y_train_log = log_scale(X_train, y_train, func_dict_in)\n",
"X_test_log, y_test_log = log_scale(X_test, y_test, func_dict_in)\n",
"\n",
"\n",
"def preprocess(data, func_dict, data_min, data_max):\n",
" data = data.copy()\n",
" for key in data.keys():\n",
" if key != \"Class\":\n",
" data[key] = (data[key] - data_min[key]) / (data_max[key] - data_min[key])\n",
"\n",
" return data\n",
"\n",
"def postprocess(data, func_dict, data_min, data_max):\n",
" data = data.copy()\n",
" for key in data.keys():\n",
" if key != \"Class\":\n",
" data[key] = data[key] * (data_max[key] - data_min[key]) + data_min[key]\n",
" data[key] = np.vectorize(func_dict[key])(data[key])\n",
" return data\n",
"\n",
"X_train, X_val, y_train, y_val = sk.train_test_split(X_train_preprocess, y_train_preprocess, test_size = 0.1)\n",
"\n",
"pp_design = preprocess(df_design_log, func_dict_in, data_min_log, data_max_log)\n",
"pp_results = preprocess(df_results_log, func_dict_in, data_min_log, data_max_log)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "ai",
"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.8"
}
},
"nbformat": 4,
"nbformat_minor": 2
}