text_html_output_1.png
from sklearn.impute import SimpleImputer

from sklearn.preprocessing import OneHotEncoder

from torch import nn

from torch.utils.data import DataLoader, TensorDataset, SubsetRandomSampler

import numpy as np

import pandas as pd

import random

import torch

import pandas as pd
import numpy as np
import torch
from torch import nn
import matplotlib.pyplot as plt
from torch.utils.data import DataLoader, TensorDataset, SubsetRandomSampler
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import OneHotEncoder
import random
random.seed(1)
torch.manual_seed(1)
np.random.seed(1)
rng = np.random.default_rng(1)

def load_data(train_path, test_path):
    train_data = pd.read_csv(train_path)
    test_data = pd.read_csv(test_path)
    return (train_data, test_data)
def describe_unique_dataset(df: pd.DataFrame, show_values=False):
    nunique = {}
    unique = {}
    nan = {}
    for col in df.columns:
        nunique[col] = df[col].nunique()
        unique[col] = df[col].unique()
        nan[col] = df[col].isna().sum()
    [print(f'{item} : {nunique[item]}') for item in nunique.keys()]
    [print(f'{item} : {nan[item]}') for item in nan.keys()]
    if show_values == True:
        [print(f'{item} : {unique[item]}') for item in unique.keys()]

def impute(data):
    data_c = data.copy()
    s_imputer = SimpleImputer(strategy='most_frequent')
    data_c['Embarked'] = s_imputer.fit_transform(np.array(data_c['Embarked']).reshape(-1, 1))
    data_c['Age'] = data_c.groupby(['Pclass', 'Embarked', 'Sex'])['Age'].transform(lambda x: x.fillna(x.mean()))
    data_c['Fare'] = data_c.groupby(['Pclass', 'Embarked', 'Sex'])['Fare'].transform(lambda x: x.fillna(x.mean()))
    return data_c
def ohe_data(data: pd.DataFrame, cat_name):
    data_c = data.copy()
    oh_encoder = OneHotEncoder(sparse=False)
    transformed_data = oh_encoder.fit_transform(np.array(data_c[cat_name]).reshape(-1, 1))
    df_transformed_data = pd.DataFrame(transformed_data)
    df_transformed_data.columns = oh_encoder.get_feature_names_out(input_features=[cat_name])
    data_c[df_transformed_data.columns] = transformed_data
    return data_c
def encode(data: pd.DataFrame):
    data_c = data.copy()
    data_c = ohe_data(data_c, 'Embarked')
    data_c = ohe_data(data_c, 'Sex')
    data_c['Pclass'].replace({3: 1, 1: 3}, inplace=True)
    for col in data_c.select_dtypes('object'):
        data_c[col], _ = data_c[col].factorize()
    return data_c
def feature_extraction(data: pd.DataFrame):
    data_c = data.copy()
    data_c['TicketNr'] = data_c['Ticket'].str.extract('(\\d+)$', expand=True).astype(np.float32)
    data_c['TicketNr'].fillna(0, inplace=True)
    name_extraction = data_c['Name'].str.extract('^(\\w+)..(\\w+)\\W+(\\w+\\s*\\w+)', expand=True)
    name_extraction.columns = ['LastName', 'Hon', 'FirstName']
    data_c[name_extraction.columns] = name_extraction
    return data_c
def split_train_test_indices(data_length, ratio):
    r_num = int(data_length * ratio)
    indices = np.random.permutation(data_length)
    return (indices[:r_num], indices[r_num:])
def load_data(train_path, test_path):
    train_data = pd.read_csv(train_path, index_col='PassengerId')
    test_data = pd.read_csv(test_path, index_col='PassengerId')
    return (train_data, test_data)

