Logo Passei Direto
Buscar
Material
páginas com resultados encontrados.
páginas com resultados encontrados.

Prévia do material em texto

Classificação
Naive Bayes
Naive Bayes é um algoritmo de machine learning simples e rápido, usado para problemas de 
classificação. Ele é baseado no Teorema de Bayes, da teoria da probabilidade. A palavra “naive” 
(ingênuo) significa que o algoritmo faz uma suposição simples: ele considera que todas as 
características (variáveis) são independentes entre si.
A Fórmula
A fórmula básica do Teorema de Bayes é:
P(A|B) = P(B|A) × P(A) / P(B)
Para classificação, usamos esta versão:
P(classe|características) = P(características|classe) × P(classe) / 
P(características)
O que isso significa?
• P(classe|características): Probabilidade de uma classe dado o conjunto de características 
(o que queremos descobrir)
• P(características|classe): Probabilidade de observar essas características em uma 
determinada classe
• P(classe): Probabilidade da classe (quão comum ela é)
• P(características): Probabilidade das características (podemos ignorar para comparação)
Quando usar Naive Bayes?
O Naive Bayes funciona bem para:
• Classificação de textos – detecção de spam, análise de sentimento, categorização de 
documentos
• Diagnóstico médico – previsão de doenças com base em sintomas
• Sistemas de recomendação – sugestão de produtos ou conteúdos
• Previsões em tempo real – quando você precisa de resultados rápidos
Onde aplicar?
Boas situações:
• Quando você tem dados categóricos (como palavras, categorias, valores sim/não)
• Quando precisa de um algoritmo rápido e que use pouca memória
• Quando tem um conjunto de dados pequeno para treino
• Quando as características são, em grande parte, independentes (ou quando essa 
suposição é aceitável)
Não é ideal para:
• Relações complexas entre as características
• Situações em que é necessária altíssima precisão para decisões críticas
• Dados numéricos contínuos (embora possa ser adaptado)
Tipos de Naive Bayes
• Existem três tipos principais:
• Naive Bayes Gaussiano – para dados numéricos contínuos
• Naive Bayes Multinomial – para dados de contagem (como frequência de palavras)
• Naive Bayes Bernoulli – para dados binários (sim/não, verdadeiro/falso)
Vantagens
• Muito rápido para treinar e fazer previsões
• Funciona bem com conjuntos de dados pequenos
• Simples de entender e implementar
• Bons resultados em classificação de textos
Desvantagens
• A suposição de independência geralmente está errada
• Não consegue aprender relações entre as características
• Nem sempre é o algoritmo mais preciso
Exemplo:
P (C∣X )=P (X∣C )⋅P (C )
P (X )
Onde:
• C = classe (Alto, Moderado, Baixo)
• X = conjunto de atributos (História, Dívida, Garantias, Renda)
• P(C) = probabilidade a priori da classe
• P(X C) = probabilidade dos atributos dado a classe∣
• P(X) = constante de normalização
Na imagem:
P(Alto)=P(Alto) x P(História∣Alto) × P(Dívida∣Alto) × 
P(Garantias∣Alto) × P(Renda∣Alto)
P (A lt o )= 6
14
⋅ 1
6
⋅ 4
6
⋅ 6
6
⋅ 1
6
Carregamento da base de dados
import pandas as pd
import random
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
dataset = pd.read_csv("/content/drive/MyDrive/Estatística para Ciência 
de Dados e Machine Learning/Bases de dados/credit_data.csv")
dataset.shape
(2000, 5)
dataset.head()
{"summary":"{\n \"name\": \"dataset\",\n \"rows\": 2000,\n 
\"fields\": [\n {\n \"column\": \"i#clientid\",\n 
\"properties\": {\n \"dtype\": \"number\",\n \"std\": 
577,\n \"min\": 1,\n \"max\": 2000,\n 
\"num_unique_values\": 2000,\n \"samples\": [\n 1861,\
n 354,\n 1334\n ],\n 
\"semantic_type\": \"\",\n \"description\": \"\"\n }\
n },\n {\n \"column\": \"income\",\n \"properties\": 
{\n \"dtype\": \"number\",\n \"std\": 
14326.32711885004,\n \"min\": 20014.4894700497,\n 
\"max\": 69995.6855783239,\n \"num_unique_values\": 2000,\n 
\"samples\": [\n 40240.7275559381,\n 
46706.4588610083,\n 51211.6540386342\n ],\n 
\"semantic_type\": \"\",\n \"description\": \"\"\n }\
n },\n {\n \"column\": \"age\",\n \"properties\": {\n 
\"dtype\": \"number\",\n \"std\": 13.624469455596008,\n 
\"min\": -52.4232799196616,\n \"max\": 63.971795841120205,\n 
\"num_unique_values\": 1997,\n \"samples\": [\n 
36.6687041711994,\n 43.0130229773931,\n 
32.553030352108195\n ],\n \"semantic_type\": \"\",\n 
\"description\": \"\"\n }\n },\n {\n \"column\": 
\"loan\",\n \"properties\": {\n \"dtype\": \"number\",\n 
\"std\": 3045.4100243915154,\n \"min\": 1.37762959325451,\n 
\"max\": 13766.0512393337,\n \"num_unique_values\": 2000,\n 
\"samples\": [\n 7498.630446855849,\n 
7084.263509070559,\n 4093.360006036261\n ],\n 
\"semantic_type\": \"\",\n \"description\": \"\"\n }\
n },\n {\n \"column\": \"c#default\",\n 
\"properties\": {\n \"dtype\": \"number\",\n \"std\": 
0,\n \"min\": 0,\n \"max\": 1,\n 
\"num_unique_values\": 2,\n \"samples\": [\n 1,\n 
0\n ],\n \"semantic_type\": \"\",\n 
\"description\": \"\"\n }\n }\n ]\
n}","type":"dataframe","variable_name":"dataset"}
dataset.tail()
{"summary":"{\n \"name\": \"dataset\",\n \"rows\": 5,\n \"fields\": 
[\n {\n \"column\": \"i#clientid\",\n \"properties\": {\n 
\"dtype\": \"number\",\n \"std\": 1,\n \"min\": 1996,\n 
\"max\": 2000,\n \"num_unique_values\": 5,\n 
\"samples\": [\n 1997,\n 2000,\n 1998\n 
],\n \"semantic_type\": \"\",\n \"description\": \"\"\n 
}\n },\n {\n \"column\": \"income\",\n \"properties\": 
{\n \"dtype\": \"number\",\n \"std\": 
12770.554147657615,\n \"min\": 43756.0566049069,\n 
\"max\": 69516.1275728606,\n \"num_unique_values\": 5,\n 
\"samples\": [\n 69516.1275728606,\n 
69436.57955154781,\n 44311.44926231349\n ],\n 
\"semantic_type\": \"\",\n \"description\": \"\"\n }\
n },\n {\n \"column\": \"age\",\n \"properties\": {\n 
\"dtype\": \"number\",\n \"std\": 17.724525188227087,\n 
\"min\": 23.162104470655304,\n \"max\": 63.971795841120205,\n 
\"num_unique_values\": 5,\n \"samples\": [\n 
23.162104470655304,\n 56.1526170284487,\n 
28.0171668957919\n ],\n \"semantic_type\": \"\",\n 
\"description\": \"\"\n }\n },\n {\n \"column\": 
\"loan\",\n \"properties\": {\n \"dtype\": \"number\",\n 
\"std\": 2446.0023471942495,\n \"min\": 1622.72259832146,\n 
\"max\": 7378.833598730591,\n \"num_unique_values\": 5,\n 
\"samples\": [\n 3503.1761563262603,\n 
7378.833598730591,\n 5522.786693255141\n ],\n 
\"semantic_type\": \"\",\n \"description\": \"\"\n }\
n },\n {\n \"column\": \"c#default\",\n 
\"properties\": {\n \"dtype\": \"number\",\n \"std\": 
0,\n \"min\": 0,\n \"max\": 1,\n 
\"num_unique_values\": 2,\n \"samples\": [\n 1,\n 
0\n ],\n \"semantic_type\": \"\",\n 
\"description\": \"\"\n }\n }\n ]\n}","type":"dataframe"}
# Checking for null values
dataset.isnull().sum()
i#clientid 0
income 0
age 3
loan 0
c#default 0
dtype: int64
# Deleting Null values
dataset.dropna(inplace=True)
dataset.shape
(1997, 5)
dataset.isnull().sum()
i#clientid 0
income 0
age 0
loan 0
c#default 0
dtype: int64
sns.countplot(x='c#default', data=dataset);
plt.title('Default Status Distribution(0 = Paid, 1 = Not Paid)');
x = dataset.iloc[:, 1:4].values
y = dataset.iloc[:, 4].values
x.shape, y.shape
((1997, 3), (1997,))
Observação.
Quando há valores muito discrepantes entre as variáveis em estudo, o conjunto de dados pode 
tornar-se inadequado para o treinamento do modelo, uma vez que o algoritmo passa a favorecer 
a classe majoritária. Para contornar esse problema, faz-se necessário o uso de técnicas de 
amostragem.
Base de treinamento e teste
x_train, x_test, y_train, y_test = train_test_split(x, y, 
test_size=0.2, stratify=y)
# 80% of dataset for train
x_train.shape, y_train.shape
((1597, 3), (1597,))
# 20% of dataset for test
x_test.shape, y_test.shape
((400, 3), (400,))
np.unique(y, return_counts=True)
(array([0, 1]), array([1714, 283]))
print(f"Paying clients: {(1714 / len(dataset)) * 100:.2f}%")
print(f"Non-paying clients: {(283 / len(dataset)) * 100:.2f}%")
Paying clients: 85.83%
Non-paying clients: 14.17%
np.unique(y_train, return_counts=True)
(array([0, 1]), array([1371, 226]))
print(f"Paying clients: {(1371 / len(y_train)) * 100:.2f}%")
print(f"Non-paying clients: {(226 / len(y_train)) * 100:.2f}%")
Paying clients: 85.85%
Non-paying clients: 14.15%
np.unique(y_test, return_counts=True)
(array([0, 1]), array([343, 57]))
print(f"Paying clients: {(343 / len(y_test)) * 100:.2f}%")
print(f"Non-paying clients: {(57 / len(y_test)) * 100:.2f}%")
Paying clients: 85.75%
Non-paying clients: 14.25%
Observação
Tadas as bases de dados y estão com o mesmo valor percentual, ou seja, a estratificação foi feita 
corretamente, mas mesmo assim ainda temos valores descrepante entre os dois valores.
Classificação com Naive Bayes.
from sklearn.naive_bayes import GaussianNB
model = GaussianNB()
model.fit(x_train, y_train)
GaussianNB()
"""
Predict() is used to train the Naive Bayes model (model) to make 
predictions on the x_test dataset.
This means it's asking the model to classify each instance in the test 
set,
and these predicted classifications are then stored in the forecast 
variable
"""
forecast = model.predict(x_test)
forecast
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 
0,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 
0,
 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0,
 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0,
 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 
