"""
# import libraries
"""
import numpy as np 
import pandas as pd 
from collections import OrderedDict

import matplotlib.pyplot as plt

from sklearn import ensemble
from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import (RandomForestClassifier, AdaBoostClassifier, GradientBoostingClassifier, ExtraTreesClassifier)
from sklearn.svm import SVC

from sklearn.model_selection import KFold
import xgboost as xgb
from sklearn.datasets import make_classification
from sklearn.ensemble import RandomForestClassifier

from sklearn.model_selection import cross_val_score,cross_val_predict,cross_validate
from sklearn.metrics import confusion_matrix
from sklearn.metrics import precision_score, recall_score
from sklearn.metrics import f1_score
from sklearn.metrics import precision_recall_curve
from sklearn.metrics import roc_auc_score
from sklearn.metrics import roc_curve
"""
# common variables
"""
RANDOM_STATE = 42
min_estimators = 30
max_estimators = 100
"""
# load data
"""
train = pd.read_csv("../input/titanic/train.csv")
test = pd.read_csv("../input/titanic/test.csv")
"""
# preprocess
"""
#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)
"""
# split data
"""
y = train["Survived"]
X = train.drop(["Survived"], axis=1)
X_test = test
"""
# define element models
"""
rf1 = RandomForestClassifier(
            warm_start=True,
            oob_score=True,
            max_features='sqrt',
            random_state=RANDOM_STATE,
        )

rf2 =  RandomForestClassifier(
            warm_start=True,
            max_features='log2',
            oob_score=True,
            random_state=RANDOM_STATE,
        )

rf3 = RandomForestClassifier(
            warm_start=True,
            max_features=None,
            oob_score=True,
            random_state=RANDOM_STATE,
        )

rf4 = RandomForestClassifier(
            warm_start=True,
            max_features=0.5,
            oob_score=True,
            random_state=RANDOM_STATE,
        )

rf5 = RandomForestClassifier(
            warm_start=True,
            max_features=0.7,
            oob_score=True,
            random_state=RANDOM_STATE,
        )


ensemble_clfs = [("rf1",rf1),("rf2'",rf2),("rf3",rf3),("rf4",rf4),("rf5",rf5)]
error_rate = OrderedDict((label, []) for label, _ in ensemble_clfs)
error_rate
min_oob_error = 1.0
min_label = ""
min_index = 0
for label, clf in ensemble_clfs:
    for i in range(min_estimators, max_estimators + 1):
        clf.set_params(n_estimators=i)
        clf.fit(X, y)

        oob_error = 1 - clf.oob_score_
        error_rate[label].append((i, oob_error))
        
        if min_oob_error > oob_error:
            min_oob_error = oob_error
            min_label = label
            min_index = i
        
#         print("clf.oob_score_",clf.oob_score_)
#         print("oob_error",round(oob_error,3))
#         print("")
        
        
print("min_oob_error=",min_oob_error)
print("min_label=",min_label)
print("min_index=",min_index)
for label, clf_err in error_rate.items():
    xs, ys = zip(*clf_err)
    plt.plot(xs, ys, label=label)

plt.xlim(min_estimators, max_estimators)
plt.xlabel("n_estimators")
plt.ylabel("OOB error rate")
plt.legend(loc="upper right")
plt.show()
"""
# build model using best parameter 
"""
rf = RandomForestClassifier(
           n_estimators = 56,
            warm_start=True,
            max_features='sqrt',
            oob_score=True,
            random_state=RANDOM_STATE
)
rf.fit(X,y)
"""
# Evaluate Model
"""
y_train_pred = cross_val_predict(rf, X, y, cv=3)
print( confusion_matrix(y, y_train_pred) )

print("")

print("precision_score1:",precision_score(y, y_train_pred) )
cm = confusion_matrix(y, y_train_pred)
print("precision_score2:",cm[1, 1] / (cm[0, 1] + cm[1, 1]) )

print("")

print("recall_score1:",recall_score(y, y_train_pred))
print("recall_score2:",cm[1, 1] / (cm[1, 0] + cm[1, 1]) )

print("")

print("f1_score1:",f1_score(y, y_train_pred))
print("f1_score2:", cm[1, 1] / (cm[1, 1] + (cm[1, 0] + cm[0, 1]) / 2) )

print("")

print("roc_auc score",roc_auc_score(y, y_train_pred) )
"""
# predict test data using stacking one model
"""
predictions = rf.predict(X_test)
"""
# submission
"""
sub = pd.read_csv("../input/titanic/gender_submission.csv")
sub["Survived"] = predictions
sub.to_csv('submission.csv', index=False)
sub.head()