WoE em R com tidywoe

WoE (weight of evidence) é uma ferramenta bastante usada em aplicações de regressão logística, principalmente na área de score de crédito. Simploriamente falando, ele transforma categorias em números que refletem a diferença entre elas pelo critério de separação do Y = 1 e Y = 0.

Se você ainda não sabe o que é ou quer ler mais sobre o assunto, um texto que eu gostei de ler:

O autor desse texto é o Kim Larsen, criador do pacote Information que é completo e cheio de ferramentas sofisticadas em torno do WoE. Porém, no dia a dia do meu trabalho volta e meia eu tinha que construir rotinas próprias para fazer as versões em WoE das minhas variáveis, mesmo com vários pacotes completos disponíveis. A principal motivação era que eles não eram muito práticos e não se encaixavam na filosofia do tidyverse. Daí acabei juntando essas rotinas num pacote chamado tidywoe e deixando no ar. A ideia é que ela faça o analista ganhar em tempo, legibilidade e reprodutibilidade. Abaixo segue como usar.

Instalação

Para instalar, basta rodar abaixo.

# install.packages("devtools")
devtools::install_github("athospd/tidywoe")

Dados e pacotes para os exemplos

library(forcats)
library(ggplot2)
library(dplyr)
library(tidywoe)

# install.packages("FactoMineR")
data(tea, package = "FactoMineR")
tea_mini <- tea %>% select(breakfast, how, where, price)

Como usar

Tem duas funções que importam: - add_woe() - adiciona os woe’s num data frame. - woe_dictionary() - cria dicionário que mapeia as categorias com os woe’s.

add_woe()

A função add_woe() serve para adicionar as versões WoE’s das variáveis em sua amostra de dados.

tea_mini %>% add_woe(breakfast)
breakfast how where price how_woe where_woe price_woe
breakfast tea bag chain store p_unknown -0.0377403 -0.0451204 -0.2564295
breakfast tea bag chain store p_variable -0.0377403 -0.0451204 0.1872882
Not.breakfast tea bag chain store p_variable -0.0377403 -0.0451204 0.1872882
Not.breakfast tea bag chain store p_variable -0.0377403 -0.0451204 0.1872882

Você pode selecionar as variáveis que vc quiser selecionando-as como se fosse no dplyr::select().

tea_mini %>% add_woe(breakfast, where:price)

woe_dictionary()

A função woe_dictionary() é uma das duas partes necessárias para fazer o add_woe() funcionar (a outra parte são os dados). Ele constrói o dicionário de categorias e seus respectivos woe’s.

tea_mini %>% woe_dictionary(breakfast)
variable explanatory n_tot n_breakfast n_Not.breakfast p_breakfast p_Not.breakfast woe
how tea bag 170 80 90 0.5555556 0.5769231 -0.0377403
how tea bag+unpackaged 94 50 44 0.3472222 0.2820513 0.2078761
how unpackaged 36 14 22 0.0972222 0.1410256 -0.3719424
where chain store 192 90 102 0.6250000 0.6538462 -0.0451204

Usando um dicionário customizado

Muitas vezes há o interesse em ajustar na mão alguns valores de woe para consertar a ordem dos efeitos de uma dada variável ordinal. Esse é o motivo de o add_woe() poder receber um dicionário passado pelo usuário. Isso se faz por meio do argumento .woe_dictionary.

A maneira mais fácil de se fazer isso é montar um dicionário inicial com o woe_dictionary() e depois alterar os valores nele para alcançar os ajustes desejados. Exemplo:

# Construa um dicionário inicial
tea_mini_woe_dic <- tea_mini %>% woe_dictionary(breakfast)

# Mexa um pouquinho nos woes
tea_mini_woe_dic_arrumado <- tea_mini_woe_dic %>% mutate(woe = if_else(explanatory == "p_unknown", 0, woe))

# Passe esse dicionário para o add_woe()
tea_mini %>% add_woe(breakfast, .woe_dictionary = tea_mini_woe_dic_arrumado)
breakfast how where price how_woe where_woe price_woe
breakfast tea bag chain store p_unknown -0.0377403 -0.0451204 0.0000000
breakfast tea bag chain store p_variable -0.0377403 -0.0451204 0.1872882
Not.breakfast tea bag chain store p_variable -0.0377403 -0.0451204 0.1872882
Not.breakfast tea bag chain store p_variable -0.0377403 -0.0451204 0.1872882

Exemplo de exploração

O woe_dictionary() devolve uma tabela arrumada, bem conveniente para explorar mais. Por exemplo, a tabela está pronta para o ggplot.

tea_mini_woe_dic_arrumado %>%
  mutate(explanatory = explanatory %>% as.factor %>% fct_reorder(woe)) %>%
  filter(variable %in% c("price", "how")) %>%
  ggplot() +
    geom_bar(aes(x = explanatory, y = woe), stat = "identity") +
    facet_wrap(~variable, scales = "free_x") +
  theme(axis.text.x = element_text(angle = 30))

Aqui está o github do pacote para contribuições. Pretendo colocar bastante coisa nova no pacote ainda.

Abs

comments powered by Disqus