0,
 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 
0,
 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 
0,
 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0,
 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0,
 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 
0,
 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 
1,
 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 
0,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 
0,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 
0,
 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 
0,
 0, 0, 0, 0])
# Original data
y_test
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 
1,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 
0,
 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0,
 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 
0,
 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 
0,
 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 
0,
 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 
0,
 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 
0,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0,
 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 
0,
 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0,
 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 
1,
 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 
0,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 
0,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0,
 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 
1,
 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 
0,
 0, 0, 0, 0])
Measuring accuracy between forecast and y_test
from sklearn.metrics import accuracy_score, confusion_matrix
accuracy = accuracy_score(forecast, y_test)
print(f"Accuracy: {accuracy * 100:.2f}%")
Accuracy: 91.75%
# Show the values that were classified correctly
cm = confusion_matrix(y_test, forecast)
print("Confusion Matrix:\n", cm)
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')
plt.xlabel('Predicted')
plt.ylabel('Actual')
plt.title('Confusion Matrix')
plt.show()
Confusion Matrix:
 [[335 8]
 [ 25 32]]
paid_0 = cm[0][0]
paid_1 = cm[0][1]
print("Client who paid off the loan\n")
print(f"Correct Classified: {(paid_0 / (paid_0 + paid_1)*100):.2f}%")
print(f"Incorrect Classified: {(paid_1 / (paid_0 + paid_1)*100):.2f}
%")
Client who paid off the loan
Correct Classified: 97.67%
Incorrect Classified: 2.33%
not_paid_0 = cm[1][0]
not_paid_1 = cm[1][1]
print("Client who paid off the loan\n")
print(f"Correct Classified: {(not_paid_1 / (not_paid_0 + 
not_paid_1)*100):.2f}%")
print(f"Incorrect Classified: {(not_paid_0 / (not_paid_0 + 
not_paid_1)*100):.2f}%")
Client who paid off the loan
Correct Classified: 56.14%
Incorrect Classified: 43.86%
import locale
locale.setlocale(locale.LC_ALL, '')
# Example:
losses = 5000 # monetary value of the loss per person
non_paying_client = 1000
error = (23 / (23 + 34)) * 100
total_non_paying_client = round(non_paying_client * error / 100)
loss_amount = total_non_paying_client * losses
print(f"Total possible customers who will not pay: 
{total_non_paying_client}")
print(f"Possible loss for the bank: {locale.currency(loss_amount, 
grouping=True)}")
Total possible customers who will not pay: 404
Possible loss for the bank: $2,020,000.00
Subamostragem (Undersampling)
• https://imbalanced-learn.org/stable/user_guide.html
Conceito
Subamostragem (Undersampling) é uma técnica utilizada em Machine Learning para lidar com 
conjuntos de dados desbalanceados, ou seja, quando uma classe (a classe majoritária) possui 
significativamente mais amostras do que outra(s) classe(s) (a(s) classe(s) minoritária(s)).
O Problema do Desbalanceamento:
Em muitos problemas de classificação, os modelos tendem a dar mais atenção à classe 
majoritária, resultando em um desempenho ruim na classificação da classe minoritária, que 
pode ser a mais interessante para o problema (por exemplo, detecção de fraude, doenças raras, 
clientes que dão 'default' no crédito).
https://imbalanced-learn.org/stable/user_guide.html
Como Funciona o Undersampling: A ideia principal do undersampling é reduzir o número de 
amostras da classe majoritária para equilibrar a proporção entre as classes. Existem várias 
abordagens para fazer isso:
1. Undersampling Aleatório (Random Undersampling):
– Remove aleatoriamente um certo número de amostras da classe majoritária até 
que a proporção desejada seja atingida. É a forma mais simples e direta.
2. Tomek Links:
– Identifica pares de amostras de classes diferentes que são vizinhos muito 
próximos. Se essas amostras forem de classes diferentes, e a amostra da classe 
majoritária estiver muito próxima da amostra da classe minoritária, a amostra da 
classe majoritária é removida. Isso ajuda a remover ruídose a criar fronteiras de 
decisão mais claras.
3. Edited Nearest Neighbours (ENN):
– Remove uma amostra da classe majoritária se ela não for classificada 
corretamente por seus k-vizinhos mais próximos (que devem ser da mesma 
classe).
4. Condensed Nearest Neighbours (CNN):
– Seleciona um subconjunto de amostras da classe majoritária que, quando 
combinadas com todas as amostras da classe minoritária, são capazes de 
classificar corretamente todas as amostras originais. Isso busca reter as amostras 
mais informativas da classe majoritária.
Vantagens do Undersampling:
• Pode ajudar a melhorar o desempenho do modelo na classe minoritária.
• Reduz o tamanho do dataset, o que pode diminuir o tempo de treinamento e o custo 
computacional, especialmente em datasets muito grandes.
Desvantagens do Undersampling:
• Perda de Informação: A maior desvantagem é a perda de dados valiosos. Ao remover 
amostras da classe majoritária, podemos perder informações importantes e 
representativas sobre essa classe, o que pode levar a um modelo menos robusto ou a um 
overfitting da classe minoritária.
• Pode não ser a melhor opção se a classe majoritária já for pequena ou se a perda de 
dados for crítica.
Quando Usar:
• Undersampling é geralmente considerado quando se tem um dataset muito grande, 
onde a redução do número de amostras da classe majoritária não comprometerá 
significativamente a informação global, ou quando o tempo de treinamento é uma 
preocupação.
• É importante sempre comparar com outras técnicas de balanceamento, como o 
oversampling (SMOTE, por exemplo) ou o uso de pesos de classe, para encontrar a 
melhor estratégia para o seu problema.
Tomek Links Algoritimo
from imblearn.under_sampling import TomekLinks
"""Undersampling"""
tl = TomekLinks(sampling_strategy='majority')
x_under, y_under = tl.fit_resample(x, y) # Uso de fit_resample, que 
retorna apenas X e y reamostrados.
x_under.shape, y_under.shape
((1897, 3), (1897,))
np.unique(y, return_counts=True) # Dataset original
(array([0, 1]), array([1714, 283]))
np.unique(y_under, return_counts=True) # Dataset TomekLinks
(array([0, 1]), array([1614, 283]))
""" Split the dataset """
x_train_tl, x_test_tl, y_train_tl, y_test_tl = 
train_test_split(x_under, y_under, test_size=0.2, stratify=y_under)
x_train_tl.shape, y_train_tl.shape # 80% of dataset for train
((1517, 3), (1517,))
x_test_tl.shape, y_test_tl.shape # 20% of dataset for train
((380, 3), (380,))
""" To Train """
model_u = GaussianNB()
model_u.fit(x_train_tl, y_train_tl)
GaussianNB()
""" Predict """
forecast_tl = model_u.predict(x_test_tl)
accuracy_tl = accuracy_score(forecast_tl, y_test_tl)
print(f"Accuracy: {accuracy_tl * 100:.2f}%")
Accuracy: 90.00%
""" Confusion Matrix """
cm_tl = confusion_matrix(y_test_tl, forecast_tl)
print("Confusion Matrix:\n", cm_tl)
sns.heatmap(cm_tl, annot=True, fmt='d', cmap='Blues')
plt.xlabel('Predicted')
plt.ylabel('Actual')
plt.title('Confusion Matrix')
plt.show()
paid_tl_0 = cm_tl[0][0]
paid_tl_1 = cm_tl[0][1]
print("Client who paid off the loan\n")
print(f"Correct Classified: {(paid_tl_0 / (paid_tl_0 + 
paid_tl_1)*100):.2f}%")
print(f"Incorrect Classified: {(paid_tl_1 / (paid_tl_0 + 
paid_tl_1)*100):.2f}%")
not_paid_tl_0 = cm_tl[1][0]
not_paid_tl_1 = cm_tl[1][1]
print("Client who paid off the loan\n")
print(f"Correct Classified: {(not_paid_tl_1 / (not_paid_tl_0 + 
not_paid_tl_1)*100):.2f}%")
print(f"Incorrect Classified: {(not_paid_tl_0 / (not_paid_tl_0 + 
not_paid_tl_1)*100):.2f}%")
Sobreamostragem (Oversampling)
Conceito
Como Funciona o Oversampling:
A ideia principal do oversampling é aumentar o número de amostras da classe minoritária, 
replicando-as ou gerando novas amostras sintéticas, até que a proporção entre as classes seja 
mais equilibrada. Existem várias técnicas de oversampling, as mais comuns incluem:
1. Oversampling Aleatório (Random Oversampling):
– Simplesmente duplica aleatoriamente as amostras existentes da classe 
minoritária. É a técnica mais direta.
– Vantagem: Fácil de implementar.
– Desvantagem: Pode levar a overfitting, pois o modelo pode memorizar as 
amostras duplicadas, e não contribui com nova informação ou variedade aos 
dados.
2. SMOTE (Synthetic Minority Over-sampling Technique):
– É uma das técnicas de oversampling mais populares e sofisticadas. Em vez de 
simplesmente duplicar, o SMOTE gera novas amostras sintéticas para a classe 
minoritária. Ele faz isso selecionando um k-vizinho mais próximo para cada 
amostra da classe minoritária e criando novas amostras ao longo da linha que une 
a amostra original e seus vizinhos.
– Vantagem: Adiciona variedade aos dados, criando amostras que são ligeiramente 
diferentes das originais, o que pode ajudar a evitar o overfitting e melhorar a 
generalização do modelo.
– Desvantagem: Pode gerar amostras ruidosas ou sobrepor-se à classe majoritária 
em áreas de fronteira mal definidas, especialmente em espaços de alta dimensão.
3. ADASYN (Adaptive Synthetic Sampling):
– Semelhante ao SMOTE, mas gera mais amostras sintéticas para as instâncias da 
classe minoritária que são mais difíceis de classificar (aquelas que estão mais 
próximas da fronteira da classe majoritária). Ele avalia a densidade das amostras 
da classe minoritária em relação à classe majoritária e foca em gerar amostras 
onde a classe minoritária é mais esparsa.
– Vantagem: Adapta a geração de amostras às necessidades do conjunto de dados, 
focando nas áreas mais desafiadoras.
– Desvantagem: Pode ser mais sensível a ruídos e outliers do que o SMOTE.
Vantagens do Oversampling:
• Não há perda de informação, pois todas as amostras existentes são mantidas.
• Pode melhorar significativamente o desempenho do modelo na classe minoritária, 
permitindo que ele aprenda melhor os padrões dessa classe.
• Gera modelos mais equilibrados e justos, especialmente quando a classe minoritária é 
crucial para o problema.
Desvantagens do Oversampling:
• Aumento do Tamanho do Dataset: O principal problema é que ele aumenta o tamanho 
do conjunto de dados, o que pode levar a um aumento no tempo de treinamento e nos 
custos computacionais, especialmente com técnicas como SMOTE e ADASYN.
• Overfitting (em Random Oversampling): O oversampling aleatório pode causar 
overfitting, pois o modelo simplesmente memoriza as amostras duplicadas.
• Geração de Ruído (em SMOTE/ADASYN): Se a classe minoritária já for ruidosa, técnicas 
sintéticas podem amplificar esse ruído ou criar amostras que não são representativas da 
verdadeira distribuição dos dados.
Quando Usar:
• Oversampling é uma escolha comum quando a perda de dados da classe majoritária 
(como ocorreria no undersampling) é inaceitável ou quando o conjunto de dados original 
não é excessivamente grande.
• A escolha da técnica específica (SMOTE, ADASYN, etc.) depende da complexidade do 
problema e das características do desbalanceamento.
SMOTE Algoritmo
from imblearn.over_sampling import SMOTE
smote = SMOTE(sampling_strategy='minority')
x_smote, y_smote = smote.fit_resample(x, y)
x_smote.shape, y_smote.shape
np.unique(y, return_counts=True)
np.unique(y_smote, return_counts=True)
""" Split the dataset """
x_train_sm, x_test_sm, y_train_sm, y_test_sm = 
train_test_split(x_smote, y_smote, test_size=0.2, stratify=y_smote)
train_80 = x_train_sm.shape, y_train_sm.shape
test_20 = x_test_sm.shape, y_test_sm.shape
print(f"Train:{train_80}\nTest: {test_20}")
""" Train """
model_sm = GaussianNB()
model_sm.fit(x_train_sm, y_train_sm)
""" Predict """
forecast_sm = model_sm.predict(x_test_sm)
accuracy_sm = accuracy_score(forecast_sm, y_test_sm)
print(f"Accuracy: {accuracy_sm * 100:.2f}%")
""" Confusion Matrix """
cm_sm = confusion_matrix(y_test_sm, forecast_sm)
print("Confusion Matrix:\n", cm_sm)
sns.heatmap(cm_sm, annot=True, fmt='d', cmap='Blues')
plt.xlabel('Predicted')
plt.ylabel('Actual')
plt.title('Confusion Matrix')
plt.show()
paid_sm_correct = cm_sm[0][0]
paid_sm_incorrect = cm_sm[0][1]
print("Client who paid off the loan\n")print(f"Correct Classified: {(paid_sm_correct / (paid_sm_correct + 
paid_sm_incorrect)*100):.2f}%")
print(f"Incorrect Classified: {(paid_sm_incorrect / (paid_sm_correct + 
paid_sm_incorrect)*100):.2f}%")
non_paid_sm_incorrect = cm_sm[1][0]
non_paid_sm_correct = cm_sm[1][1]
print("Client who paid off the loan\n")
print(f"Correct Classified: {(non_paid_sm_correct / 
(non_paid_sm_incorrect + non_paid_sm_correct)*100):.2f}%")
print(f"Incorrect Classified: {(non_paid_sm_incorrect / 
(non_paid_sm_incorrect + non_paid_sm_correct)*100):.2f}%")
#
import locale
locale.setlocale(locale.LC_ALL, '')
# Example:
losses = 5000 # monetary value of the loss per person
non_paying_client = 1000
error = (non_paid_sm_incorrect / (non_paid_sm_incorrect + 
non_paid_sm_correct)*100)
total_non_paying_client = round(non_paying_client * error / 100)
loss_amount = total_non_paying_client * losses
print(f"Total possible customers who will not pay: 
{total_non_paying_client}")
print(f"Possible loss for the bank: {locale.currency(loss_amount, 
grouping=True)}")
	Classificação
	Naive Bayes
	A Fórmula
	O que isso significa?
	Quando usar Naive Bayes?
	Onde aplicar?
	Tipos de Naive Bayes
	Vantagens
	Desvantagens
	Exemplo:
	Carregamento da base de dados
	Observação.
	Base de treinamento e teste
	Observação
	Classificação com Naive Bayes.
	Measuring accuracy between forecast and y_test
	Subamostragem (Undersampling)
	Conceito
	Tomek Links Algoritimo
	Sobreamostragem (Oversampling)
	Conceito
	SMOTE Algoritmo

Mais conteúdos dessa disciplina