# ---
# 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
# ---

# ### <NAME> - TITANIC

# <NAME>

# +
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

import scipy.stats as stats

from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
# -

data = pd.read_csv('train.csv')
data.head()

print(str(data.shape))

# +
#data['Sex'].unique()
# -

#Eliminamos el id de pasajero ya que solo es ruido en la data
data.drop('PassengerId', axis=1, inplace=True)
data.drop('Name', axis=1, inplace=True)

print(str(data.shape))

# ### Analisis de Datos

## Analisis de la data
data.describe()

data.dtypes

var_with_na = [var for var in data.columns if(data[var].isnull().sum() > 0)]
len(var_with_na)

data[var_with_na].isnull().mean().sort_values(ascending=False)

data[var_with_na].isnull().mean().sort_values(ascending=False).plot.bar()
plt.ylabel("Porcentaje de NAs")
plt.axhline(y=0.9, color="r")
plt.axhline(y=0.75, color="g")


def na_impact_over_target(df, Xvar, Yvar):
    df = data.copy()
    df[Xvar] = np.where(df[Xvar].isnull(), 1, 0)
    temp = df.groupby(Xvar)[Yvar].agg(['mean', 'std'])
    temp.plot(kind="barh", y="mean", xerr="std", legend=False, title=Yvar)
    plt.show()


for var in var_with_na:
    na_impact_over_target(data, var, 'Survived')

# ### Transformacion de Variables

X_train, X_test, y_train, y_test = train_test_split(
                        data.drop(['Survived'], axis=1),
                        data['Survived'],
                        test_size=0.2,
                        random_state=2021)

X_train.shape, X_test.shape

# ### Variables Categoricas

cat_vars = [var for var in data.columns if data[var].dtype == 'O']
cat_vars = cat_vars + ['Pclass']
cat_vars

X_train[cat_vars] = X_train[cat_vars].astype('O')
X_test[cat_vars] = X_test[cat_vars].astype('O')

cat_vars_with_na = [var for var in cat_vars 
                        if X_train[var].isnull().sum() > 0]

# ## Variables Numericas

num_vars = [var for var in X_train.columns
               if var not in cat_vars and var != ('Survived', 'Pclass')]
num_vars

# # Tratamiento de Variables con NA

# ##### Variables Categoricas con NA

cat_vars_with_na

X_train[cat_vars_with_na].isnull().mean().sort_values(ascending = False)

# Vemos que la variable "Cabin" muestra que más de la mitad de los registros están en blanco, por lo que podemos descartar dicha variable (además que es una variable categórica).

# +
#data.drop('Cabin', axis=1, inplace=True)

# +
#variables tratadas con etiqueta de faltante por cantidad masiva de faltantes.
vars_with_missing_string = [var for var in cat_vars_with_na
                               if X_train[var].isnull().mean() > 0.2]

#variables tratadas con procedimiento por candiad adecuada de faltantes.
vars_freq_category = [var for var in cat_vars_with_na
                               if X_train[var].isnull().mean() <= 0.2]
# -

vars_with_missing_string

vars_freq_category

#Faltantes con etiqueta missing
X_train[vars_with_missing_string] = X_train[vars_with_missing_string].fillna('Missing')
X_test[vars_with_missing_string] = X_test[vars_with_missing_string].fillna('Missing')

for var in vars_freq_category:
    mode = X_train[var].mode()[0]
    
    X_train[var].fillna(mode, inplace=True)
    X_test[var].fillna(mode, inplace=True)
    
    print(var, "-------", mode)

X_train[cat_vars_with_na].isnull().mean().sort_values(ascending = False)

cat_vars_with_na = [var for var in cat_vars 
                        if X_train[var].isnull().sum() > 0]
cat_vars_with_na

# #### Variables Numericas con NA

##Numéricas con faltantes
num_vars_with_na = [var for var in num_vars
                       if X_train[var].isnull().sum() > 0]

X_train[num_vars_with_na].isnull().mean()

for var in num_vars_with_na:
    mean_val = X_train[var].mean()
    
    print(var, mean_val)
    
    X_train[var].fillna(mean_val, inplace=True)
    X_test[var].fillna(mean_val, inplace=True)

X_train[num_vars_with_na].isnull().mean()

# ### Transformacion Variable de Precio

#Aplicamos transformación logaritmica para el precio
#for var in ['Fare']:
 #   X_train[var] = np.log(X_train[var])
  #  X_test[var] = np.log(X_test[var])

# ### Codificacion Variables Categoricas

# +
sex_mapping = {'male':1, 'female':2}

var = 'Sex'

X_train[var] = X_train[var].map(sex_mapping)
X_test[var] = X_test[var].map(sex_mapping)
# -

# ### Codificacion Otras Variables

other_cat = ['Pclass'] + ['SibSp'] + ['Parch'] + ['Ticket'] + ['Embarked'] + ['Cabin']


#funcion para encontar etiquetas raras
def find_rare_labels_freq(df, var, rare_perc):
    temp = df.groupby(var)[var].count()/len(df)
    return temp[temp > rare_perc].index


for var in other_cat:
    freqValue = find_rare_labels_freq(X_train, var, 0.01)
    
    #print(var, '--------', freqValue)
    
    X_train[var] = np.where(X_train[var].isin(freqValue), X_train[var], 'Rare')
    X_test[var] = np.where(X_test[var].isin(freqValue), X_test[var], 'Rare')


