Subamostragem por grupos em R

cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br


[This article was first published on R – Predictive Hacks, and kindly contributed to R-bloggers]. (Você pode relatar problemas sobre o conteúdo desta página aqui)


Quer compartilhar seu conteúdo em R-bloggers? clique aqui se você tiver um blog, ou aqui se não tiver.

Quando lidamos com classes desequilibradas em projetos de aprendizado de máquina, existem muitas abordagens que você pode seguir. Apenas para destacar alguns deles:

  • Undersampling: Tentamos reduzir as observações da classe majoritária para que o conjunto de dados final seja balanceado
  • Superamostragem: Tentamos gerar mais observações da classe minoritária, geralmente replicando as amostras da classe minoritária para que o conjunto de dados final seja balanceado.
  • Geração de dados sintéticos (SMOTE): Geramos dados artificiais usando algoritmos de bootstrapping e k-Nearest Neighbours.

Gere os Dados Desequilibrados

O cenário é que estamos lidando com 3 campanhas de e-mail que têm CTRs diferentes e queremos aplicar a subamostragem para normalizar o CTR pela campanha para evitar qualquer distorção e parcialidade quando construirmos o modelo de aprendizado de máquina. O conjunto de dados hipotético é o seguinte:

  • Campanha A: 5000 observações com CTR de 10% (aprox)
  • Campanha B: 10.000 observações com CTR de 20% (aprox)
  • Campanha C: 1000 observações com 30% CTR (aprox)

Vamos tentar gerar esta amostra aleatória em R.

library(tidyverse)

set.seed(5)
df = rbind(data.frame(Campaign = "A", Click = rbinom(n=5000, size=1, prob=0.1)),
           data.frame(Campaign = "B", Click = rbinom(n=10000, size=1, prob=0.2)),
           data.frame(Campaign = "C", Click = rbinom(n=1000, size=1, prob=0.3)))

head(df)
 

Resultado:

  Campaign Click
1        A     0
2        A     0
3        A     1
4        A     0
5        A     0
6        A     0

Vamos obter a CTR por campanha

df%>%group_by(Campaign)%>%
    summarise(CTR=mean(Click))
 

Resultado:

# A tibble: 3 x 2
  Campaign   CTR
      
1 A        0.106
2 B        0.198
3 C        0.302

Como podemos ver, a campanha A tem CTR de 10,6%, a B 19,8% e a C 30,2%. Vamos adicionar também uma coluna aleatória chamada atributo que assume os valores “X”, “Y”, “Z”, uma vez que vamos lidar com conjuntos de dados com mais de duas colunas.

Leia Também  Arquivos / diretórios não padrão, Rbuildignore e inst
cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br
df$Attribute

Now, our goal is to apply undersampling so that each campaign will have around 50% CTR

Undersampling by Group

We will use the map2 function from the purrr package which belongs to the tidyverse family:

campaign_summary % group_by(Campaign)%>% summarize(rr=sum(Click)/n(), pos= sum(Click))


df_neg_sample% filter(Click==0) %>%
  group_by(Campaign) %>% 
  nest() %>%             #group all data by campaign name
  ungroup() %>% 
  inner_join(campaign_summary, by="Campaign") 



sampled_df_neg%
  mutate(samp = map2(data, pos, sample_n, replace = FALSE))  %>%# sample based on the campaing summary
  select(-data) %>%  #remove original nested data
  unnest(samp) %>% select(c(-"rr",-"pos"))


df_pos % filter(Click==1) #positive samples
new_df 

Let’s check if the new_df is balanced by campaign. We will group by campaign and we will show the CTR and the number of observations:

new_df%>%group_by(Campaign)%>%summarise(CTR=mean(Click), Observations=n())

  Campaign   CTR Observations
              
1 A          0.5         1064
2 B          0.5         3950
3 C          0.5          604

Como podemos ver, sacrificamos uma amostra, mas temos um número equilibrado de classes para cada campanha (50-50).


Subamostragem por Grupo usando o Pacote ROSE

Podemos usar também o pacote ROSE. A seguir, aplicaremos um loop for por campanha para obter uma amostra balanceada usando a técnica de subamostragem.

library(ROSE)


balanced_sample = NULL


for (c in unique(df$Campaign)) {
  tmp_df = df%>%filter(Campaign==c)
  tmp

Let’s check if the balanced_sample is actually balanced.

balanced_sample%>%group_by(Campaign)%>%summarise(CTR=mean(Click), Observations=n())
 

Resultado:

  Campaign   CTR Observations
              
1 A        0.504         1056
2 B        0.496         3978
3 C        0.510          592

Impressionante. Mostramos duas abordagens diferentes de como aplicar a subamostragem por grupo.



cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br