#!/usr/bin/env python
# coding: utf-8


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import tensorflow as tf

from utils.preprocessing import data_formatting
from utils.setup import df_config
from sklearn.preprocessing import StandardScaler
from tensorflow import keras


# Load dataset from .dat
df = pd.read_csv("automobile\src\data\imports-85.data", names=df_config["head"])

# Set target feature:
# target: str = "fuel-type"
target: str = "city-mpg"

# Set features to be processed:
features: list = [
    "wheel-base",
    "length",
    "width",
    "height",
    "curb-weight",
    "engine-size",
    # "compression-ratio",
    # "price",
    # "horsepower",
    # "peak-rpm",
    "fuel-type",
]

# Format the dataset: Splitting into completely existend dataframe
# (used for modeling) and dataframe with missing values (used for evaluation)
X, y = data_formatting(df, target, features)
gas = np.where(X[:, -1] == 1)[0]
diesel = np.where(X[:, -1] == 0)[0]

X = X[:, :-1]
X = StandardScaler().fit_transform(X)

dropout_factor = 0.1

model = keras.models.Sequential()
model.add(
    keras.layers.Dense(
        128,
        activation="elu",
        input_shape=(6,),
        kernel_initializer="he_normal",
        kernel_regularizer=keras.regularizers.l2(0.01),
    )
)
tf.keras.layers.Dropout(dropout_factor)
model.add(
    keras.layers.Dense(
        128,
        activation="elu",
        kernel_initializer="he_normal",
        kernel_regularizer=keras.regularizers.l2(0.01),
    )
)
tf.keras.layers.Dropout(dropout_factor)
model.add(
    keras.layers.Dense(
        128,
        activation="elu",
        kernel_initializer="he_normal",
        kernel_regularizer=keras.regularizers.l2(0.01),
    )
)
tf.keras.layers.Dropout(dropout_factor)
model.add(
    keras.layers.Dense(
        128,
        activation="elu",
        kernel_initializer="he_normal",
        kernel_regularizer=keras.regularizers.l2(0.01),
    )
)
tf.keras.layers.Dropout(dropout_factor)
model.add(
    keras.layers.Dense(
        128,
        activation="elu",
        kernel_initializer="he_normal",
        kernel_regularizer=keras.regularizers.l2(0.01),
    )
)
tf.keras.layers.Dropout(dropout_factor)
model.add(
    keras.layers.Dense(
        128,
        activation="elu",
        kernel_initializer="he_normal",
        kernel_regularizer=keras.regularizers.l2(0.01),
    )
)
tf.keras.layers.Dropout(dropout_factor)
model.add(
    keras.layers.Dense(
        128,
        activation="elu",
        kernel_initializer="he_normal",
        kernel_regularizer=keras.regularizers.l2(0.01),
    )
)
model.add(keras.layers.Dense(1))

batch_size = 16
epochs = 250

# initial_learning_rate = 0.05
# lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay(
#     initial_learning_rate,
#     decay_steps=100,
#     decay_rate=0.90)
#     # staircase=True)

# Exponential LR decay


def exponential_decay(lr0, s):
    def exponential_decay_fn(epoch):
        return lr0 * 0.1 ** (epoch / s)

    return exponential_decay_fn


exponential_decay_fn = exponential_decay(lr0=0.05, s=150)
lr_scheduler = keras.callbacks.LearningRateScheduler(exponential_decay_fn)

es = tf.keras.callbacks.EarlyStopping(
    monitor="val_loss", mode="auto", verbose=1, patience=10
)

opt = keras.optimizers.Adam()  # learning_rate=lr_schedule)
model.compile(optimizer=opt, loss=tf.keras.losses.log_cosh, metrics=["MAE"])
hist = model.fit(
    X,
    y,
    batch_size=batch_size,
    epochs=epochs,
    validation_split=0.1,
    callbacks=[lr_scheduler, es],
)

opt = keras.optimizers.Adam(learning_rate=0.0001)
model.compile(optimizer=opt, loss=tf.keras.losses.log_cosh, metrics=["MAE"])
hist = model.fit(
    X, y, batch_size=batch_size, epochs=epochs, validation_split=0.1, callbacks=[es]
)

predData_gas = model.predict(X[gas, :])

plt.figure()
plt.scatter(np.linspace(0, gas.shape[0], gas.shape[0]), y[gas], label="Actual")
plt.scatter(
    np.linspace(0, gas.shape[0], gas.shape[0]), predData_gas, label="Prediction"
)
plt.title("Gas")
plt.legend()

predData_diesel = model.predict(X[diesel, :])

plt.figure()
plt.scatter(np.linspace(0, diesel.shape[0], diesel.shape[0]), y[diesel], label="Actual")
plt.scatter(
    np.linspace(0, diesel.shape[0], diesel.shape[0]),
    predData_diesel,
    label="Prediction",
)
plt.title("Diesel")
plt.legend()

diff1 = np.abs(predData_gas[:, 0] - y[gas])
diff2 = np.abs(predData_diesel[:, 0] - y[diesel])

tol = 2
print("gas: ", np.sum(diff1 < tol) / 1.83)
print("diesel: ", np.sum(diff2 < tol) / 0.2)

#!/usr/bin/env python
# coding: utf-8


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import tensorflow as tf

from utils.preprocessing import data_formatting
from utils.setup import df_config
from sklearn.preprocessing import StandardScaler
from tensorflow import keras