def replace_category_vals(train, test, y_train, var, target):
    
    temp = pd.concat([train, y_train], axis=1) 
    order_labels = temp.groupby([var])[target].mean().sort_values().index
    
    ordinal_values = {k: i for i, k in enumerate(order_labels, 0)}
    
    print(var, ordinal_values)
    
    train[var] = train[var].map(ordinal_values)
    test[var] = test[var].map(ordinal_values)
    


for var in other_cat:
    replace_category_vals(X_train, X_test, y_train, var, 'Survived')


def analyse_other_cats(train, y_train, var):
    temp = pd.concat([train, y_train], axis=1)

    temp.groupby(var)['Survived'].median().plot.bar()
    plt.title(var)
    plt.ylabel('Survied')
    plt.show()


for var in other_cat:
    analyse_other_cats(X_train, y_train, var)

# # Construccion de Modelo

# ### Feature Scaling

# +
scaler = MinMaxScaler()

scaler.fit(X_train)

X_train = pd.DataFrame(
    scaler.transform(X_train),
    columns=X_train.columns
)


X_test = pd.DataFrame(
    scaler.transform(X_test),
    columns=X_test.columns
)
# -



# ## Seleccion de Variables

from sklearn.linear_model import Lasso
from sklearn.feature_selection import SelectFromModel

# +
#objeto selector de variables
sel_ = SelectFromModel(Lasso(alpha=0.001, random_state=0))

sel_.fit(X_train, y_train)
# -

sel_.get_support().sum()

selected_features = X_train.columns[(sel_.get_support())]

selected_features

# ### Entrenamiento del Modelo

X_train = X_train[selected_features]
X_test = X_test[selected_features]

# +
linear_model = Lasso(alpha=0.001, random_state=2022)

linear_model.fit(X_train, y_train)
# -

# ### Predicciones

from sklearn.metrics import mean_squared_error, r2_score

preds_train = linear_model.predict(X_train)

# +
#Resultados del Train
print("MSE de Entrenamiento: {}".format(mean_squared_error(np.exp(y_train), np.exp(preds_train))))

print("RMSE de Entrenamiento: {}".format(mean_squared_error(np.exp(y_train), 
                                                           np.exp(preds_train), squared=False)))

print("R2 de Entrenamiento: {}".format(r2_score(np.exp(y_train), np.exp(preds_train))))
# -

preds_test = linear_model.predict(X_test)

# +
#Resultados del Test
print("MSE de Entrenamiento: {}".format(mean_squared_error(np.exp(y_test), np.exp(preds_test))))

print("RMSE de Entrenamiento: {}".format(mean_squared_error(np.exp(y_test), 
                                                           np.exp(preds_test), squared=False)))

print("R2 de Entrenamiento: {}".format(r2_score(np.exp(y_test), np.exp(preds_test))))
# -

# ## 

# +
#import joblib

# +
#joblib.dump(linear_model, 'final_model/lasso_reg.joblib')
# -

# # PIPELINE

# +
from sklearn.pipeline import Pipeline

from feature_engine.imputation import(
    AddMissingIndicator,
    MeanMedianImputer,
    CategoricalImputer
)

from feature_engine.encoding import (
    RareLabelEncoder,
    OrdinalEncoder
)

from feature_engine.transformation import LogTransformer

from feature_engine.selection import DropFeatures
from feature_engine.wrappers import SklearnTransformerWrapper

#import my_preprocessors as mypp

# +
### Configuracion de Modelo Pipeline
# -

X_train.shape, X_test.shape

# ### Configuración del Machine Learning Pipeline

# +

#Mapeos de variables categoricas
SEX_MAPPINGS = {'male':1, 'female':2}

#Variables numéricas con NA
NUMERICAL_VARS_WITH_NA = ['Age']

DROP_FEATURES = ['PassengerId', 'Name']

#Variables seleccionadas según análisis de Lasso
FEATURES = ['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Cabin', 'Embarked']
# -



# +
titanic_pipeline = Pipeline([
    
    #3. Indicamos Faltante en variables numéricas para imputar
    ('missing_indicator', AddMissingIndicator(variables=NUMERICAL_VARS_WITH_NA)),
    
     #6. Drop de variables
    ('drop_features', DropFeatures(features_to_drop=DROP_FEATURES)),
    
 #=============== CODIFICACION DE VARIABLES CATEGORICAS ORDINALES ==============
    #('mapper_quality', Mapper(
     #   variables=QUAL_VARS, mappings=QUAL_MAPPINGS)),
    
    #=========== SCALER ==============
    ('scaler', MinMaxScaler()),
    
    #=========== ENTRENAMIENTO DEL MODELO ============
    ('Lasso', Lasso(alpha=0.01, random_state=2022))
    
])
# -

X_trainv3 = X_train[FEATURES]

preds = titanic_pipeline.predict(X_test)

mean_squared_error(np.exp(y_test), np.exp(preds), squared=False)

import joblib

#Guardamos pipeline
joblib.dump(titanic_pipeline, 'titanic_pipeline.pkl')



StarcoderdataJupyterScriptsDedupFiltered