Criação de Features Derivadas
Objetivos de Aprendizagem
- ✅ Criar features derivadas relevantes
- ✅ Codificar variáveis categóricas
- ✅ Identificar features importantes
- ✅ Preparar dataset final
# Ambiente: Python 3.8+, libs: pandas, numpy, scikit-learn
# Carregar dados pré-processados
import pandas as pd
import numpy as np
print("=" * 60)
print("📂 CARREGAMENTO DE DADOS PRÉ-PROCESSADOS")
print("=" * 60)
# Verificar se dataset está carregado (do notebook anterior ou carregar agora)
try:
_ = df.shape
print(f"✅ Dataset já carregado em memória")
print(f" Dimensões: {df.shape[0]:,} registros × {df.shape[1]} colunas")
except (NameError, AttributeError):
print("📂 Dataset não encontrado em memória. Carregando arquivo pré-processado...")
# Carregar dataset pré-processado do notebook 03
try:
df = pd.read_csv("credit_risk_preprocessed.csv")
print(f"✅ Dataset pré-processado carregado com sucesso!")
print(f" Arquivo: credit_risk_preprocessed.csv")
print(f" Dimensões: {len(df):,} registros × {df.shape[1]} colunas")
print(f" Valores ausentes: {df.isnull().sum().sum():,}")
except FileNotFoundError:
print("⚠️ Arquivo 'credit_risk_preprocessed.csv' não encontrado!")
print(" Por favor, execute o notebook 03 (Pré-processamento) primeiro para gerar o arquivo pré-processado.")
raise FileNotFoundError("Arquivo credit_risk_preprocessed.csv não encontrado. Execute o notebook 03 primeiro.")
print("=" * 60)
============================================================ 📂 CARREGAMENTO DE DADOS PRÉ-PROCESSADOS ============================================================ ✅ Dataset já carregado em memória Dimensões: 1,148,198 registros × 18 colunas ============================================================
1. Criação de Features Derivadas
📊 Por que criar features derivadas?
Features derivadas são variáveis criadas a partir das variáveis originais que capturam relações e padrões que podem ser mais informativos para o modelo do que as variáveis individuais. Elas ajudam o modelo a entender melhor o problema de negócio.
🎯 Features que serão criadas
1. Razão Empréstimo/Renda (razao_emprestimo_renda)
- Fórmula:
valor_emprestimo / renda - Hipótese: Pessoas que solicitam empréstimos muito grandes em relação à sua renda têm maior risco de inadimplência, pois podem ter dificuldade para pagar as parcelas.
- Benefício: Captura a capacidade de pagamento de forma relativa, mais informativa que valor absoluto do empréstimo ou renda isoladamente.
- Exemplo: Um empréstimo de R$ 50.000 para quem ganha R$ 5.000/mês (razão = 10) é mais arriscado que R$ 50.000 para quem ganha R$ 20.000/mês (razão = 2.5).
2. Comprometimento Mensal (comprometimento_mensal)
- Fórmula:
(valor_emprestimo / prazo_emprestimo) / renda - Hipótese: O percentual da renda comprometido com a parcela mensal do empréstimo é um forte indicador de risco. Quanto maior o comprometimento, maior a probabilidade de default.
- Benefício: Mede diretamente o impacto financeiro mensal do empréstimo na vida do cliente, considerando tanto o valor quanto o prazo.
- Exemplo: Uma parcela de R$ 1.000 para quem ganha R$ 3.000/mês (33% comprometido) é mais arriscado que R$ 1.000 para quem ganha R$ 10.000/mês (10% comprometido).
3. É Jovem (e_jovem)
- Fórmula:
1 se idade < 25, 0 caso contrário - Hipótese: Pessoas muito jovens podem ter menos experiência financeira, histórico de crédito mais curto e renda instável, aumentando o risco de inadimplência.
- Benefício: Cria uma feature binária que captura um padrão não-linear relacionado à idade, que pode ser mais fácil para o modelo interpretar do que a idade contínua.
- Exemplo: Um cliente de 22 anos pode ter perfil de risco diferente de um de 30 anos, mesmo com outras características similares.
4. Score Normalizado (score_normalizado)
- Fórmula:
(score_credito - min) / (max - min)(normalização min-max) - Hipótese: A normalização facilita a comparação e pode melhorar a performance de alguns algoritmos que são sensíveis à escala das variáveis.
- Benefício: Coloca o score de crédito em uma escala de 0 a 1, facilitando a interpretação e melhorando a convergência de algoritmos como redes neurais e regressão logística.
- Exemplo: Um score de 650 em uma escala de 300-850 se torna 0.636 após normalização, facilitando comparações.
💡 Benefícios Gerais da Engenharia de Features
- Captura de Relações de Negócio: Features derivadas incorporam conhecimento de domínio que o modelo pode não descobrir sozinho.
- Melhora de Performance: Features bem criadas podem melhorar significativamente a acurácia do modelo.
- Interpretabilidade: Features derivadas são geralmente mais fáceis de interpretar e explicar para stakeholders.
- Redução de Dimensionalidade: Uma feature derivada pode ser mais informativa que múltiplas features originais.
⚠️ Cuidados Importantes
- Evitar vazamento de dados: Não usar informações do futuro para prever o presente.
- Validação: Testar se as features realmente melhoram o modelo.
- Overfitting: Muitas features podem levar a overfitting, especialmente com poucos dados.
# Criar features derivadas
print("🔧 CRIANDO FEATURES DERIVADAS")
print("=" * 60)
# Razão empréstimo/renda
df["razao_emprestimo_renda"] = df["valor_emprestimo"] / (df["renda"] + 1)
print("✅ razao_emprestimo_renda criada")
# Comprometimento mensal
df["comprometimento_mensal"] = (df["valor_emprestimo"] / df["prazo_emprestimo"]) / (df["renda"] + 1)
print("✅ comprometimento_mensal criada")
# É jovem
df["e_jovem"] = (df["idade"] < 25).astype(int)
print("✅ e_jovem criada")
# Score normalizado
score_min = df["score_credito"].min()
score_max = df["score_credito"].max()
df["score_normalizado"] = (df["score_credito"] - score_min) / (score_max - score_min)
print("✅ score_normalizado criada")
print(f"\n📊 Total de features: {df.shape[1]}")
🔧 CRIANDO FEATURES DERIVADAS ============================================================ ✅ razao_emprestimo_renda criada ✅ comprometimento_mensal criada ✅ e_jovem criada ✅ score_normalizado criada 📊 Total de features: 18
2. Codificação de Variáveis Categóricas
📊 Por que codificar variáveis categóricas?
A maioria dos algoritmos de machine learning (como regressão logística, árvores de decisão, redes neurais) trabalha apenas com números. Variáveis categóricas (como "solteiro", "casado", "divorciado") precisam ser convertidas em números para que o modelo possa processá-las.
🎯 Método: One-Hot Encoding
Vamos usar o One-Hot Encoding, que cria uma coluna binária (0 ou 1) para cada categoria. Este método é preferível porque não cria uma ordem artificial entre as categorias.
Como funciona:
- Cada categoria vira uma coluna separada
- A coluna recebe valor 1 se o registro pertence àquela categoria, 0 caso contrário
- Uma categoria é removida para evitar multicolinearidade (dummy variable trap)
Exemplo - Estado Civil:
- Original:
estado_civil = "solteiro" - Após One-Hot:
estado_civil_solteiro = 1,estado_civil_casado = 0,estado_civil_divorciado = 0,estado_civil_viuvo = 0
📋 Variáveis que serão codificadas
1. Gênero (genero_F, genero_M, genero_outro)
- Valores originais: "F", "M", "outro"
- Hipótese: O gênero pode estar relacionado a padrões de comportamento financeiro e risco de crédito.
- Benefício: Converte a variável categórica em colunas binárias, permitindo que o modelo aprenda padrões específicos para cada categoria sem criar ordem artificial.
- Exemplo: Para "F":
genero_F = 1,genero_M = 0,genero_outro = 0
2. Estado Civil (estado_civil_solteiro, estado_civil_casado, estado_civil_divorciado, estado_civil_viuvo)
- Valores originais: "solteiro", "casado", "divorciado", "viuvo"
- Hipótese: O estado civil pode influenciar a estabilidade financeira e capacidade de pagamento. Pessoas casadas podem ter maior estabilidade, enquanto divorciados podem ter compromissos financeiros adicionais.
- Benefício: Captura informações sobre estabilidade e responsabilidades financeiras, permitindo que o modelo aprenda efeitos diferentes para cada estado civil.
- Exemplo: Para "casado":
estado_civil_solteiro = 0,estado_civil_casado = 1,estado_civil_divorciado = 0,estado_civil_viuvo = 0
3. Tipo de Emprego (colunas: tipo_emprego_CLT, tipo_emprego_autonomo, etc.)
- Valores originais: Diferentes tipos de emprego (CLT, autônomo, empresário, etc.)
- Hipótese: O tipo de emprego está relacionado à estabilidade de renda. Empregos formais (CLT) tendem a ser mais estáveis que trabalhos autônomos.
- Benefício: Permite ao modelo considerar a estabilidade e tipo de renda do cliente, aprendendo padrões específicos para cada tipo de emprego.
- Exemplo: Para "CLT":
tipo_emprego_CLT = 1, outras colunas = 0
4. Região (colunas: regiao_Norte, regiao_Sul, etc.)
- Valores originais: Diferentes regiões geográficas
- Hipótese: A região pode estar relacionada a condições econômicas locais, custo de vida e oportunidades de emprego, influenciando o risco de crédito.
- Benefício: Captura efeitos geográficos e econômicos regionais, permitindo que o modelo aprenda padrões específicos por região.
- Exemplo: Para "Sul":
regiao_Sul = 1, outras colunas de região = 0
💡 Vantagens do One-Hot Encoding
- Sem Ordem Artificial: Não cria relações de ordem entre categorias que não existem na realidade. Cada categoria é tratada de forma independente.
- Compatibilidade Universal: Funciona bem com praticamente todos os algoritmos de ML (regressão logística, redes neurais, SVM, árvores, etc.).
- Interpretabilidade: Os coeficientes do modelo são mais fáceis de interpretar - cada coluna representa diretamente uma categoria.
- Flexibilidade: Permite que o modelo aprenda efeitos diferentes para cada categoria sem restrições.
⚠️ Limitações e Considerações
- Aumento de Dimensionalidade: Cria múltiplas colunas (uma por categoria), aumentando o número de features. Para variáveis com muitas categorias, isso pode ser problemático.
- Memória: Ocupa mais espaço em memória que Label Encoding, especialmente com muitas categorias.
- Multicolinearidade: Precisa remover uma categoria (dummy variable trap) para evitar multicolinearidade perfeita em regressão.
- Alta Cardinalidade: Se uma variável tiver muitas categorias (ex: 100+), One-Hot Encoding pode criar muitas colunas e aumentar o risco de overfitting.
🔄 Alternativas (para conhecimento futuro)
- Label Encoding: Atribui números sequenciais (útil apenas para árvores quando ordem não importa)
- Target Encoding: Usa a média do target por categoria (pode causar overfitting, precisa validação cruzada)
- Frequency Encoding: Substitui categorias pela frequência de ocorrência
- Embedding: Para muitas categorias, pode usar embeddings (técnica avançada)
✅ Quando usar One-Hot Encoding?
- ✅ Variáveis categóricas nominais (sem ordem natural)
- ✅ Poucas categorias (< 20 por variável)
- ✅ Algoritmos como regressão logística, redes neurais, SVM
- ✅ Quando queremos que o modelo aprenda efeitos independentes para cada categoria
- ✅ Quando a interpretabilidade é importante
# Codificação de variáveis categóricas usando One-Hot Encoding
print("🔧 CODIFICAÇÃO DE VARIÁVEIS CATEGÓRICAS (ONE-HOT ENCODING)")
print("=" * 60)
# Verificar se df está disponível
try:
_ = df.shape
except NameError:
raise NameError("Dataset 'df' não encontrado. Execute a célula anterior primeiro!")
categorical_cols = ["genero", "estado_civil", "tipo_emprego", "regiao"]
features_before = df.shape[1]
print(f"\n📊 Features antes da codificação: {features_before}")
# Aplicar One-Hot Encoding
for col in categorical_cols:
if col in df.columns:
# Contar categorias antes
n_categories = df[col].nunique()
print(f"\n📋 Processando '{col}':")
print(f" - Categorias únicas: {n_categories}")
# Aplicar One-Hot Encoding usando pandas.get_dummies
# drop_first=True remove a primeira categoria para evitar multicolinearidade
dummies = pd.get_dummies(df[col], prefix=col, drop_first=True)
# Adicionar colunas ao dataframe
df = pd.concat([df, dummies], axis=1)
# Remover coluna original
df = df.drop(columns=[col])
# Mostrar colunas criadas
new_cols = dummies.columns.tolist()
print(f" - Colunas criadas: {len(new_cols)}")
print(f" - Exemplos: {', '.join(new_cols[:3])}{'...' if len(new_cols) > 3 else ''}")
print(f" ✅ {col} codificado com sucesso!")
else:
print(f"⚠️ Coluna '{col}' não encontrada no dataset")
features_after = df.shape[1]
features_added = features_after - features_before
print(f"\n📊 Resumo da codificação:")
print(f" - Features antes: {features_before}")
print(f" - Features depois: {features_after}")
print(f" - Features adicionadas: {features_added}")
print(f" - Features removidas (originais): {len(categorical_cols)}")
🔧 CODIFICAÇÃO DE VARIÁVEIS CATEGÓRICAS (ONE-HOT ENCODING) ============================================================ 📊 Features antes da codificação: 18 📋 Processando 'genero': - Categorias únicas: 3 - Colunas criadas: 2 - Exemplos: genero_m, genero_outro ✅ genero codificado com sucesso! 📋 Processando 'estado_civil': - Categorias únicas: 4 - Colunas criadas: 3 - Exemplos: estado_civil_divorciado, estado_civil_solteiro, estado_civil_viuvo ✅ estado_civil codificado com sucesso! 📋 Processando 'tipo_emprego': - Categorias únicas: 46 - Colunas criadas: 45 - Exemplos: tipo_emprego_CLT, tipo_emprego_DESEMPREGADO, tipo_emprego_PUBLICO... ✅ tipo_emprego codificado com sucesso! 📋 Processando 'regiao': - Categorias únicas: 46 - Colunas criadas: 45 - Exemplos: regiao_NORDESTE, regiao_NORTE, regiao_SUDESTE... ✅ regiao codificado com sucesso! 📊 Resumo da codificação: - Features antes: 18 - Features depois: 109 - Features adicionadas: 91 - Features removidas (originais): 4
# Salvar dataset com features de engenharia para uso nos próximos notebooks
print("💾 SALVANDO DATASET COM FEATURES DE ENGENHARIA")
print("=" * 60)
# Nome do arquivo de saída
output_filename = "credit_risk_features_engineered.csv"
# Salvar o dataset
df.to_csv(output_filename, index=False)
print(f"\n✅ Dataset salvo com sucesso!")
print(f" - Arquivo: {output_filename}")
print(f" - Registros: {len(df):,}")
print(f" - Features: {df.shape[1]}")
print(f" - Valores ausentes: {df.isnull().sum().sum():,}")
if 'default' in df.columns:
default_rate = df['default'].mean()
print(f"\n✅ Variável target (default):")
print(f" - Taxa de default: {default_rate:.2%}")
print(f" - Total de defaults: {df['default'].sum():,}")
print(f" - Total de não-defaults: {(df['default'] == 0).sum():,}")
print(f"\n📝 O dataset com features de engenharia está pronto para ser usado nos próximos notebooks de modelagem.")
💾 SALVANDO DATASET COM FEATURES DE ENGENHARIA ============================================================ ✅ Dataset salvo com sucesso! - Arquivo: credit_risk_features_engineered.csv - Registros: 1,148,198 - Features: 109 - Valores ausentes: 0 ✅ Variável target (default): - Taxa de default: 2.96% - Total de defaults: 33,959 - Total de não-defaults: 1,114,239 📝 O dataset com features de engenharia está pronto para ser usado nos próximos notebooks de modelagem.
💼 Implicações de Negócio
Lição Chave: Um feature engineering bem feito pode dobrar a performance de um modelo. Conheça bem seu domínio de negócio - as melhores features vêm do entendimento do problema, não apenas de transformações matemáticas.