# Load dataset from .dat
df = pd.read_csv("automobile\src\data\imports-85.data", names=df_config["head"])

# Set target feature:
# target: str = "fuel-type"
target: str = "city-mpg"

# Set features to be processed:
features: list = [
    "wheel-base",
    "length",
    "width",
    "height",
    "curb-weight",
    "engine-size",
    # "compression-ratio",
    # "price",
    # "horsepower",
    # "peak-rpm",
    "fuel-type",
]

# Format the dataset: Splitting into completely existend dataframe
# (used for modeling) and dataframe with missing values (used for evaluation)
X, y = data_formatting(df, target, features)
gas = np.where(X[:, -1] == 1)[0]
diesel = np.where(X[:, -1] == 0)[0]

X = X[:, :-1]
X = StandardScaler().fit_transform(X)

dropout_factor = 0.1

model = keras.models.Sequential()
model.add(
    keras.layers.Dense(
        128,
        activation="elu",
        input_shape=(6,),
        kernel_initializer="he_normal",
        kernel_regularizer=keras.regularizers.l2(0.01),
    )
)
tf.keras.layers.Dropout(dropout_factor)
model.add(
    keras.layers.Dense(
        128,
        activation="elu",
        kernel_initializer="he_normal",
        kernel_regularizer=keras.regularizers.l2(0.01),
    )
)
tf.keras.layers.Dropout(dropout_factor)
model.add(
    keras.layers.Dense(
        128,
        activation="elu",
        kernel_initializer="he_normal",
        kernel_regularizer=keras.regularizers.l2(0.01),
    )
)
tf.keras.layers.Dropout(dropout_factor)
model.add(
    keras.layers.Dense(
        128,
        activation="elu",
        kernel_initializer="he_normal",
        kernel_regularizer=keras.regularizers.l2(0.01),
    )
)
tf.keras.layers.Dropout(dropout_factor)
model.add(
    keras.layers.Dense(
        128,
        activation="elu",
        kernel_initializer="he_normal",
        kernel_regularizer=keras.regularizers.l2(0.01),
    )
)
tf.keras.layers.Dropout(dropout_factor)
model.add(
    keras.layers.Dense(
        128,
        activation="elu",
        kernel_initializer="he_normal",
        kernel_regularizer=keras.regularizers.l2(0.01),
    )
)
tf.keras.layers.Dropout(dropout_factor)
model.add(
    keras.layers.Dense(
        128,
        activation="elu",
        kernel_initializer="he_normal",
        kernel_regularizer=keras.regularizers.l2(0.01),
    )
)
model.add(keras.layers.Dense(1))

batch_size = 16
epochs = 250

# initial_learning_rate = 0.05
# lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay(
#     initial_learning_rate,
#     decay_steps=100,
#     decay_rate=0.90)
#     # staircase=True)

# Exponential LR decay


def exponential_decay(lr0, s):
    def exponential_decay_fn(epoch):
        return lr0 * 0.1 ** (epoch / s)

    return exponential_decay_fn


exponential_decay_fn = exponential_decay(lr0=0.05, s=150)
lr_scheduler = keras.callbacks.LearningRateScheduler(exponential_decay_fn)

es = tf.keras.callbacks.EarlyStopping(
    monitor="val_loss", mode="auto", verbose=1, patience=10
)

opt = keras.optimizers.Adam()  # learning_rate=lr_schedule)
model.compile(optimizer=opt, loss=tf.keras.losses.log_cosh, metrics=["MAE"])
hist = model.fit(
    X,
    y,
    batch_size=batch_size,
    epochs=epochs,
    validation_split=0.1,
    callbacks=[lr_scheduler, es],
)

opt = keras.optimizers.Adam(learning_rate=0.0001)
model.compile(optimizer=opt, loss=tf.keras.losses.log_cosh, metrics=["MAE"])
hist = model.fit(
    X, y, batch_size=batch_size, epochs=epochs, validation_split=0.1, callbacks=[es]
)

predData_gas = model.predict(X[gas, :])

plt.figure()
plt.scatter(np.linspace(0, gas.shape[0], gas.shape[0]), y[gas], label="Actual")
plt.scatter(
    np.linspace(0, gas.shape[0], gas.shape[0]), predData_gas, label="Prediction"
)
plt.title("Gas")
plt.legend()

predData_diesel = model.predict(X[diesel, :])

plt.figure()
plt.scatter(np.linspace(0, diesel.shape[0], diesel.shape[0]), y[diesel], label="Actual")
plt.scatter(
    np.linspace(0, diesel.shape[0], diesel.shape[0]),
    predData_diesel,
    label="Prediction",
)
plt.title("Diesel")
plt.legend()

diff1 = np.abs(predData_gas[:, 0] - y[gas])
diff2 = np.abs(predData_diesel[:, 0] - y[diesel])

tol = 2
print("gas: ", np.sum(diff1 < tol) / 1.83)
print("diesel: ", np.sum(diff2 < tol) / 0.2)

#!/usr/bin/env python # coding: utf-8 # Load dataset from .dat # Set target feature: # target: str = "fuel-type" # Set features to be processed: # "compression-ratio", # "price", # "horsepower", # "peak-rpm", # Format the dataset: Splitting into completely existend dataframe # (used for modeling) and dataframe with missing values (used for evaluation) # initial_learning_rate = 0.05 # lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay( #     initial_learning_rate, #     decay_steps=100, #     decay_rate=0.90) #     # staircase=True) # Exponential LR decay # learning_rate=lr_schedule)