<jupyter_start><jupyter_text>Health Insurance Cross Sell Prediction - KaggleData Science for Business**Goal**:Our client is an Insurance company that has provided Health Insurance to its customers now they need your help in building a model to predict whether the policyholders (customers) from past year will also be interested in Vehicle Insurance provided by the company.*   Dataset: https://www.kaggle.com/anmolkumar/health-insurance-cross-sell-prediction***Teacher:*** <NAME>***Group:*** <NAME> , <NAME>, <NAME> e <NAME> Melhores Modelos*   Logistic Regression*   Random Florest*   XGBoost Campos/ConceitoTotal de 12 campos, sendo nenhum nulo, 3 categoricos  e 9 númericos.*  id - Unique ID for the customer*  Gender - Gender of the customer*  Age - Age of the customer*  Driving_License - 0 : Customer does not have DL, 1 : Customer already has DL*  Region_Code -  Unique code for the region of the customer*  Previously_Insured - 1 : Customer already has Vehicle Insurance, 0 : Customer doesn't have Vehicle Insurance*  Vehicle_Age - Age of the Vehiclevy  *  Vehicle_Damage - 1 : Customer got his/her vehicle damaged in the past. 0 : Customer didn't get his/her vehicle damaged in the past.*  Annual_Premium - The amount customer needs to pay as premium in the year*  PolicySalesChannel - Anonymized Code for the channel of outreaching to the customer ie. Different Agents, Over Mail, Over Phone, In Person, etc.*  Vintage - Number of Days, Customer has been associated with the company.*  Response - 1 : Customer is interested, 0 : Customer is not interested  1. Importando Bibliotecas<jupyter_code>!pip install shap 
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns
import shap
import xgboost

from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.model_selection import KFold, cross_val_score
from sklearn.neighbors import KNeighborsClassifier, DistanceMetric
from sklearn.tree import DecisionTreeClassifier, plot_tree
from sklearn.linear_model import LogisticRegression, SGDClassifier
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix, ConfusionMatrixDisplay, SCORERS
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import ConfusionMatrixDisplay
pd.options.display.max_columns = None
sns.set(font_scale=1.2)
sns.set_style({'font.family': 'serif',
               'fontname': 'Times New Roman'})<jupyter_output><empty_output><jupyter_text>2. Carregando Dados<jupyter_code>df_train = pd.read_csv('train.csv', sep=',')
df_train.head(2)<jupyter_output><empty_output><jupyter_text>3. Análise Exploratoria<jupyter_code>df_train.info()
df_train.head()
#Princiapis categorias
categoricals = df_train.select_dtypes(exclude=[np.number])
categoricals.describe()
#Categorias por variavel
n = categoricals
for c in n.columns:
    print('{:<14}'.format(c), df_train[c].unique())
plt.figure(figsize = (12,5))

ax = sns.countplot(x = 'Vehicle_Age', 
                   data = df_train, 
                   order = df_train['Vehicle_Age'].value_counts().index)

ax.set_title('Idade do Veiculo')
ax.set_xlabel('Idade')
ax.set_ylabel('Qtde')

plt.show()
plt.figure(figsize = (12,5))

ax = sns.countplot(x = 'Gender', 
                   data = df_train, 
                   order = df_train['Gender'].value_counts().index)

ax.set_title('Clientes por Genero')
ax.set_xlabel('Gender')
ax.set_ylabel('Qtde')

plt.show()
plt.figure(figsize = (35,10))

ax = sns.countplot(x = 'Vehicle_Damage', 
                   data = df_train, 
                   order = df_train['Vehicle_Damage'].value_counts().index)

ax.set_title('Veiculos Danificados')
ax.set_xlabel('Damage')
ax.set_ylabel('Qtde')

