Entenda por que o pré-processamento não é opcional—é o núcleo de qualquer modelo ML bem-sucedido. Aprenda a diagnosticar a saúde do conjunto de dados antes de tocar em qualquer algoritmo.
"Ciência de dados é 80% limpeza de dados, 20% reclamação sobre limpeza de dados." — Anônimo
No mundo real, os dados nunca chegam limpos, ordenados e prontos para uso. Eles chegam com:
NaN, None, "", ?)Consequência direta: Alimentar dados sujos em um modelo faz com que ele aprenda padrões incorretos. Lixo Dentro → Lixo Fora.
Antes de fazer qualquer coisa, explore seu conjunto de dados como um detetive.
import pandas as pd
# Carregar conjunto de dados
df = pd.read_csv("dados_fraude.csv")
# Visualização rápida
print(df.head())
print(df.info()) # Tipos de dados e contagens não nulas
print(df.describe()) # Estatísticas descritivas (apenas numéricas)
# Ver valores únicos em colunas categóricas
print(df['tipo_transacao'].unique())
print(df['pais'].value_counts())
# Verificar valores nulos
print(df.isnull().sum())
import seaborn as sns
import matplotlib.pyplot as plt
# Histograma de uma variável numérica
sns.histplot(df['valor_transacao'], bins=50, kde=True)
plt.title("Distribuição do Valor das Transações")
plt.show()
# Boxplot para detectar outliers
sns.boxplot(x=df['valor_transacao'])
plt.title("Boxplot: Encontrando Outliers nos Valores")
plt.show()
# Gráfico de barras para variáveis categóricas
sns.countplot(data=df, x='tipo_cartao')
plt.title("Distribuição dos Tipos de Cartão")
plt.xticks(rotation=45)
plt.show()
Opção 1: Excluir linhas ou colunas
# Excluir linhas com qualquer NaN
df_clean = df.dropna()
# Excluir colunas com mais de 50% de NaN
df_clean = df.dropna(axis=1, thresh=len(df)*0.5)
⚠️ Cuidado: Apenas aconselhável se você perder poucos pontos de dados. Se você excluir 30% das suas linhas, seu modelo pode se tornar tendencioso.
Opção 2: Imputação (preencher com valores)
from sklearn.impute import SimpleImputer
# Imputar média para variáveis numéricas
imputer_num = SimpleImputer(strategy='mean')
df[['idade', 'valor_transacao']] = imputer_num.fit_transform(df[['idade', 'valor_transacao']])
# Imputar moda para variáveis categóricas
imputer_cat = SimpleImputer(strategy='most_frequent')
df[['tipo_cartao']] = imputer_cat.fit_transform(df[['tipo_cartao']])
✅ Melhor prática: Use ColumnTransformer para aplicar diferentes estratégias a diferentes colunas (abordaremos isso em detalhes no Módulo 3).
Um valor que se desvia significativamente do resto dos dados. Pode ser:
Q1 = df['valor_transacao'].quantile(0.25)
Q3 = df['valor_transacao'].quantile(0.75)
IQR = Q3 - Q1
limite_inferior = Q1 - 1.5 * IQR
limite_superior = Q3 + 1.5 * IQR
outliers = df[(df['valor_transacao'] < limite_inferior) | (df['valor_transacao'] > limite_superior)]
print(f"Outliers detectados: {len(outliers)}")
df['valor_transacao'] = df['valor_transacao'].clip(lower=limite_inferior, upper=limite_superior)
df['log_valor'] = np.log1p(df['valor_transacao']) # log(1+x) para evitar log(0)
Conjunto de dados sugerido: dados_fraude.csv (simulado, com colunas: id_usuario, valor, idade, pais, tipo_cartao, hora_dia, eh_fraude)
Tarefas:
.info() e .describe().valor. Aplique capping baseado em IQR.idade. Há valores impossíveis (ex., idade < 0 ou > 120)? Corrija-os.fraude_limpo.csv.