train_data, test_data = load_data('../input/titanic/train.csv', '../input/titanic/test.csv')
dataset = pd.concat([train_data, test_data])
dataset = impute(dataset)
dataset = feature_extraction(dataset)
dataset = encode(dataset)
dataset.drop(columns=['Name', 'Sex', 'Ticket', 'Cabin', 'Embarked'], inplace=True)
dataset = dataset.astype(np.float32)
train_data = dataset.loc[train_data.index, :]
test_data = dataset.loc[test_data.index, :]
test_data.drop(columns=['Survived'], inplace=True)
train_indices, valid_indices = split_train_test_indices(len(train_data), 0.8)
y = train_data.pop('Survived')
X = train_data
t_train_data = TensorDataset(torch.Tensor(X.to_numpy()), torch.Tensor(y.to_numpy().reshape(-1, 1)))
t_test_data = torch.Tensor(test_data.to_numpy())

class BinaryLogisticNetwork(nn.Module):
    def __init__(self, input_size):
        super(BinaryLogisticNetwork, self).__init__()
        self.input_size = input_size
        self.binary_logistic = nn.Sequential(nn.BatchNorm1d(input_size), nn.Linear(input_size, 2048), nn.ReLU(), nn.Dropout(0.2), nn.BatchNorm1d(2048), nn.Linear(2048, 2048), nn.ReLU(), nn.Dropout(0.2), nn.BatchNorm1d(2048), nn.Linear(2048, 2048), nn.ReLU(), nn.Dropout(0.2), nn.BatchNorm1d(2048), nn.Linear(2048, 2048), nn.ReLU(), nn.Dropout(0.2), nn.BatchNorm1d(2048), nn.Linear(2048, 2048), nn.ReLU(), nn.Dropout(0.2), nn.BatchNorm1d(2048), nn.Linear(2048, 2048), nn.ReLU(), nn.Dropout(0.2), nn.Linear(2048, 1), nn.Sigmoid())
    def forward(self, x):
        out = self.binary_logistic(x)
        return out

def accuracy(y_preds, y_true):
    y_preds = torch.round(y_preds)
    return float((y_preds == y_true).sum().float() / y_preds.shape[0])

BATCH_SIZE = 32
EPOCHS = 20
train_sampler = SubsetRandomSampler(train_indices)
valid_sampler = SubsetRandomSampler(valid_indices)
g = torch.Generator()
g.manual_seed(1)
train_loader = DataLoader(t_train_data, BATCH_SIZE, sampler=train_sampler, worker_init_fn=1, generator=g)
valid_loader = DataLoader(t_train_data, BATCH_SIZE, sampler=valid_sampler, worker_init_fn=1, generator=g)
model = BinaryLogisticNetwork(len(X.columns))
loss_fn = nn.functional.binary_cross_entropy
optimizer = torch.optim.Adagrad(model.parameters(), lr=0.01, eps=0.01)

def evaluate(model, valid_dl, loss_fn, metric):
    losses = []
    val_accuracy = []
    with torch.no_grad():
        for x, y in valid_dl:
            preds = model(x)
            loss = loss_fn(preds, y)
            losses.append(loss.item())
            val_accuracy.append(metric(preds, y))
    return (sum(losses) / len(losses), sum(val_accuracy) / len(val_accuracy))
def fit(epochs, model, loss_fn, opt, train_dl, valid_dl, metric):
    history = {'Loss': [], 'Accuracy': [], 'Val_Loss': [], 'Val_Accuracy': []}
    scheduler = torch.optim.lr_scheduler.StepLR(opt, 30, gamma=0.01)
    for epoch in range(epochs):
        loss_list = []
        scores = []
        for count, (x, y) in enumerate(train_dl):
            preds = model(x)
            loss = loss_fn(preds, y)
            loss.backward()
            opt.step()
            opt.zero_grad()
            scheduler.step()
            score = accuracy(preds, y)
            loss_list.append(loss.item())
            scores.append(score)
        val_loss, val_accuracy = evaluate(model, valid_dl, loss_fn, metric)
        history['Loss'].append(sum(loss_list) / len(loss_list))
        history['Accuracy'].append(sum(scores) / len(scores))
        history['Val_Loss'].append(val_loss)
        history['Val_Accuracy'].append(val_accuracy)
    return history

history = fit(EPOCHS, model, loss_fn, optimizer, train_loader, valid_loader, accuracy)