# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# # Aujourd'hui on voit notre classement
#
#
# https://challengedata.ens.fr/en/challenge/39/prediction_of_transaction_claims_status.html

# # Imports des librairies de bases
#
# On ajoutera celles qui manquent au fur et à mesure de nos besoins

# +
# To support both python 2 and python 3
from __future__ import division, print_function, unicode_literals

# Common imports
import numpy as np
import pandas as pd
import os, gc
# -

# # Définition de la seed pour le random
#
# Très important pour qu'on voit les mêmes choses entre nos deux ordis

RANDOM_SEED = 42;
np.random.seed(RANDOM_SEED)

# # Définition des paramètres pour Matplot
#
# Rien de bien intéréssant

# To plot pretty figures
# %matplotlib inline
import matplotlib
import matplotlib.pyplot as plt
plt.rcParams['axes.labelsize'] = 14
plt.rcParams['xtick.labelsize'] = 12
plt.rcParams['ytick.labelsize'] = 12

# # Set des variables globales
#
# Attention, je n'utilise les variables globales pour la gestion des fichiers. Sinon, c'est mort

# Where to save the figures
PROJECT_ROOT_DIR = "."
DATA_PROCESSED = os.path.join(PROJECT_ROOT_DIR, "data_processed")


# # Fonction pour load les libraires
#
# En vrai, on a juste besoin de pd.read_csv, mais c'était pour faire joli

def load_data(file,data_path=DATA_PROCESSED, sep=';'):
    csv_path = os.path.join(data_path, file)
    return pd.read_csv(csv_path, sep=';')


# # On load les jeux de données

TX_data = load_data(file = "train.csv");
TEST_DATA = load_data(file = "test.csv");

RESULTS = pd.DataFrame({'ID' : []})
RESULTS["ID"]=TEST_DATA["ID"]

TEST_DATA.drop("ID", axis=1, inplace=True)

TX_data.info()


# # Jointure entre les X et Y

def datapreprocess(data):
    data=data.apply(pd.to_numeric, errors='ignore')
    
    # Y and X
    try :
        Y=data["CLAIM_TYPE"]
        X=data.drop("CLAIM_TYPE", axis=1,inplace=False)
    except:
        Y=0
        X=data
    # Exclude Objets
    X=X.select_dtypes(exclude=['object'])
    
    # Work on fare
    from sklearn.preprocessing import Imputer
    imp = Imputer(missing_values='NaN',strategy='median', axis=1)
    X=pd.DataFrame(imp.fit_transform(X),columns=X.columns.values)
 
    return X, Y


# +
X_train, Y_train = datapreprocess(TX_data)
TEST_DATA, _ = datapreprocess(TEST_DATA)

#del TX_data;
gc.collect()
# -

# # MODEL!

# ## XGBoost

# #### Core XGBoost Library VS scikit-learn API
#
# Models can be trained in two different ways:
#
# 1. Directly using the core library – this is closer to the implementation of the caret-package in R
# 2. Using the scikit-learn API – this means that the models are implemented in a way that lets the scikit package recognize it as one of it’s own models.
#
# Nous, on va travailler avec l'API de Sklearn, c'est pas optimisé mais plus simple. De toute façon, j'arrive pas à utiliser le Core, a cause des DMatrix qui veulent que des numerics en entrées
#
# Doc des paramètres: https://github.com/dmlc/xgboost/blob/master/doc/parameter.md
#
# Doc sur le tunning : https://www.analyticsvidhya.com/blog/2016/03/complete-guide-parameter-tuning-xgboost-with-codes-python/

from xgboost import XGBClassifier
from sklearn.utils.class_weight import compute_sample_weight

sample_weight_arr = compute_sample_weight(class_weight='balanced', y=Y_train)

# +
params_XGB={
# General Parameters -  the overall functioning
    'booster':'gbtree',
    'silent':0,
    'nthread':4,
    'n_estimators' : 500,
    
# Booster Parameters - the individual booster (tree/regression) at each step
    'learning_rate' : 0.02,
    'min_child_weight' : 1, #A smaller value is chosen because it is a highly imbalanced class problem and leaf nodes can have smaller size groups.
    'max_depth' : 4,
    #'max_leaf_nodes':None, #If this is defined, GBM will ignore max_depth.
    'gamma' : 0.4,
    'max_delta_step':1, #it might help in logistic regression when class is extremely imbalanced/ 1-10 might help control the update
    'subsample' : 0.8,
    'colsample_bytree' : 0.9,
    'colsample_bylevel':1, #default
    'reg_lambda' : 1, #default
    'reg_alpha':0.05,
    'scale_pos_weight' : sample_weight_arr,

# Learning Task Parameters -  the optimization performed
    #'objective' : ['rank:pairwise','multi:softmax'], # you also need to set an additional num_class (number of classes)
    'objective' :['reg:gamma', 'rank:pairwise','multi:softmax'],
    'num_class' : len(Y_train.unique()),
    'eval_metric':["mlogloss", 'auc'],
    'seed' : RANDOM_SEED,
    'random_state':RANDOM_SEED
}
# -



xgb_clf = XGBClassifier(**params_XGB)

xgb_clf.fit(
    X=X_train, 
    y=Y_train, 
    sample_weight=sample_weight_arr, 
    eval_set=None, 
    eval_metric='auc', 
    early_stopping_rounds=None, 
    verbose=True, 
    xgb_model=None
)

y_pred_gb = xgb_clf.predict(TEST_DATA)

RESULTS["CLAIM_TYPE"] = pd.DataFrame(y_pred_gb)

RESULTS.head()

# +
filename = DATA_PROCESSED+"/submission_XBG_5.csv"

RESULTS.to_csv(filename, index=False, sep=";")

StarcoderdataJupyterScriptsDedupFiltered