plt.show()
df_train.head(2)
total = df_train.isnull().sum().sort_values(ascending=False)
percent = (df_train.isnull().sum()/df_train.isnull().count()).sort_values(ascending=False)
null_data = pd.concat([total, percent], axis=1, keys=['Total', 'Percent'])
null_data.head(20)
resposta = df_train['Response'].value_counts().reset_index()
resposta = resposta.rename(columns={'index': 'resposta', 'Response': 'qtde'})
resposta
correlacao = df_train.corr()
correlacao
fet_set = df_train.drop(labels=['id','Response'],axis=1)
def plot_diag_heatmap(data):
    corr = data.corr()
    mask = np.triu(np.ones_like(corr, dtype=bool))
    f, ax = plt.subplots(figsize=(10, 12))
    sns.heatmap(corr, mask=mask, cmap='YlGnBu', center=0,square=True, linewidths=1, cbar_kws={"shrink": 1.0})
plot_diag_heatmap(fet_set)<jupyter_output><empty_output><jupyter_text>4. Pré-processamento<jupyter_code>#Removendo campo
df_train.drop(['id'], axis='columns', inplace=True)
#Convertendo string em numeros
label_encoder = LabelEncoder()
df_train['Gender'] = label_encoder.fit_transform(list(df_train['Gender'].values))
df_train['Vehicle_Age'] = label_encoder.fit_transform(list(df_train['Vehicle_Age'].values))
df_train['Vehicle_Damage'] = label_encoder.fit_transform(list(df_train['Vehicle_Damage'].values))

df_train.head(2)
target_names = ["Não","Sim"]<jupyter_output><empty_output><jupyter_text>4.1 Dividindo Treino e Teste<jupyter_code>X_train, X_test, y_train, y_test = \
    train_test_split(df_train.drop(columns='Response'), 
                     df_train['Response'], 
                     test_size=0.33, random_state=42)
y_train.value_counts(normalize=True)
y_test.value_counts(normalize=True)
print('Amostras de treino:')
print(f' * X_train: {X_train.shape}')
print(f' * y_train: {y_train.shape}')

print('Amostras de teste:')
print(f' * X_test: {X_test.shape}')
print(f' * y_test: {y_test.shape}')<jupyter_output>Amostras de treino:
 * X_train: (255343, 10)
 * y_train: (255343,)
Amostras de teste:
 * X_test: (125766, 10)
 * y_test: (125766,)<jupyter_text>5. KNN 5.1 Treino Modelo<jupyter_code>knn_model = KNeighborsClassifier(n_neighbors=25)

knn_model.fit(X_train, y_train)<jupyter_output><empty_output><jupyter_text>5.2 Avaliando Modelo<jupyter_code>print(f'Acurácia (Treino): {round(accuracy_score(y_train, knn_model.predict(X_train)), 2)}')
print(f'Acurácia (Teste): {round(accuracy_score(y_test, knn_model.predict(X_test)), 2)}')
print(classification_report(y_test, knn_model.predict(X_test), target_names=['Não', 'Sim']))
cm = confusion_matrix(y_test, knn_model.predict(X_test), labels=knn_model.classes_)
# Normalise
cmn = cm.astype('float') /  cm.sum(axis=1)[:, np.newaxis]
fig, ax = plt.subplots(figsize=(5,4))
sns.heatmap(cmn, annot=True, fmt='.2f', xticklabels=target_names, yticklabels=target_names)
plt.ylabel('Actual')
plt.xlabel('Predicted')
plt.show(block=False)<jupyter_output><empty_output><jupyter_text>6. Árvore de Decisão 6.1 Treinando Modelo<jupyter_code>tree_model = DecisionTreeClassifier(criterion='gini',
                                    max_depth=10,
                                    random_state=0)

tree_model.fit(X_train, y_train)
plt.figure(figsize=(18,10))

ax = plot_tree(tree_model,
               max_depth=3,
               fontsize=12,
               feature_names=df_train.columns[1:])

