<jupyter_start><jupyter_text>**Part 3: Modeling and Evaluation**  **Prepare Environment**  Imports<jupyter_code># Data analysis and data wrangling
import numpy as np
import pandas as pd

# Plotting
import seaborn as sns
import matplotlib.pyplot as plt
import missingno as msno # missing values

# Preprocessing
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import PolynomialFeatures

# Machine Learning
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import RandomForestRegressor
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Ridge

# Metrics
from sklearn.model_selection import KFold
from sklearn.model_selection import StratifiedKFold
from sklearn.model_selection import cross_val_score

# Other
from IPython.display import Image
import configparser
import warnings
import os
import time
import pprint<jupyter_output><empty_output><jupyter_text>Prepare Principal Directory<jupyter_code>def path_to_work(end_directory: str='notebooks'):
    curr_dir = os.path.dirname(os.path.realpath ("__file__")) 
    
    if curr_dir.endswith(end_directory):
        os.chdir('..')
        return f'Change directory to: {curr_dir}'
    
    return f'Current working directory: {curr_dir}'
path_to_work(end_directory='notebooks')<jupyter_output><empty_output><jupyter_text>Set Config<jupyter_code># Visualization inside the jupyter
%matplotlib inline

# Load the "autoreload" extension so that code can change
%load_ext autoreload

# ----------
# Plot
# ----------
# graph style
sns.set_style("darkgrid")
plt.style.use('fivethirtyeight')

# ----------
# Seaborn rcParams
# ----------
rc={'savefig.dpi': 500, 
    'figure.autolayout': True, 
    'figure.figsize': [17, 12], 
    'axes.labelsize': 18,
    'axes.titlesize': 18, 
    'font.size': 10, 
    'lines.linewidth': 1.0, 
    'lines.markersize': 8, 
    'legend.fontsize': 15,
    'xtick.labelsize': 15, 
    'ytick.labelsize': 15}

sns.set(context='notebook',  # notebook
        style='darkgrid',
        palette='deep',
        color_codes=True, 
        rc=rc)

# ----------
# Pandas
# ----------
# Floating point
pd.options.display.float_format = '{:.2f}'.format

# Print xxxx rows and all columns
pd.set_option('display.max_rows', 300)
pd.set_option('display.max_columns', None)

# ----------
# Python
# ----------
# pretty print
pp = pprint.PrettyPrinter(indent=4)

# Supress unnecessary warnings so that presentation looks clean
warnings.filterwarnings('ignore')<jupyter_output><empty_output><jupyter_text>Load Data<jupyter_code>%%time

df_callcenter = pd.read_csv('data/cleansing/callcenter_marketing_clenning.csv', 
                            encoding='utf8',
                            delimiter=',',
                            verbose=True)
df_callcenter.info()<jupyter_output><class 'pandas.core.frame.DataFrame'>
RangeIndex: 41167 entries, 0 to 41166
Data columns (total 15 columns):
 #   Column                       Non-Null Count  Dtype  
---  ------                       --------------  -----  
 0   idade                        41167 non-null  int64  
 1   profissao                    41167 non-null  int64  
 2   educacao                     41167 non-null  int64  
 3   meio_contato                 41167 non-null  int64  
 4   mes                          41167 non-null  int64  
 5   dia_da_semana                41167 non-null  int64  
 6   duracao                      41167 non-null  int64  
 7   dias_ultimo_contato          41167 non-null  int64  
 8   qtd_contatos_total           41167 non-null  int64  
 9   campanha_anterior            41167 non-null  int64  
 10  indice_precos_consumidor     41167 non-null  float64
 11  indice_confianca_consumidor  41167 non-null  float64
 12  euribor3m                    41167 non-null  float64
 13  numero_empregado[...]<jupyter_text>Global Variables<jupyter_code># Lists that will be manipulated in the data processing
list_columns = []
list_categorical_col = []
list_numerical_col = []
list_without_target_col = []
def get_col(df: pd.core.frame.DataFrame, type_descr: 'numpy') -> list:
    """
    Function get list columns 
    
    Args:
    type_descr
        np.number, np.object -> return list with all columns
        np.number            -> return list numerical columns 
        np.object            -> return list object columns
    """
    try:
        col = (df.describe(include=type_descr).columns) 
    except ValueError:
        print(f'Dataframe not contains {type_descr} columns !', end='\n')    
    else:
        return col.tolist()
def get_col_without_target(df: pd.core.frame.DataFrame,
                           list_columns: list,
                           target_col: str) -> list:

    col_target = list_columns.copy()
    
    col_target.remove(target_col)
    print(type(col_target))
    
    return col_target
list_numerical_col = get_col(df=df_callcenter,
                             type_descr=np.number)
list_categorical_col = get_col(df=df_callcenter,
                               type_descr=np.object)
list_columns = get_col(df=df_callcenter,
                       type_descr=[np.object, np.number])
list_without_target_col = get_col_without_target(df=df_callcenter,
                                                 list_columns=list_columns,
                                                 target_col='resultado')<jupyter_output>Dataframe not contains <class 'object'> columns !
