Avaliação de Risco de Crédito Usando Random Forest e XGBoost

João Gustavo
Data Hackers
Published in
7 min readJan 29, 2023

--

Photo by Alexander Mils on Unsplash

Quando falamos dos problemas que os bancos, financiadoras e empresários enfrentam, a taxa de inadimplência pode ser considerada um dos maiores.

Como avaliar se uma pessoa irá deixar ou não de cumprir com suas obrigações financeiras, um assunto de extrema importância, que pode causar um grande impacto no balanço da instituição. Consequentemente, cada vez mais soluções são desenvolvidas e aprimoradas a fim de minimizar o risco de default.

Default é o termo utilizado para indicar o não cumprimento das obrigações e/ou condições, por exemplo, de um empréstimo (como financiamentos ou dívidas de cartão de crédito). Contudo, o principal motivo para o descumprimento das condições de pagamento é a incapacidade financeira do cliente e cabe a instituição minimizar o risco de liberar o crédito para esses clientes.

Uma solução que os grandes bancos e Fintechs têm apostado, são os modelos de Machine Learning, a fim de prevenir a inadimplência de alguns clientes.

Dentre as principais instituições financeiras, o Nubank é uma das que mais tem se destacado no uso de Inteligência Artificial e times de Ciência de Dados.

O conjunto de dados utilizado parte de uma antiga competição realizada pelo Nubank, a fim de revelar talentos e potenciais contratações pela Fintech.

Contextualização Do Problema

O problema é a inadimplência e o objetivo é prever qual a probabilidade de um cliente do Nubank, não cumprir com suas obrigações com a instituição e deixar de pagar a fatura do cartão de crédito.

Photo by Lukas Blazek on Unsplash

Podemos ressaltar que essa avaliação é realizada no momento em que o cliente solicita o cartão (possivelmente no primeiro contato com a instituição), porém as análises continuam sendo feitas, mesmo após a liberação do cartão. Dessa forma, o limite pode subir, tanto de empréstimos quanto do cartão de crédito.

O objetivo é encontrar um modelo que minimiza as perdas financeiras, mas que também o mínimo de falsos positivos. Portanto, irei trabalhar com 3 modelos (Random Forest , XGBoost , Logistic Regression).

Vamos dar uma olhada nos dados.

head dataframe

Além disso, o dataset possui 45.000 entradas e 43 colunas, das quais existem algumas desnecessárias para a análise.

Nesse primeiro contato, podemos concluir que:

  • A coluna ids representa, de forma anônima, cada um dos clientes do NuBank. Por não conter informações relevantes, irei excluí-la mais a frente.
  • Diferente de outros datasets que já trabalhei, esse a variável alvo não aparece na última coluna e sim na segunda, como target_default. O objetivo dessa variável é dizer se o respectivo cliente possui risco de inadimplência.
  • As colunas last_amount_borrowed e last_borrowed_in_months, são referentes ao valor do empréstimo e há quantos meses foi o último empréstimo, respectivamente.
  • Outra coluna que podemos ver é a risk_rate, que representa a taxa de risco que um cliente representa, na avaliação de crédito.
  • Existem diversas colunas que apresentam uma codificação como, por exemplo, ⁣score-1, score-2, reason, state, zip, channel, job_name, real_state. Essas são colunas que precisam de uma análise mais minuciosa, a fim de saber se podemos extrair alguma informação.
  • Diferente das colunas score-1 e score-2, as colunas score-3, score-4 e score-5 não apresentam codificação e são numéricas.
  • A coluna lat_lon está em formato string, onde nos mostra coordenadas, possivelmente a localização de onde foi acessado o aplicativo.

Ao olhar o resumo das variáveis numéricas, pude obter algumas informações:

describe dataframe
  • Existem variáveis com valores ausentes, por exemplo, a variável score_3, possui apenas 44438 entradas, enquanto outras variáveis possuem as 45000.
  • A variável external_data_provider_email_seen_before possui um valor mínimo incomum, sendo -999, essa entrada em específico está puxando a média para baixo, dessa forma pode atrapalhar a leitura dos dados, o que irei fazer é substituir os valores menores que 0, por np.nan.
  • A coluna reported_income, possui valores np.inf, que representam um infinito positivo, isso atrapalharia tanto a análise quanto o desempenho do modelo, por isso irei substituir esses valores por np.nan.

Ao verificar a porcentagem de valores ausentes por variável, também foi possível notar que:

  • Diversas variáveis possuem valores ausentes, mesmo que sejam poucos, alguns até mesmo referentes a variáveis categóricas. Porém, existem variáveis numéricas que também apresentam valores ausentes.
  • As variáveis last_amount_borrowed, last_borrowed_in_months, ok_since, external_data_provider_credit_checks_last_2_year e target_fraud possuem mais da metade dos valores ausentes.
  • As variáveis credit_limit, n_issues e external_data_provider_credit_checks_last_year possuem entre 25% e 34% dos valores ausentes.
  • As outras variáveis, com a exceção da variável target_fraud, possuem menos de 10% dos valores ausentes.

O caso com mais valores ausentes é referente a variável target_fraud, porém não é um problema, pois essa variável alvo é irrelevante para a análise do risco de crédito. Porém, todas as outras variáveis representam informações relevantes para a análise e treino do Modelo De Machine Learning.

