"""
# Before building model
### imports & variables 
"""
import numpy as np
import pandas as pd
import random 
import os 
import warnings
warnings.filterwarnings('ignore')

from sklearn.model_selection import train_test_split, StratifiedShuffleSplit

from xgboost import XGBClassifier
import optuna
from sklearn.metrics import roc_auc_score

TRAIN_PATH = "../input/titanic/train.csv"
TEST_PATH = "../input/titanic/test.csv"
SAMPLE_SUBMISSION_PATH = "../input/titanic/gender_submission.csv"
SUBMISSION_PATH = "submission.csv"

ID = "PassengerId"
TARGET = "Survived"

TEST_SIZE = 0.2

OPTUNA_TRIALS = 100
OPTUNA_ESR = 50
OPTUNA_DIRECTION = "maximize"

NFOLD = 100
TREE_METHOD = 'gpu_hist'
BOOSTER = "gbtree"

SEED = 2002
def seed_everything(seed=SEED):
    random.seed(seed)
    os.environ['PYTHONHASHSEED'] = str(seed)
    np.random.seed(seed)
    
seed_everything()
"""
## preprocess
"""
train = pd.read_csv(TRAIN_PATH)
test = pd.read_csv(TEST_PATH)

#1. delete unnecessary columns
drop_elements = ['PassengerId', 'Name', 'Ticket', 'Cabin', 'SibSp','Parch']
train = train.drop(drop_elements, axis = 1)
test = test.drop(drop_elements, axis = 1)

# #2.find null data and fill new data 
# def checkNull_fillData(df):
#     for col in df.columns:
#         if len(df.loc[df[col].isnull() == True]) != 0:
#             if df[col].dtype == "float64" or df[col].dtype == "int64":
#                 df.loc[df[col].isnull() == True,col] = df[col].mean()
#             else:
#                 df.loc[df[col].isnull() == True,col] = df[col].mode()[0]
                
# checkNull_fillData(train)
# checkNull_fillData(test)

#3.one hot encoding 
str_list = [] 
num_list = []
for colname, colvalue in train.iteritems():
    if type(colvalue[1]) == str:
        str_list.append(colname)
    else:
        num_list.append(colname)
        
train = pd.get_dummies(train, columns=str_list)
test = pd.get_dummies(test, columns=str_list)
"""
# Optuna : Search Best parameter
"""
# split data 
y = train[TARGET]
X = train.drop(columns=[TARGET])
X_test = test

# search best param

def objective(trial, data=X, target=y):
    
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=777, stratify=y) 
    params = {
        'objective': 'binary:logistic',
        'max_depth': trial.suggest_int('max_depth',1, 20),
        'eta': trial.suggest_float('eta', 1e-5, 0.1),
        'subsample': trial.suggest_discrete_uniform('subsample', 0.1, 0.9, 0.1),
        'colsample_bytree': trial.suggest_discrete_uniform('colsample_bytree', 0.1, 0.9, 0.1),
        'min_child_weight': trial.suggest_loguniform('min_child_weight', 1e-5, 1e5),
        'reg_lambda': trial.suggest_loguniform('reg_lambda', 1e-5, 1e5),
        'reg_alpha': trial.suggest_loguniform('reg_alpha', 1e-5, 1e5),
        'gamma': trial.suggest_loguniform('gamma', 1e-5, 1e5),
        'predictor': "gpu_predictor",
        'eval_metric': 'auc'
    }
    
    model = XGBClassifier(**params,
                         tree_method=TREE_METHOD, 
                         booster=BOOSTER,
                         random_state=SEED)
    model.fit(X_train, y_train, eval_set=[(X_test, y_test)], early_stopping_rounds=OPTUNA_ESR, verbose=False)
    preds = model.predict(X_test)
    score = roc_auc_score(y_test, preds)
    
    return score

study = optuna.create_study(direction=OPTUNA_DIRECTION)
study.optimize(objective, n_trials=OPTUNA_TRIALS)
print('Number of finished trials:', len(study.trials))
print('Best trial:', study.best_trial.params)

params=study.best_params
print(params)
"""
# Build Best Model & OOF prediction 
"""
# import module we'll need to import our custom module
from shutil import copyfile

# copy our file into the working directory (make sure it has .py suffix)
copyfile(src = "../input/stratified-shuffle-split-oof-py/function_stratifiedshufflesplit_oof.py", dst = "../working/function_stratifiedshufflesplit_oof.py")

from function_stratifiedshufflesplit_oof import *
model = XGBClassifier(**params,tree_method=TREE_METHOD,booster=BOOSTER,)
preds = stratifiedShuffleSplitOOF(5,X,y,X_test,model,roc_auc_score)
"""
# submit 
"""
sub = pd.read_csv(SAMPLE_SUBMISSION_PATH)
sub[TARGET] = preds.astype(int)
sub.to_csv(SUBMISSION_PATH, index=False)
sub.head()