MLP
Trabalhando com Redes Neurais com TensorFlow¶
Neste módulo, exploraremos os fundamentos das redes neurais e aprenderemos a aplicar esses conceitos poderosos usando a biblioteca TensorFlow. O TensorFlow não apenas facilita a construção e o treinamento de modelos complexos, mas também oferece ferramentas robustas para o processamento de dados, essenciais para qualquer projeto de machine learning.
Objetivos de Aprendizado¶
- Entender o funcionamento das redes neurais.
- Desenvolver habilidades práticas em modelagem e treinamento de redes neurais com TensorFlow.
- Aplicar redes neurais em problemas reais de classificação e regressão.
Desafios a Serem Explorados¶
Problema de Regressão
- Contexto: Utilizaremos um conjunto de dados com o desafio enfrentado pelos planos de saúde na estimativa de gastos por segurado.
- Modelo Sugerido: Rede neural com múltiplas camadas densas.
- Métricas de Avaliação: RMSE (Root Mean Square Error) e R2-score para quantificar a diferença entre os valores preditos e os reais.
Problema de Classificação
- Contexto: otimizar processos de RH.Onde o objetivo é prever se um colaborador irá deixar a empresa ou não.
- Modelo Sugerido: Rede neural scom múltiplas camadas densas para classificação multiclasse.
- Métricas de Avaliação: Acurácia e matriz de confusão para avaliar o desempenho do modelo.
Pré-processamento e Tratamento de Dados¶
Antes de aplicar o treinamento de modelos, é essencial realizar o pré-processamento e o tratamento adequado dos dados. Esse processo inclui:
- Limpeza de Dados: Remoção de valores ausentes ou correção de dados corrompidos.
- Normalização/Padronização: Escalonamento dos valores numéricos para que o modelo não seja enviesado por características com escalas grandes.
- Codificação de Variáveis Categóricas: Transformação de variáveis categóricas em formatos numéricos que podem ser interpretados pelo modelo, como one-hot encoding.
Vamos começar!!!
Problema de Regressão¶
Nosso problema é o desafio enfrentado pelos planos de saúde na estimativa de gastos por segurado.
Poder estimar este valor permite uma melhor alocação de recursos e uma gestão mais eficiente dos custos operacionais.
Do ponto de vista prático, utilizaremos uma base bastante conhecida contendo informações sobre os segurados (como idade, gênero, região de residência, entre outros).
Esses atributos são comumente usados para prever os custos médicos de um segurado, o que pode ser útil para companhias de seguros na precificação de apólices ou na identificação de segmentos de clientes com diferentes perfis de risco.
Esta base é composta pelos seguintes atributos:
- age: Refere-se à idade do segurado, representada em anos.
- sex: Indica o sexo do segurado, podendo ser 'male' ou 'female'.
- bmi: Corresponde ao Índice de Massa Corporal (IMC) do segurado, uma medida que relaciona o peso e a altura da pessoa, geralmente expressa em kg/m².
- children: Representa o número de filhos ou dependentes do segurado.
- smoker: Indica se o segurado é fumante ou não, podendo ser 'yes' ou 'no'.
- region: Refere-se à região de residência do segurado, podendo ser 'northeast', 'northwest', 'southeast' ou 'southwest'.
- expenses: Corresponde aos custos médicos do segurado, em dólares.
# Ignorar warnings
import warnings
warnings.filterwarnings("ignore")
# Bibliotecas para uso e visualização de dados
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
# Import para divisão dos dados de treino e teste
from sklearn.model_selection import train_test_split
# Imports para preparação de dados
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import MinMaxScaler
# Import de modelo preditivo de regressão para comparar os resultados no final.
from sklearn.linear_model import LinearRegression
# Import de métricas para avaliação dos modelos
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
# Leitura do dataset
df = pd.read_csv("insurance.csv")
df.head(5)
age | sex | bmi | children | smoker | region | expenses | |
---|---|---|---|---|---|---|---|
0 | 19 | female | 27.9 | 0 | yes | southwest | 16884.92 |
1 | 18 | male | 33.8 | 1 | no | southeast | 1725.55 |
2 | 28 | male | 33.0 | 3 | no | southeast | 4449.46 |
3 | 33 | male | 22.7 | 0 | no | northwest | 21984.47 |
4 | 32 | male | 28.9 | 0 | no | northwest | 3866.86 |
# Quais os tipos? Dados faltantes?
df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 1338 entries, 0 to 1337 Data columns (total 7 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 age 1338 non-null int64 1 sex 1338 non-null object 2 bmi 1338 non-null float64 3 children 1338 non-null int64 4 smoker 1338 non-null object 5 region 1338 non-null object 6 expenses 1338 non-null float64 dtypes: float64(2), int64(2), object(3) memory usage: 73.3+ KB
## note que temos que tratar os atributos 'sex', 'smoker' e 'region'
# Quantos dados únicos
df.nunique()
age 47 sex 2 bmi 275 children 6 smoker 2 region 4 expenses 1337 dtype: int64
# Removendo duplicatas
df.drop_duplicates(inplace=True)
df.shape
# note que existia 1 dado duplicado
(1337, 7)
Agora já podemos partir para a limpeza da base, convertendo strings para números, aplicando OneHotEncoder e eliminando colunas originais que já foram tratadas
# Convertendo dados "string" para "números"
df["genero"] = df["sex"].apply( lambda x: 0 if x == "male" else 1 )
df["fumante"] = df["smoker"].apply( lambda x: 1 if x == "yes" else 0 )
# OneHotEncoder da coluna "region"
aux = pd.get_dummies(df["region"], drop_first=True)
df_final = pd.concat([df, aux], axis=1)
# Remover colunas que já foram processadas
df_final.drop(columns=["sex", "smoker", "region"], inplace=True)
df_final
age | bmi | children | expenses | genero | fumante | northwest | southeast | southwest | |
---|---|---|---|---|---|---|---|---|---|
0 | 19 | 27.9 | 0 | 16884.92 | 1 | 1 | False | False | True |
1 | 18 | 33.8 | 1 | 1725.55 | 0 | 0 | False | True | False |
2 | 28 | 33.0 | 3 | 4449.46 | 0 | 0 | False | True | False |
3 | 33 | 22.7 | 0 | 21984.47 | 0 | 0 | True | False | False |
4 | 32 | 28.9 | 0 | 3866.86 | 0 | 0 | True | False | False |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
1333 | 50 | 31.0 | 3 | 10600.55 | 0 | 0 | True | False | False |
1334 | 18 | 31.9 | 0 | 2205.98 | 1 | 0 | False | False | False |
1335 | 18 | 36.9 | 0 | 1629.83 | 1 | 0 | False | True | False |
1336 | 21 | 25.8 | 0 | 2007.95 | 1 | 0 | False | False | True |
1337 | 61 | 29.1 | 0 | 29141.36 | 1 | 1 | True | False | False |
1337 rows × 9 columns
Preste atenção¶
O nosso atributo alvo é expenses
que caracteriza o valor gasto.
Os outros atributos são possiveis entradas de dados.
Nosso objetivo é praticar redes neurais, por essa razão e apenas por isso, vamos simplificar a análise e considerar todas outras colunas como entradas de dados. Em outros casos, é necessário realizar uma exploração de dados mais profunda.
# Separação de DADOS e LABEL
X = df_final.drop(columns=["expenses"])
y = df_final["expenses"]
# Dividindo dados para TREINO e TESTE
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.3,
random_state=42
)
# Padronização dos dados
ss = StandardScaler()
X_train_scaled = ss.fit_transform(X_train)
X_test_scaled = ss.transform(X_test)
X_train, X_train_scaled
( age bmi children genero fumante northwest southeast southwest 138 54 31.9 3 1 0 False True False 381 55 30.7 0 0 1 False False False 292 25 45.5 2 0 1 False True False 1090 47 36.2 0 0 1 False True False 893 47 38.9 2 0 1 False True False ... ... ... ... ... ... ... ... ... 1096 51 35.0 2 1 1 False False False 1131 27 45.9 2 0 0 False False True 1295 20 22.0 1 0 0 False False True 861 38 28.0 3 1 0 False False True 1127 35 35.9 2 1 0 False True False [935 rows x 8 columns], array([[ 1.07135822, 0.21232198, 1.59987002, ..., -0.57776193, 1.64630418, -0.57282196], [ 1.14282796, 0.01300366, -0.90578906, ..., -0.57776193, -0.60742116, -0.57282196], [-1.00126436, 2.47126303, 0.76465033, ..., -0.57776193, 1.64630418, -0.57282196], ..., [-1.35861308, -1.43205422, -0.07056936, ..., -0.57776193, -0.60742116, 1.74574312], [-0.07215769, -0.43546258, 1.59987002, ..., -0.57776193, -0.60742116, 1.74574312], [-0.28656692, 0.87671641, 0.76465033, ..., -0.57776193, 1.64630418, -0.57282196]]))
Agora vamos treinar nossos dados, vamos fazer dois modelos:
- modelo de regressão linear simples.
- modelo de rede neural
Ao final, vamos compara os resultados.
# funçao para facilitar o calculo das métricas
def metricas(X_tr_scaled, y_tr, y_ts, y_pr, model, id_modelo):
y_pr_tr = model.predict(X_tr_scaled)
# Erro quadrático médio
print(f"MSE do TREINO ({id_modelo}): ", mean_squared_error(y_tr, y_pr_tr))
print(f"MSE do TESTE ({id_modelo}): ", mean_squared_error(y_ts, y_pr))
# Erro absoluto médio
print(f"MAE do TREINO ({id_modelo}): ", mean_absolute_error(y_tr, y_pr_tr))
print(f"MAE do TESTE ({id_modelo}): ", mean_absolute_error(y_ts, y_pr))
# R²
print(f"R² do TREINO ({id_modelo}): ", r2_score(y_tr, y_pr_tr))
print(f"R² do TESTE ({id_modelo}): ", r2_score(y_ts, y_pr))
# Treinando o modelo usando sklearn
model_lr = LinearRegression()
model_lr.fit(X_train_scaled, y_train)
# Fazendo as predições
y_pred = model_lr.predict(X_test_scaled)
# Metricas para regressão linear
metricas(X_train_scaled, y_train, y_test, y_pred, model_lr, "Reg Linear")
MSE do TREINO (Reg Linear): 35810116.96256572 MSE do TESTE (Reg Linear): 38939165.63000257 MAE do TREINO (Reg Linear): 4165.7883312974745 MAE do TESTE (Reg Linear): 4181.631594223737 R² do TREINO (Reg Linear): 0.7362844577541661 R² do TESTE (Reg Linear): 0.772442225318259
até aqui não existe nenhum novidade, ou pelo menos não deveria...¶
A novidade vem agora, onde vamos implementar um modelo de rede neural com Tensorflow
Vamos seguir os seguintes passos:
- criar o modelo de rede neural
- compilar o modelo
- treinar o modelo
import tensorflow as tf
# Cria o modelo de rede neural
# aqui devemos definir ao menos a quantidade de camadas, a quantidade de neuronios, o tipo de ativacao ...
model_rn = tf.keras.models.Sequential([
tf.keras.layers.Dense(64, activation='relu', input_shape=[X_train_scaled.shape[1]]),
tf.keras.layers.Dense(16, activation='relu',),
tf.keras.layers.Dense(1)
])
# Compila o modelo
model_rn.compile(optimizer='adam', loss='mean_squared_error', metrics=['mae'])
# Treina o modelo
historico_epochs = model_rn.fit(X_train_scaled, y_train, epochs=100, validation_split=0.2)
# Fazendo as predições
y_pr = model_rn.predict(X_test_scaled)
Epoch 1/100 24/24 [==============================] - 1s 14ms/step - loss: 308024192.0000 - mae: 13181.6006 - val_loss: 296421696.0000 - val_mae: 12449.0557 Epoch 2/100 24/24 [==============================] - 0s 6ms/step - loss: 307994464.0000 - mae: 13180.5371 - val_loss: 296391872.0000 - val_mae: 12447.9141 Epoch 3/100 24/24 [==============================] - 0s 6ms/step - loss: 307956576.0000 - mae: 13179.2100 - val_loss: 296349440.0000 - val_mae: 12446.3809 Epoch 4/100 24/24 [==============================] - 0s 5ms/step - loss: 307902272.0000 - mae: 13177.3838 - val_loss: 296288992.0000 - val_mae: 12444.2891 Epoch 5/100 24/24 [==============================] - 0s 6ms/step - loss: 307824352.0000 - mae: 13174.8447 - val_loss: 296201984.0000 - val_mae: 12441.3770 Epoch 6/100 24/24 [==============================] - 0s 6ms/step - loss: 307709760.0000 - mae: 13171.2451 - val_loss: 296075840.0000 - val_mae: 12437.2754 Epoch 7/100 24/24 [==============================] - 0s 6ms/step - loss: 307544896.0000 - mae: 13166.1885 - val_loss: 295892704.0000 - val_mae: 12431.5859 Epoch 8/100 24/24 [==============================] - 0s 6ms/step - loss: 307314016.0000 - mae: 13159.2715 - val_loss: 295643712.0000 - val_mae: 12423.9736 Epoch 9/100 24/24 [==============================] - 0s 6ms/step - loss: 306994528.0000 - mae: 13150.1514 - val_loss: 295318528.0000 - val_mae: 12414.2021 Epoch 10/100 24/24 [==============================] - 0s 4ms/step - loss: 306591456.0000 - mae: 13138.3623 - val_loss: 294892576.0000 - val_mae: 12401.7129 Epoch 11/100 24/24 [==============================] - 0s 3ms/step - loss: 306071232.0000 - mae: 13123.6416 - val_loss: 294359424.0000 - val_mae: 12386.4053 Epoch 12/100 24/24 [==============================] - 0s 3ms/step - loss: 305421440.0000 - mae: 13105.7822 - val_loss: 293715392.0000 - val_mae: 12368.1982 Epoch 13/100 24/24 [==============================] - 0s 3ms/step - loss: 304651936.0000 - mae: 13084.4570 - val_loss: 292936992.0000 - val_mae: 12346.3252 Epoch 14/100 24/24 [==============================] - 0s 4ms/step - loss: 303713824.0000 - mae: 13059.1729 - val_loss: 292033600.0000 - val_mae: 12321.2598 Epoch 15/100 24/24 [==============================] - 0s 4ms/step - loss: 302645632.0000 - mae: 13029.8467 - val_loss: 290954816.0000 - val_mae: 12291.6406 Epoch 16/100 24/24 [==============================] - 0s 4ms/step - loss: 301404064.0000 - mae: 12995.9268 - val_loss: 289723520.0000 - val_mae: 12257.9385 Epoch 17/100 24/24 [==============================] - 0s 4ms/step - loss: 299979488.0000 - mae: 12957.6992 - val_loss: 288364448.0000 - val_mae: 12220.7383 Epoch 18/100 24/24 [==============================] - 0s 4ms/step - loss: 298385440.0000 - mae: 12915.3516 - val_loss: 286831680.0000 - val_mae: 12179.0605 Epoch 19/100 24/24 [==============================] - 0s 4ms/step - loss: 296624672.0000 - mae: 12867.6387 - val_loss: 285127488.0000 - val_mae: 12132.7871 Epoch 20/100 24/24 [==============================] - 0s 3ms/step - loss: 294684672.0000 - mae: 12815.3584 - val_loss: 283254048.0000 - val_mae: 12081.8770 Epoch 21/100 24/24 [==============================] - 0s 4ms/step - loss: 292528736.0000 - mae: 12758.1953 - val_loss: 281211328.0000 - val_mae: 12026.5293 Epoch 22/100 24/24 [==============================] - 0s 4ms/step - loss: 290164832.0000 - mae: 12695.2744 - val_loss: 279027968.0000 - val_mae: 11967.0859 Epoch 23/100 24/24 [==============================] - 0s 3ms/step - loss: 287577312.0000 - mae: 12626.9883 - val_loss: 276615744.0000 - val_mae: 11901.2656 Epoch 24/100 24/24 [==============================] - 0s 3ms/step - loss: 284817920.0000 - mae: 12550.3613 - val_loss: 273862208.0000 - val_mae: 11827.1309 Epoch 25/100 24/24 [==============================] - 0s 4ms/step - loss: 281801760.0000 - mae: 12469.6982 - val_loss: 271013600.0000 - val_mae: 11749.6084 Epoch 26/100 24/24 [==============================] - 0s 4ms/step - loss: 278670464.0000 - mae: 12383.8594 - val_loss: 268082704.0000 - val_mae: 11669.3584 Epoch 27/100 24/24 [==============================] - 0s 3ms/step - loss: 275324800.0000 - mae: 12294.7109 - val_loss: 265058576.0000 - val_mae: 11585.3271 Epoch 28/100 24/24 [==============================] - 0s 4ms/step - loss: 271782560.0000 - mae: 12197.9414 - val_loss: 261658544.0000 - val_mae: 11491.6621 Epoch 29/100 24/24 [==============================] - 0s 3ms/step - loss: 268054400.0000 - mae: 12095.4717 - val_loss: 258102448.0000 - val_mae: 11393.0254 Epoch 30/100 24/24 [==============================] - 0s 4ms/step - loss: 264061936.0000 - mae: 11985.5469 - val_loss: 254433904.0000 - val_mae: 11290.2676 Epoch 31/100 24/24 [==============================] - 0s 4ms/step - loss: 259988720.0000 - mae: 11871.6328 - val_loss: 250552624.0000 - val_mae: 11180.4414 Epoch 32/100 24/24 [==============================] - 0s 3ms/step - loss: 255628976.0000 - mae: 11750.6670 - val_loss: 246568560.0000 - val_mae: 11067.1133 Epoch 33/100 24/24 [==============================] - 0s 4ms/step - loss: 251240272.0000 - mae: 11625.0967 - val_loss: 242364048.0000 - val_mae: 10946.6680 Epoch 34/100 24/24 [==============================] - 0s 3ms/step - loss: 246592896.0000 - mae: 11494.1426 - val_loss: 238034336.0000 - val_mae: 10821.3848 Epoch 35/100 24/24 [==============================] - 0s 3ms/step - loss: 241746208.0000 - mae: 11357.7549 - val_loss: 233718192.0000 - val_mae: 10694.5723 Epoch 36/100 24/24 [==============================] - 0s 4ms/step - loss: 236915920.0000 - mae: 11214.3076 - val_loss: 228979280.0000 - val_mae: 10556.7324 Epoch 37/100 24/24 [==============================] - 0s 3ms/step - loss: 231722160.0000 - mae: 11063.3906 - val_loss: 224265856.0000 - val_mae: 10417.8896 Epoch 38/100 24/24 [==============================] - 0s 4ms/step - loss: 226510224.0000 - mae: 10910.9033 - val_loss: 219460704.0000 - val_mae: 10274.6670 Epoch 39/100 24/24 [==============================] - 0s 4ms/step - loss: 221185728.0000 - mae: 10749.5986 - val_loss: 214382576.0000 - val_mae: 10123.2861 Epoch 40/100 24/24 [==============================] - 0s 4ms/step - loss: 215703184.0000 - mae: 10582.2109 - val_loss: 209248960.0000 - val_mae: 9968.8867 Epoch 41/100 24/24 [==============================] - 0s 4ms/step - loss: 210073680.0000 - mae: 10410.6133 - val_loss: 204216192.0000 - val_mae: 9817.5371 Epoch 42/100 24/24 [==============================] - 0s 3ms/step - loss: 204534592.0000 - mae: 10238.3750 - val_loss: 199093456.0000 - val_mae: 9661.6475 Epoch 43/100 24/24 [==============================] - 0s 3ms/step - loss: 198908512.0000 - mae: 10058.8135 - val_loss: 193889456.0000 - val_mae: 9503.5029 Epoch 44/100 24/24 [==============================] - 0s 3ms/step - loss: 193218880.0000 - mae: 9879.5518 - val_loss: 188626656.0000 - val_mae: 9339.9531 Epoch 45/100 24/24 [==============================] - 0s 4ms/step - loss: 187512288.0000 - mae: 9696.0898 - val_loss: 183381088.0000 - val_mae: 9174.8506 Epoch 46/100 24/24 [==============================] - 0s 3ms/step - loss: 181829760.0000 - mae: 9505.8057 - val_loss: 178038800.0000 - val_mae: 9007.2891 Epoch 47/100 24/24 [==============================] - 0s 3ms/step - loss: 176051024.0000 - mae: 9314.3721 - val_loss: 172765568.0000 - val_mae: 8845.7617 Epoch 48/100 24/24 [==============================] - 0s 4ms/step - loss: 170342736.0000 - mae: 9126.3125 - val_loss: 167594320.0000 - val_mae: 8682.2070 Epoch 49/100 24/24 [==============================] - 0s 3ms/step - loss: 164712736.0000 - mae: 8933.8652 - val_loss: 162215952.0000 - val_mae: 8508.7910 Epoch 50/100 24/24 [==============================] - 0s 4ms/step - loss: 159002160.0000 - mae: 8743.4521 - val_loss: 157105120.0000 - val_mae: 8346.0391 Epoch 51/100 24/24 [==============================] - 0s 3ms/step - loss: 153383632.0000 - mae: 8549.1221 - val_loss: 151866928.0000 - val_mae: 8176.3745 Epoch 52/100 24/24 [==============================] - 0s 5ms/step - loss: 147751280.0000 - mae: 8351.1963 - val_loss: 146628912.0000 - val_mae: 8006.8911 Epoch 53/100 24/24 [==============================] - 0s 15ms/step - loss: 142311600.0000 - mae: 8158.2930 - val_loss: 141649424.0000 - val_mae: 7839.0576 Epoch 54/100 24/24 [==============================] - 0s 7ms/step - loss: 137052288.0000 - mae: 7968.6030 - val_loss: 136781648.0000 - val_mae: 7673.2632 Epoch 55/100 24/24 [==============================] - 0s 3ms/step - loss: 131805904.0000 - mae: 7776.8003 - val_loss: 131958016.0000 - val_mae: 7506.0562 Epoch 56/100 24/24 [==============================] - 0s 3ms/step - loss: 126633736.0000 - mae: 7588.6479 - val_loss: 127325848.0000 - val_mae: 7339.7520 Epoch 57/100 24/24 [==============================] - 0s 4ms/step - loss: 121830688.0000 - mae: 7398.9072 - val_loss: 122614352.0000 - val_mae: 7165.6499 Epoch 58/100 24/24 [==============================] - 0s 3ms/step - loss: 116867616.0000 - mae: 7212.1631 - val_loss: 118210936.0000 - val_mae: 6997.6812 Epoch 59/100 24/24 [==============================] - 0s 4ms/step - loss: 112218944.0000 - mae: 7029.5034 - val_loss: 113806984.0000 - val_mae: 6825.0791 Epoch 60/100 24/24 [==============================] - 0s 3ms/step - loss: 107603248.0000 - mae: 6847.2158 - val_loss: 109771576.0000 - val_mae: 6672.4443 Epoch 61/100 24/24 [==============================] - 0s 3ms/step - loss: 103244584.0000 - mae: 6683.3677 - val_loss: 105706608.0000 - val_mae: 6524.2261 Epoch 62/100 24/24 [==============================] - 0s 3ms/step - loss: 99132856.0000 - mae: 6517.2505 - val_loss: 101598928.0000 - val_mae: 6364.3096 Epoch 63/100 24/24 [==============================] - 0s 4ms/step - loss: 94970952.0000 - mae: 6355.7822 - val_loss: 98016152.0000 - val_mae: 6222.1416 Epoch 64/100 24/24 [==============================] - 0s 3ms/step - loss: 91231920.0000 - mae: 6205.1357 - val_loss: 94391016.0000 - val_mae: 6073.1323 Epoch 65/100 24/24 [==============================] - 0s 3ms/step - loss: 87387648.0000 - mae: 6050.4199 - val_loss: 90797160.0000 - val_mae: 5926.0024 Epoch 66/100 24/24 [==============================] - 0s 4ms/step - loss: 83801384.0000 - mae: 5911.8970 - val_loss: 87456216.0000 - val_mae: 5787.4624 Epoch 67/100 24/24 [==============================] - 0s 4ms/step - loss: 80357032.0000 - mae: 5770.2314 - val_loss: 84332704.0000 - val_mae: 5654.8472 Epoch 68/100 24/24 [==============================] - 0s 4ms/step - loss: 77195456.0000 - mae: 5631.3193 - val_loss: 81285416.0000 - val_mae: 5519.2588 Epoch 69/100 24/24 [==============================] - 0s 4ms/step - loss: 74181616.0000 - mae: 5500.9248 - val_loss: 78512632.0000 - val_mae: 5397.8213 Epoch 70/100 24/24 [==============================] - 0s 4ms/step - loss: 71399392.0000 - mae: 5376.7144 - val_loss: 75814560.0000 - val_mae: 5279.1787 Epoch 71/100 24/24 [==============================] - 0s 3ms/step - loss: 68731824.0000 - mae: 5250.6655 - val_loss: 73385264.0000 - val_mae: 5164.4263 Epoch 72/100 24/24 [==============================] - 0s 4ms/step - loss: 66265680.0000 - mae: 5141.7153 - val_loss: 70985144.0000 - val_mae: 5072.7891 Epoch 73/100 24/24 [==============================] - 0s 4ms/step - loss: 63865572.0000 - mae: 5033.4941 - val_loss: 68804264.0000 - val_mae: 4990.0488 Epoch 74/100 24/24 [==============================] - 0s 3ms/step - loss: 61669300.0000 - mae: 4936.6753 - val_loss: 66616820.0000 - val_mae: 4909.1758 Epoch 75/100 24/24 [==============================] - 0s 4ms/step - loss: 59600328.0000 - mae: 4844.8169 - val_loss: 64678952.0000 - val_mae: 4847.2295 Epoch 76/100 24/24 [==============================] - 0s 4ms/step - loss: 57748048.0000 - mae: 4766.2852 - val_loss: 62831856.0000 - val_mae: 4788.0566 Epoch 77/100 24/24 [==============================] - 0s 3ms/step - loss: 55978840.0000 - mae: 4693.2549 - val_loss: 61138988.0000 - val_mae: 4733.3950 Epoch 78/100 24/24 [==============================] - 0s 4ms/step - loss: 54305580.0000 - mae: 4625.1113 - val_loss: 59558924.0000 - val_mae: 4679.4077 Epoch 79/100 24/24 [==============================] - 0s 4ms/step - loss: 52743128.0000 - mae: 4570.7480 - val_loss: 57956868.0000 - val_mae: 4630.3262 Epoch 80/100 24/24 [==============================] - 0s 3ms/step - loss: 51295348.0000 - mae: 4522.2739 - val_loss: 56563732.0000 - val_mae: 4583.4443 Epoch 81/100 24/24 [==============================] - 0s 4ms/step - loss: 49967028.0000 - mae: 4478.7407 - val_loss: 55256244.0000 - val_mae: 4536.0591 Epoch 82/100 24/24 [==============================] - 0s 3ms/step - loss: 48723444.0000 - mae: 4436.0522 - val_loss: 54030732.0000 - val_mae: 4496.7080 Epoch 83/100 24/24 [==============================] - 0s 4ms/step - loss: 47607720.0000 - mae: 4397.7729 - val_loss: 52838856.0000 - val_mae: 4457.5830 Epoch 84/100 24/24 [==============================] - 0s 3ms/step - loss: 46555212.0000 - mae: 4364.5078 - val_loss: 51807856.0000 - val_mae: 4426.5640 Epoch 85/100 24/24 [==============================] - 0s 3ms/step - loss: 45606780.0000 - mae: 4334.0249 - val_loss: 50827476.0000 - val_mae: 4393.8535 Epoch 86/100 24/24 [==============================] - 0s 4ms/step - loss: 44714728.0000 - mae: 4307.4604 - val_loss: 49917180.0000 - val_mae: 4365.0024 Epoch 87/100 24/24 [==============================] - 0s 3ms/step - loss: 43917060.0000 - mae: 4287.4868 - val_loss: 49070520.0000 - val_mae: 4346.1450 Epoch 88/100 24/24 [==============================] - 0s 3ms/step - loss: 43161264.0000 - mae: 4267.1626 - val_loss: 48292316.0000 - val_mae: 4328.0166 Epoch 89/100 24/24 [==============================] - 0s 3ms/step - loss: 42456712.0000 - mae: 4254.2334 - val_loss: 47557792.0000 - val_mae: 4314.3003 Epoch 90/100 24/24 [==============================] - 0s 3ms/step - loss: 41833936.0000 - mae: 4242.4316 - val_loss: 46893772.0000 - val_mae: 4299.5166 Epoch 91/100 24/24 [==============================] - 0s 3ms/step - loss: 41240580.0000 - mae: 4231.1001 - val_loss: 46278236.0000 - val_mae: 4285.2363 Epoch 92/100 24/24 [==============================] - 0s 3ms/step - loss: 40719432.0000 - mae: 4226.0356 - val_loss: 45693584.0000 - val_mae: 4276.3940 Epoch 93/100 24/24 [==============================] - 0s 4ms/step - loss: 40220296.0000 - mae: 4220.7168 - val_loss: 45120600.0000 - val_mae: 4267.1113 Epoch 94/100 24/24 [==============================] - 0s 3ms/step - loss: 39756344.0000 - mae: 4217.3608 - val_loss: 44617428.0000 - val_mae: 4261.2793 Epoch 95/100 24/24 [==============================] - 0s 4ms/step - loss: 39327236.0000 - mae: 4208.3306 - val_loss: 44190656.0000 - val_mae: 4252.0391 Epoch 96/100 24/24 [==============================] - 0s 3ms/step - loss: 38952060.0000 - mae: 4206.3081 - val_loss: 43728744.0000 - val_mae: 4246.5986 Epoch 97/100 24/24 [==============================] - 0s 4ms/step - loss: 38572184.0000 - mae: 4198.7144 - val_loss: 43350212.0000 - val_mae: 4241.7441 Epoch 98/100 24/24 [==============================] - 0s 3ms/step - loss: 38272360.0000 - mae: 4199.6626 - val_loss: 42952100.0000 - val_mae: 4241.5894 Epoch 99/100 24/24 [==============================] - 0s 4ms/step - loss: 37951040.0000 - mae: 4196.4678 - val_loss: 42595540.0000 - val_mae: 4237.7051 Epoch 100/100 24/24 [==============================] - 0s 4ms/step - loss: 37669696.0000 - mae: 4190.8159 - val_loss: 42283788.0000 - val_mae: 4233.1113 13/13 [==============================] - 0s 2ms/step
df_historico = pd.DataFrame(historico_epochs.history)
df_historico.info()
df_historico[['loss','val_loss']].plot()
plt.show();
<class 'pandas.core.frame.DataFrame'> RangeIndex: 100 entries, 0 to 99 Data columns (total 4 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 loss 100 non-null float64 1 mae 100 non-null float64 2 val_loss 100 non-null float64 3 val_mae 100 non-null float64 dtypes: float64(4) memory usage: 3.2 KB
# Metricas para regressão linear
metricas(X_train_scaled, y_train, y_test, y_pr, model_rn, "rede neural")
30/30 [==============================] - 0s 2ms/step MSE do TREINO (rede neural): 38467686.13248875 MSE do TESTE (rede neural): 44636508.86689253 MAE do TREINO (rede neural): 4196.846846059544 MAE do TESTE (rede neural): 4426.687228262982 R² do TREINO (rede neural): 0.7167133880635896 R² do TESTE (rede neural): 0.7391473478444126
Desafio¶
otimize o treinamento do modelo alterando a quantidade de camadas, a quantidade de neuronios, o tipo de ativacao ...
Desafio¶
Aplicação em Marketing
As análises preditivas têm uma variedade de aplicações no marketing, ajudando as empresas a entenderem o comportamento do consumidor, otimizar estratégias de vendas e melhorar o retorno sobre o investimento em publicidade. O potencial das aplicações é vasto, incluindo, mas não se limitando, a previsão de demanda, segmentação de mercado, recomendação de produtos e otimização de preços. As aplicações listadas podem ser tratadas como problemas supervisionados, não supervisionados e até mesmo análises estatísticas clássicas. Tudo depende do objetivo principal da demanda.
Definição do problema e dos dados¶
Nosso case tem como objetivo representar o impacto dos investimentos em publicidade nos resultados de vendas de um produto ou serviço. Esse problema é relevante no marketing porque as empresas precisam entender como a alocação de recursos em diferentes canais de publicidade afeta suas vendas, para otimizar suas estratégias de marketing e maximizar o retorno sobre o investimento.
Para esta modelagem utilizaremos outra base de dados clássica. As variáveis que a compõem são:
- TV: Valor gasto em publicidade na televisão.
- Radio: Valor gasto em publicidade no rádio.
- Newspaper: Valor gasto em publicidade em jornais.
- Sales: Número de vendas do produto ou serviço.
Essas variáveis representam os diferentes canais de publicidade e as vendas associadas àquela alocação, permitindo que os analistas e profissionais de marketing avaliem o impacto de cada canal nas vendas totais.
# Lendo o dataset
df = pd.read_csv("advertising.csv")
df.head()
Problema de Classificação¶
Definição do problema e dos dados
O problema em questão é de classificação binária, onde o objetivo é prever se um colaborador irá deixar a empresa ou não. Essa previsão é útil para o departamento de recursos humanos, pois permite identificar antecipadamente os funcionários com maior probabilidade de sair, possibilitando a implementação de medidas preventivas para retenção de talentos.
As variáveis que compõem a base e suas respectivas descrições são:
- satisfaction_level: Nível de satisfação do colaborador com o trabalho, geralmente medido através de pesquisas de satisfação ou avaliações internas.
- last_evaluation: Última avaliação de desempenho do colaborador, que pode ser realizada periodicamente pela empresa para acompanhar o progresso e a performance.
- number_project: Número de projetos em que o colaborador está atualmente envolvido, fornecendo uma medida da carga de trabalho e da diversidade de responsabilidades.
- average_montly_hours: Média de horas trabalhadas por mês pelo colaborador, um indicador do seu nível de envolvimento e dedicação ao trabalho.
- time_spend_company: Tempo de permanência do colaborador na empresa, em anos, que pode influenciar sua propensão a deixar a organização.
- Work_accident: Indicador binário que representa se o colaborador sofreu algum acidente de trabalho durante seu período na empresa.
- left: Variável de destino binária que indica se o colaborador deixou a empresa (1) ou permaneceu (0).
- promotion_last_5years: Indica se o colaborador recebeu alguma promoção nos últimos cinco anos, o que pode influenciar sua satisfação e lealdade.
- sales: Departamento em que o colaborador trabalha, fornecendo informações sobre a área de atuação e a equipe em que está inserido.
- salary: Nível salarial do colaborador, que pode ser classificado em baixo, médio ou alto, oferecendo uma indicação do seu status e remuneração na empresa.
# Carregando o dataset
data = pd.read_csv('turnover.csv')
data.head()
satisfaction_level | last_evaluation | number_project | average_montly_hours | time_spend_company | Work_accident | left | promotion_last_5years | sales | salary | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 0.38 | 0.53 | 2 | 157 | 3 | 0 | 1 | 0 | sales | low |
1 | 0.80 | 0.86 | 5 | 262 | 6 | 0 | 1 | 0 | sales | medium |
2 | 0.11 | 0.88 | 7 | 272 | 4 | 0 | 1 | 0 | sales | medium |
3 | 0.72 | 0.87 | 5 | 223 | 5 | 0 | 1 | 0 | sales | low |
4 | 0.37 | 0.52 | 2 | 159 | 3 | 0 | 1 | 0 | sales | low |
# Removendo duplicatas
data.drop_duplicates(inplace=True)
# Criando o LabelEncoder
le = LabelEncoder()
# Convertendo strings em números
data['salary'] = le.fit_transform(data['salary'])
data['sales'] = le.fit_transform(data['sales'])
# Separando features do label
X = data.drop(columns=["left"])
y = data["left"]
# Dividindo os dados em TREINO e TESTE
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.3,
random_state=42)
# Padronização dos dados
ss = StandardScaler()
X_train_scaled = ss.fit_transform(X_train)
X_test_scaled = ss.transform(X_test)
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
# Modelo baseline: regressão logística
logreg = LogisticRegression()
logreg.fit(X_train_scaled, y_train)
y_pred_logreg = logreg.predict(X_test_scaled)
# Calcula a acurácia da predição
accuracy_logreg = accuracy_score(y_test, y_pred_logreg)
print("ACC (regressão logística):", accuracy_logreg)
ACC (regressão logística): 0.8315730961645359
Dense(1, activation='sigmoid'): Esta configuração na última camada utiliza a função de ativação 'sigmoid' para produzir uma probabilidade como saída.
loss='binary_crossentropy': Essa função de perda é adequada para problemas de classificação binária, onde as classes são mutuamente exclusivas.
metrics=['accuracy']: A acurácia é uma métrica útil para avaliação em tarefas de classificação, indicando a porcentagem de classificações corretas.
import tensorflow as tf
# Cria o modelo de rede neural
# aqui devemos definir ao menos a quantidade de camadas, a quantidade de neuronios, o tipo de ativacao ...
model_rn = tf.keras.models.Sequential([
tf.keras.layers.Dense(64, activation='relu', input_shape=[X_train_scaled.shape[1]]),
tf.keras.layers.Dense(16, activation='relu'),
tf.keras.layers.Dense(1, activation='sigmoid')
])
# Compila o modelo para classificação binária
model_rn.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
# Treina o modelo
historico_epochs = model_rn.fit(X_train_scaled, y_train, epochs=100, validation_split=0.2)
# Fazendo as predições
y_pr = model_rn.predict(X_test_scaled)
df_historico = pd.DataFrame(historico_epochs.history)
df_historico.info()
df_historico[['loss','val_loss']].plot()
plt.show();
df_historico[['accuracy','val_accuracy']].plot()
plt.show();
<class 'pandas.core.frame.DataFrame'> RangeIndex: 100 entries, 0 to 99 Data columns (total 4 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 loss 100 non-null float64 1 accuracy 100 non-null float64 2 val_loss 100 non-null float64 3 val_accuracy 100 non-null float64 dtypes: float64(4) memory usage: 3.2 KB
# 'y_pr' são as probabilidades previstas pelo seu modelo de forma binaria
y_pred_binario = (y_pr > 0.5).astype(int)
# Calcula a acurácia
accuracy_rn = accuracy_score(y_test, y_pred_binario)
print("Accuracy:", accuracy_rn)
Accuracy: 0.9727626459143969
Desafio¶
otimize o modelo
### seu código...
Problema de Classificação Binária – Churn de Clientes¶
- Contexto: Dataset com informações demográficas e financeiras de clientes de um banco, visando prever se o cliente irá encerrar sua conta (churn).
- Métricas de Avaliação: Acurácia, Precisão, Recall, F1-score e AUC para avaliar a capacidade do modelo em identificar clientes propensos ao churn.
# Carregando o dataset
data = pd.read_csv('Churn_Modelling.csv')
data.head()