plt.show()<jupyter_output><empty_output><jupyter_text>6.2 Avaliando Modelo<jupyter_code>print(f'Acurácia (Treino): {round(accuracy_score(y_train, tree_model.predict(X_train)), 2)}')
print(f'Acurácia (Teste): {round(accuracy_score(y_test, tree_model.predict(X_test)), 2)}')
print(classification_report(y_test, tree_model.predict(X_test), target_names=['Não', 'Sim']))
cm = confusion_matrix(y_test, tree_model.predict(X_test), labels=tree_model.classes_)
# Normalise
cmn = cm.astype('float') /  cm.sum(axis=1)[:, np.newaxis]
fig, ax = plt.subplots(figsize=(5,4))
sns.heatmap(cmn, annot=True, fmt='.2f', xticklabels=target_names, yticklabels=target_names)
plt.ylabel('Actual')
plt.xlabel('Predicted')
plt.show(block=False)<jupyter_output><empty_output><jupyter_text>7. Regressão Logística 7.1 Treino Modelo<jupyter_code>reglog_model = SGDClassifier(loss='log', 
                             learning_rate='constant', 
                             max_iter=250,
                             eta0=0.05, 
                             verbose=1, 
                             tol=None, 
                             random_state=0)

reglog_model.fit(X_train, y_train)<jupyter_output>-- Epoch 1
Norm: 14032.86, NNZs: 10, Bias: 14.225000, T: 255343, Avg. loss: 7054625.025389
Total training time: 0.06 seconds.
-- Epoch 2
Norm: 17318.56, NNZs: 10, Bias: 34.375000, T: 510686, Avg. loss: 6938599.325796
Total training time: 0.11 seconds.
-- Epoch 3
Norm: 17846.28, NNZs: 10, Bias: 58.575000, T: 766029, Avg. loss: 6981220.470380
Total training time: 0.16 seconds.
-- Epoch 4
Norm: 17498.80, NNZs: 10, Bias: 78.275000, T: 1021372, Avg. loss: 7026589.618499
Total training time: 0.21 seconds.
-- Epoch 5
Norm: 17555.03, NNZs: 10, Bias: 99.675000, T: 1276715, Avg. loss: 6954615.382544
Total training time: 0.27 seconds.
-- Epoch 6
Norm: 17853.33, NNZs: 10, Bias: 122.325000, T: 1532058, Avg. loss: 6969674.374617
Total training time: 0.32 seconds.
-- Epoch 7
Norm: 18356.92, NNZs: 10, Bias: 140.625000, T: 1787401, Avg. loss: 6883414.792744
Total training time: 0.37 seconds.
-- Epoch 8
Norm: 18389.29, NNZs: 10, Bias: 164.825000, T: 2042744, Avg. loss: 6962080.681106
Total training time[...]<jupyter_text>7.2 Avaliando Modelo<jupyter_code>for f, c in zip(df_train.columns[1:], reglog_model.coef_[0].tolist()):
    print(f'{f} = {c}')

print(f'CONST = {float(reglog_model.intercept_)}')
print(f'Acurácia (Treino): {round(accuracy_score(y_train, reglog_model.predict(X_train)), 2)}')
print(f'Acurácia (Teste): {round(accuracy_score(y_test, reglog_model.predict(X_test)), 2)}')
cm = confusion_matrix(y_test, reglog_model.predict(X_test), labels=reglog_model.classes_)
# Normalise
cmn = cm.astype('float') /  cm.sum(axis=1)[:, np.newaxis]
fig, ax = plt.subplots(figsize=(5,4))
sns.heatmap(cmn, annot=True, fmt='.2f', xticklabels=target_names, yticklabels=target_names)
plt.ylabel('Actual')
plt.xlabel('Predicted')
plt.show(block=False)<jupyter_output><empty_output><jupyter_text>8. Random Forest<jupyter_code>random_forest_model = RandomForestClassifier(n_estimators=50, 
                                             criterion='entropy',
                                             max_depth=10,
                                             min_samples_split=2,
                                             random_state=0)

random_forest_model.fit(X_train, y_train)
print('Random Forest')
print(f'Acurácia: {round(accuracy_score(y_test, random_forest_model.predict(X_test)), 4)}')
print(classification_report(y_test, random_forest_model.predict(X_test), target_names=['Não', 'Sim']))
cm = confusion_matrix(y_test, random_forest_model.predict(X_test), labels=random_forest_model.classes_)
# Normalise
cmn = cm.astype('float') /  cm.sum(axis=1)[:, np.newaxis]
fig, ax = plt.subplots(figsize=(5,4))
sns.heatmap(cmn, annot=True, fmt='.2f', xticklabels=target_names, yticklabels=target_names)
plt.ylabel('Actual')
plt.xlabel('Predicted')
plt.show(block=False)<jupyter_output><empty_output><jupyter_text>9. XGBoost<jupyter_code>%%capture