<class 'list'><jupyter_text>--- **Training and Testing Data**<jupyter_code>def cross_val_model(X,y, model, n_splits=3):
    'Do split dataset and calculate cross_score'
    print("Begin training", end='\n\n')
    start = time.time()
    
    X = np.array(X)
    y = np.array(y)
    folds = list(StratifiedKFold(n_splits=n_splits, shuffle=True, random_state=2017).split(X, y))

    for j, (train_idx, test_idx) in enumerate(folds):
        X_train = X[train_idx]
        y_train = y[train_idx]
        X_holdout = X[test_idx]
        y_holdout = y[test_idx]

        print ("Fit %s fold %d" % (str(model).split('(')[0], j+1))
        model.fit(X_train, y_train)
        cross_score = cross_val_score(model, X_holdout, y_holdout, cv=3, scoring='roc_auc')
        print("\tcross_score: %.5f" % cross_score.mean())
    
    end = time.time()
    print("\nTraining done! Time Elapsed:", end - start, " seconds.")
X = df_callcenter[list_without_target_col]
y = df_callcenter['resultado'] # target<jupyter_output><empty_output><jupyter_text>--- **Build Models**  Baseline  Linear Regression<jupyter_code># training model
X = df_callcenter[list_without_target_col]
y = df_callcenter['resultado']

print(X.shape)
print(y.shape)
# Visualize params

LinearRegression(n_jobs=-1)
# create model
lr_model = LinearRegression(n_jobs=-1, normalize=False)
# split dataset and calculate cross_score
cross_val_model(X, y, lr_model)<jupyter_output>Begin training

Fit LinearRegression fold 1
	cross_score: 0.78831
Fit LinearRegression fold 2
	cross_score: 0.82517
Fit LinearRegression fold 3
	cross_score: 0.82065

Training done! Time Elapsed: 0.3465287685394287  seconds.<jupyter_text>Linear Regression with Regularization<jupyter_code># create model
lr_ridge_model = Ridge()
# split dataset and calculate cross_score
cross_val_model(X, y, lr_ridge_model)<jupyter_output>Begin training

Fit Ridge fold 1
	cross_score: 0.78937
Fit Ridge fold 2
	cross_score: 0.82620
Fit Ridge fold 3
	cross_score: 0.81947

Training done! Time Elapsed: 0.24179339408874512  seconds.<jupyter_text>Polynomial Regression<jupyter_code>poly = PolynomialFeatures(degree=2)

X_poly = poly.fit_transform(X)
print(X_poly.shape)
# split dataset and calculate cross_score
cross_val_model(X_poly, y, lr_model)<jupyter_output>Begin training

Fit LinearRegression fold 1
	cross_score: 0.59654
Fit LinearRegression fold 2
	cross_score: 0.77486
Fit LinearRegression fold 3
	cross_score: 0.59465

Training done! Time Elapsed: 4.3111491203308105  seconds.<jupyter_text>Benckmarks  RandomForest<jupyter_code># RandomForest params dict
rf_params_one = {}

rf_params_one['n_estimators'] = 10
rf_params_one['max_depth'] = 10
rf_params_one['min_samples_split'] = 10
rf_params_one['min_samples_leaf'] = 10 # end tree necessary 30 leaf
rf_params_one['n_jobs'] = -1 # run all process
# create model
rf_model_one = RandomForestClassifier(**rf_params_one)

# training model
X = df_callcenter[list_without_target_col]
y = df_callcenter['resultado']
# split dataset and calculate cross_score
cross_val_model(X, y, rf_model_one)
# RandomForest params dict
rf_params_two = {}

rf_params_two['n_estimators'] = 1
rf_params_two['max_depth'] = len(list_numerical_col)*2
rf_params_two['min_samples_split'] = len(list_numerical_col)
rf_params_two['min_samples_leaf'] = len(list_numerical_col)
rf_params_two['n_jobs'] = -1 # run all process
# create model
rf_model = RandomForestClassifier(**rf_params_two, criterion='entropy')

# training model
X = df_callcenter[list_without_target_col]
y = df_callcenter['resultado']
# split dataset and calculate cross_score
cross_val_model(X, y, rf_model)<jupyter_output>Begin training

Fit RandomForestClassifier fold 1
	cross_score: 0.43202
Fit RandomForestClassifier fold 2
	cross_score: 0.45268
Fit RandomForestClassifier fold 3
	cross_score: 0.44761

Training done! Time Elapsed: 0.3521687984466553  seconds.<jupyter_text>Random Forest Regressor<jupyter_code># 1st model Random Forest
rf_regressor_one = RandomForestRegressor(n_jobs = -1,
                                         verbose = 0)
# split dataset and calculate cross_score
cross_val_model(X, y, rf_regressor_one)
# 2st model Random Forest
rf_regressor_two = RandomForestRegressor(n_estimators = 1000,
                                         max_leaf_nodes = len(list_numerical_col)*8,
                                         min_samples_leaf = len(list_numerical_col),
                                         max_depth = len(list_numerical_col)*4,
                                         n_jobs = -1,
                                         verbose = 0)
# split dataset and calculate cross_score
cross_val_model(X, y, rf_regressor_two)<jupyter_output>Begin training

Fit RandomForestRegressor fold 1
	cross_score: 0.84680
Fit RandomForestRegressor fold 2
	cross_score: 0.81629
Fit RandomForestRegressor fold 3
	cross_score: 0.83830

Training done! Time Elapsed: 44.41213035583496  seconds.
{'fraction_non_alphanumeric': 0.09803921568627451, 'fraction_numerical': 0.036704336907176664, 'mean_word_length': 3.203816483962647, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 17, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '11', 'dir': 'jupyter-structured-clean-dedup', 'id': '423786', 'license': 'MIT', 'n_tokens_mistral': 3691, 'n_tokens_neox': 3331, 'n_words': 753, 'path': 'notebooks/3-modeling_evaluation.ipynb', 'repo_name': 'brunocampos01/challenge-keyrus', 'size': '10353'}