Após a exclusão dessa coluna, realizei a preparação dos dados, como o tratamento de valores ausentes, valores frequentes, transformação de dados numéricos e categóricos, a divisão entre treino e teste. Assim como, também realizei a padronização dos dados e a validação dos modelos de machine learning.

Por ser uma parte mais maçante da análise de dados, irei deixar o link do notebook para caso queira aprofundar ainda mais!

No balanceamento dos dados, optei por usar o método de Random Under Sampling, por ter uma boa quantidade de dados, com uma grande discrepância. O algoritmo irá realizar a exclusão de dados da classe majoritária, de forma randômica, assim mantendo a integridade dos dados da variável alvo (target_default), uma vez que não irá criar nenhuma entrada nova.

Optei pela exclusão e não pela adição, pois quando usei algoritmos de Over Sampling, onde adicionamos entradas, o desempenho do modelo foi prejudicado.

target_default balanceada

Após o balanceamento e a padronização dos dados, realizei mais uma rodada de validação dos modelos, dessa vez com os dados padronizados e balanceados, a fim de escolher qual seria o melhor algoritmo de padronização para os modelos. O algoritmo escolhido foi o StandardScaler, pois obteve a melhor métrica com os modelos.

Otimizando os Hiperparâmetros

Photo by Markus Winkler on Unsplash

Após todo o trabalho de validação, balanceamento e padronização, irei realizar o ajuste fino dos parâmetros dos modelos, por meio do GridSearchCV, a fim de obter o melhor desempenho possível com cada modelo.

Durante o tuning, pode ser que haja uma diminuição nos valores das métricas, indicando uma diminuição do desempenho do modelo. Porém, quando avaliamos o desempenho com os dados de teste, é possível notar uma métrica próxima do real.

Random Forest

Os parâmetros usados foram:

ran_for_scaled = RandomForestClassifier(n_estimators=200, 
bootstrap=True,
max_depth=20,
max_features="auto",
min_samples_leaf=2,
min_samples_split=5)

Com esses parâmetros obtive os seguintes resultados:

  • AUC: 0.6531
  • Um modelo com resultados bem equilibrados, uma excelente quantidade de verdadeiros negativos (adimplentes) e uma quantidade aceitável de verdadeiros positivos (inadimplentes).
  • Um excesso de falsos positivos, o que resultaria em muitas pessoas que não recebem o crédito, mesmo quando possuem uma boa relação com suas obrigações financeiras.
  • A maior quantidade de falsos negativos dentre os 3 modelos.
Matriz de Confusão (Random Forest)

XGBoost

Os parâmetros usados foram:

XGB_BOO = XGBClassifier(learning_rate=0.01, 
n_estimators=150,
gamma=0,
max_depth=3,
min_child_weight=1)

Com esses parâmetros obtive os seguintes resultados:

  • AUC: 0.6579
  • Um modelo com resultados mais discrepantes, mais uma vez uma excelente quantidade de verdadeiros negativos (adimplentes), a maior dentre os modelos.
  • Uma quantidade maior de verdadeiros positivos (inadimplentes), quando comparado com os outros 2 modelos.
  • Uma quantidade absurda de falsos positivos, porém não é a maior dentre os 3 modelos.
  • A menor quantidade de falsos negativos dentre os 3 modelos.
Matriz de Confusão (XGBoost)

Logistic Regression

Os parâmetros usados foram:

log_reg_scaled = LogisticRegression(penalty='l2', 
C=0.2,
fit_intercept=False,
class_weight='balanced',
multi_class='multinomial',
solver='newton-cg')

Com esses parâmetros obtive os seguintes resultados:

  • AUC: 0.6202
  • Um modelo com resultados ainda mais discrepantes, seguindo com uma excelente quantidade de verdadeiros negativos (adimplentes).
  • A menor quantidade de verdadeiros positivos (inadimplentes).
  • Uma quantidade absurda de falsos positivos, a maior dos 3 modelos.
Matriz de Confusão (Regressão Logística)

Conclusão

Esse tipo de avaliação de Risco de Crédito é comum em bancos, a fim de identificar qual a probabilidade de um cliente se tornar inadimplente. Dessa forma, é possível separar em grupos de risco, onde cada grupo terá uma quantidade específica de crédito liberado ou não terá crédito algum, conforme o risco que representa para a instituição financeira.

O modelo com o melhor resultado foi o XGBOOST. Porém, outro excelente modelo foi o de Random Forest, certamente são modelos que poderiam ter um estudo e trabalho mais aprofundado, melhorando ainda mais seus resultados.

A fim de melhorar os resultados, aqui vão algumas possíveis soluções, onde caberia um estudo mais aprofundado:

  • Poderia ser feito um trabalho de feature engineering melhor, trabalhando com mais correlações entre as variáveis, para o modelo obter um melhor desempenho.
  • Estudar modelos que desempenhar melhor lidando com esses dados, por exemplo, modelos que usam aprendizado profundo, ao invés de modelos mais simples!
  • Usar outra plataforma para realizar o tuning e até mesmo a construção dos modelos, uma vez que a versão gratuita do colab possui muitas limitações.

Para ter acesso ao projeto completo, clique aqui! Aproveita para me seguir no LinkedIn e fica de olho no meu GitHub, lá você poderá encontrar mais projetos futuramente.

--

--