xgb_model = xgboost.XGBClassifier(booster = 'gbtree', 
                                  learning_rate = 0.03,
                                  n_estimators = 100,
                                  max_depth = 3, 
                                  use_label_encoder=False)

cv = KFold(n_splits = 5, 
           shuffle = True, 
           random_state=0)

n_scores = cross_val_score(xgb_model, 
                           X_train, y_train, 
                           scoring = 'accuracy', 
                           cv = cv)
print('Validação Cruzada\n')
print(f'Acurácias: {n_scores}\n')
print(f'Acurácias (média): {round(np.mean(n_scores), 4)}')
print(f'Acurácias (desvio padrão): {round(np.std(n_scores), 4)}')
%%capture

xgb_model.fit(X_train, y_train)
print('XGBoost')
print(f'Acurácia: {round(accuracy_score(y_test, xgb_model.predict(X_test)), 4)}')
cm = confusion_matrix(y_test, xgb_model.predict(X_test), labels=xgb_model.classes_)
# Normalise
cmn = cm.astype('float') /  cm.sum(axis=1)[:, np.newaxis]
fig, ax = plt.subplots(figsize=(5,4))
sns.heatmap(cmn, annot=True, fmt='.2f', xticklabels=target_names, yticklabels=target_names)
plt.ylabel('Actual')
plt.xlabel('Predicted')
plt.show(block=False)<jupyter_output><empty_output><jupyter_text>10. Baleceamento + Seleção de Features<jupyter_code>train = xgboost.DMatrix(X_train,y_train,feature_names=X_train.columns)
test = xgboost.DMatrix(X_test,feature_names=X_test.columns)
xgb_params = {
    'eta':0.03,
    'max_depth':4,
    'sub_sample':0.9,
    'colsample_bytree':0.5,
    'objective':'binary:logistic',
    'eval_metric':'auc',
    'silent':0}

final_model = xgboost.train(xgb_params,train,num_boost_round=500)
import pickle
import numpy as np
from util import ScoreDistribution, ROC_AUC, \
    prob_scale, get_resampling, PSI, xgbCV
X_train_under, y_train_under = get_resampling(X_train, y_train, 
                                              verbose=False, 
                                              random_state=42, 
                                              by='undersampling', 
                                              good_mult=1)
y_train_under.value_counts(normalize=True)
train = xgboost.DMatrix(X_train_under,y_train_under,
                    feature_names=X_train_under.columns)
test = xgboost.DMatrix(X_test,feature_names=X_train_under.columns)
xgb_params = {
                    'eta':0.03,
                    'max_depth':4,
                    'sub_sample':0.9,
                    'colsample_bytree':0.5,
                    'objective':'binary:logistic',
                    'eval_metric':'auc',
                    'silent':0
                    }

final_model_under = xgboost.train(xgb_params,train,num_boost_round=500)
y_pred_train_under = final_model_under.predict(train)

xgboost.plot_importance(final_model_under)
plt.show()<jupyter_output><empty_output><jupyter_text>10.Gerando Modelo<jupyter_code>file_name = 'xgboost_undersampling.pkl'
pickle.dump(final_model_under, open(file_name, "wb"))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12974192638555915, 'fraction_numerical': 0.03680722042025102, 'mean_word_length': 4.10363440086362, 'pattern_counts': {'":': 1, '<': 65, '<?xml version=': 0, '>': 64, 'https://': 1, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 22, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '15', 'dir': 'jupyter-structured-clean-dedup', 'id': '573915', 'license': 'FTL', 'n_tokens_mistral': 5506, 'n_tokens_neox': 5023, 'n_words': 933, 'path': 'CDN_Trabalho_Final.ipynb', 'repo_name': 'ehdob-cid20/mlops-deploy', 'size': '14232'}