GLM em R: modelo linear generalizado com exemplo

O que รฉ regressรฃo logรญstica?

A regressรฃo logรญstica รฉ usada para prever uma classe, ou seja, uma probabilidade. A regressรฃo logรญstica pode prever um resultado binรกrio com precisรฃo.

Imagine que vocรช deseja prever se um emprรฉstimo serรก negado/aceito com base em vรกrios atributos. A regressรฃo logรญstica tem o formato 0/1. y = 0 se um emprรฉstimo for rejeitado, y = 1 se for aceito.

Um modelo de regressรฃo logรญstica difere do modelo de regressรฃo linear de duas maneiras.

  • Em primeiro lugar, a regressรฃo logรญstica aceita apenas dados dicotรดmicos (binรกrios) como variรกvel dependente (ou seja, um vetor de 0 e 1).
  • Em segundo lugar, o resultado รฉ medido pela seguinte funรงรฃo de ligaรงรฃo probabilรญstica chamada sigmรณide devido ao seu formato em S.:

Regressรฃo Logรญstica

A saรญda da funรงรฃo estรก sempre entre 0 e 1. Verifique a imagem abaixo

Regressรฃo Logรญstica

A funรงรฃo sigmรณide retorna valores de 0 a 1. Para a tarefa de classificaรงรฃo, precisamos de uma saรญda discreta de 0 ou 1.

Para converter um fluxo contรญnuo em valor discreto, podemos definir um limite de decisรฃo em 0.5. Todos os valores acima deste limite sรฃo classificados como 1

Regressรฃo Logรญstica

Como criar um modelo de liner generalizado (GLM)

Vamos usar o adulto conjunto de dados para ilustrar a regressรฃo logรญstica. O โ€œadultoโ€ รฉ um รณtimo conjunto de dados para a tarefa de classificaรงรฃo. O objetivo รฉ prever se a renda anual em dรณlares de um indivรญduo ultrapassarรก 50.000. O conjunto de dados contรฉm 46,033 observaรงรตes e dez recursos:

  • idade: idade do indivรญduo. Numรฉrico
  • educaรงรฃo: Nรญvel educacional do indivรญduo. Fator.
  • estado civil: Mariestatuto social do indivรญduo. Fator, ou seja, nunca casado, cรดnjuge civil casado, ...
  • gรชnero: Gรชnero do indivรญduo. Fator, ou seja, Masculino ou Feminino
  • renda: Target variรกvel. Renda acima ou abaixo de 50K. Fator, ou seja, >50K, <=50K

entre outros

library(dplyr)
data_adult <-read.csv("https://raw.githubusercontent.com/guru99-edu/R-Programming/master/adult.csv")
glimpse(data_adult)

Saรญda:

Observations: 48,842
Variables: 10
$ x               <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,...
$ age             <int> 25, 38, 28, 44, 18, 34, 29, 63, 24, 55, 65, 36, 26...
$ workclass       <fctr> Private, Private, Local-gov, Private, ?, Private,...
$ education       <fctr> 11th, HS-grad, Assoc-acdm, Some-college, Some-col...
$ educational.num <int> 7, 9, 12, 10, 10, 6, 9, 15, 10, 4, 9, 13, 9, 9, 9,...
$ marital.status  <fctr> Never-married, Married-civ-spouse, Married-civ-sp...
$ race            <fctr> Black, White, White, Black, White, White, Black, ...
$ gender          <fctr> Male, Male, Male, Male, Female, Male, Male, Male,...
$ hours.per.week  <int> 40, 50, 40, 40, 30, 30, 40, 32, 40, 10, 40, 40, 39...
$ income          <fctr> <=50K, <=50K, >50K, >50K, <=50K, <=50K, <=50K, >5...

Procederemos da seguinte forma:

  • Passo 1: Verifique variรกveis โ€‹โ€‹contรญnuas
  • Passo 2: Verifique as variรกveis โ€‹โ€‹fatoriais
  • Etapa 3: engenharia de recursos
  • Etapa 4: estatรญstica resumida
  • Etapa 5: conjunto de treinamento/teste
  • Etapa 6: construir o modelo
  • Etapa 7: Avalie o desempenho do modelo
  • etapa 8: Melhore o modelo

Sua tarefa รฉ prever qual indivรญduo terรก uma receita superior a 50 mil.

Neste tutorial, cada etapa serรก detalhada para realizar uma anรกlise em um conjunto de dados real.

Passo 1) Verifique variรกveis โ€‹โ€‹contรญnuas

Na primeira etapa, vocรช pode ver a distribuiรงรฃo das variรกveis โ€‹โ€‹contรญnuas.

continuous <-select_if(data_adult, is.numeric)
summary(continuous)

Code Explicaรงรฃo

  • contรญnuo <- select_if(data_adult, is.numeric): Use a funรงรฃo select_if() da biblioteca dplyr para selecionar apenas as colunas numรฉricas
  • resumo (contรญnuo): Imprime a estatรญstica do resumo

Saรญda:

##        X              age        educational.num hours.per.week 
##  Min.   :    1   Min.   :17.00   Min.   : 1.00   Min.   : 1.00  
##  1st Qu.:11509   1st Qu.:28.00   1st Qu.: 9.00   1st Qu.:40.00  
##  Median :23017   Median :37.00   Median :10.00   Median :40.00  
##  Mean   :23017   Mean   :38.56   Mean   :10.13   Mean   :40.95  
##  3rd Qu.:34525   3rd Qu.:47.00   3rd Qu.:13.00   3rd Qu.:45.00  
##  Max.   :46033   Max.   :90.00   Max.   :16.00   Max.   :99.00	

Na tabela acima, vocรช pode ver que os dados tรชm escalas totalmente diferentes e horas por semana tรชm grandes discrepรขncias (ou seja, observe o รบltimo quartil e o valor mรกximo).

Vocรช pode lidar com isso seguindo duas etapas:

  • 1: Trace a distribuiรงรฃo de horas por semana
  • 2: Padronize as variรกveis โ€‹โ€‹contรญnuas
  1. Trace a distribuiรงรฃo

Vejamos mais de perto a distribuiรงรฃo de horas por semana

# Histogram with kernel density curve
library(ggplot2)
ggplot(continuous, aes(x = hours.per.week)) +
    geom_density(alpha = .2, fill = "#FF6666")

Saรญda:

Verifique variรกveis โ€‹โ€‹contรญnuas

A variรกvel tem muitos valores discrepantes e distribuiรงรฃo nรฃo bem definida. Vocรช pode resolver parcialmente esse problema excluindo 0.01% das principais horas da semana.

Sintaxe bรกsica do quantil:

quantile(variable, percentile)
arguments:
-variable:  Select the variable in the data frame to compute the percentile
-percentile:  Can be a single value between 0 and 1 or multiple value. If multiple, use this format:  `c(A,B,C, ...)
- `A`,`B`,`C` and `...` are all integer from 0 to 1.

Calculamos o percentil dos 2 por cento superiores

top_one_percent <- quantile(data_adult$hours.per.week, .99)
top_one_percent

Code Explicaรงรฃo

  • quantile(data_adult$hours.per.week, .99): Calcule o valor de 99 por cento do tempo de trabalho

Saรญda:

## 99% 
##  80

98 por cento da populaรงรฃo trabalha menos de 80 horas por semana.

Vocรช pode deixar as observaรงรตes acima desse limite. Vocรช usa o filtro do dplyr biblioteca.

data_adult_drop <-data_adult %>%
filter(hours.per.week<top_one_percent)
dim(data_adult_drop)

Saรญda:

## [1] 45537    10
  1. Padronize as variรกveis โ€‹โ€‹contรญnuas

Vocรช pode padronizar cada coluna para melhorar o desempenho porque seus dados nรฃo tรชm a mesma escala. Vocรช pode usar a funรงรฃo mutate_if da biblioteca dplyr. A sintaxe bรกsica รฉ:

mutate_if(df, condition, funs(function))
arguments:
-`df`: Data frame used to compute the function
- `condition`: Statement used. Do not use parenthesis
- funs(function):  Return the function to apply. Do not use parenthesis for the function

Vocรช pode padronizar as colunas numรฉricas da seguinte forma:

data_adult_rescale <- data_adult_drop % > %
	mutate_if(is.numeric, funs(as.numeric(scale(.))))
head(data_adult_rescale)

Code Explicaรงรฃo

  • mutate_if(is.numeric, funs(scale)): A condiรงรฃo รฉ apenas coluna numรฉrica e a funรงรฃo รฉ escala

Saรญda:

##           X         age        workclass    education educational.num
## 1 -1.732680 -1.02325949          Private         11th     -1.22106443
## 2 -1.732605 -0.03969284          Private      HS-grad     -0.43998868
## 3 -1.732530 -0.79628257        Local-gov   Assoc-acdm      0.73162494
## 4 -1.732455  0.41426100          Private Some-college     -0.04945081
## 5 -1.732379 -0.34232873          Private         10th     -1.61160231
## 6 -1.732304  1.85178149 Self-emp-not-inc  Prof-school      1.90323857
##       marital.status  race gender hours.per.week income
## 1      Never-married Black   Male    -0.03995944  <=50K
## 2 Married-civ-spouse White   Male     0.86863037  <=50K
## 3 Married-civ-spouse White   Male    -0.03995944   >50K
## 4 Married-civ-spouse Black   Male    -0.03995944   >50K
## 5      Never-married White   Male    -0.94854924  <=50K
## 6 Married-civ-spouse White   Male    -0.76683128   >50K

Passo 2) Verifique as variรกveis โ€‹โ€‹fatoriais

Esta etapa tem dois objetivos:

  • Verifique o nรญvel em cada coluna categรณrica
  • Defina novos nรญveis

Dividiremos esta etapa em trรชs partes:

  • Selecione as colunas categรณricas
  • Armazene o grรกfico de barras de cada coluna em uma lista
  • Imprima os grรกficos

Podemos selecionar as colunas de fator com o cรณdigo abaixo:

# Select categorical column
factor <- data.frame(select_if(data_adult_rescale, is.factor))
	ncol(factor)

Code Explicaรงรฃo

  • data.frame(select_if(data_adult, is.factor)): Armazenamos as colunas de fator em factor em um tipo de quadro de dados. A biblioteca ggplot2 requer um objeto de quadro de dados.

Saรญda:

## [1] 6

O conjunto de dados contรฉm 6 variรกveis โ€‹โ€‹โ€‹โ€‹categรณricas

A segunda etapa รฉ mais qualificada. Vocรช deseja traรงar um grรกfico de barras para cada coluna no fator do quadro de dados. ร‰ mais conveniente automatizar o processo, principalmente em situaรงรตes em que hรก muitas colunas.

library(ggplot2)
# Create graph for each column
graph <- lapply(names(factor),
    function(x) 
	ggplot(factor, aes(get(x))) +
		geom_bar() +
		theme(axis.text.x = element_text(angle = 90)))

Code Explicaรงรฃo

  • lapply(): Use a funรงรฃo lapply() para passar uma funรงรฃo em todas as colunas do conjunto de dados. Vocรช armazena a saรญda em uma lista
  • function(x): A funรงรฃo serรก processada para cada x. Aqui x sรฃo as colunas
  • ggplot(factor, aes(get(x))) + geom_bar()+ theme(axis.text.x = element_text(angle = 90)): Crie um grรกfico de barras para cada elemento x. Observe que para retornar x como uma coluna, vocรช precisa incluรญ-lo dentro de get()

A รบltima etapa รฉ relativamente fรกcil. Vocรช deseja imprimir os 6 grรกficos.

# Print the graph
graph

Saรญda:

## [[1]]

Verifique variรกveis โ€‹โ€‹de fator

## ## [[2]]

Verifique variรกveis โ€‹โ€‹de fator

## ## [[3]]

Verifique variรกveis โ€‹โ€‹de fator

## ## [[4]]

Verifique variรกveis โ€‹โ€‹de fator

## ## [[5]]

Verifique variรกveis โ€‹โ€‹de fator

## ## [[6]]

Verifique variรกveis โ€‹โ€‹de fator

Nota: Use o botรฃo seguinte para navegar para o prรณximo grรกfico

Verifique variรกveis โ€‹โ€‹de fator

Etapa 3) Engenharia de recursos

Reformular a educaรงรฃo

No grรกfico acima vocรช pode perceber que a variรกvel escolaridade possui 16 nรญveis. Isto รฉ substancial e alguns nรญveis tรชm um nรบmero relativamente baixo de observaรงรตes. Se quiser melhorar a quantidade de informaรงรตes que pode obter dessa variรกvel, vocรช pode reformulรก-la para um nรญvel superior. Ou seja, vocรช cria grupos maiores com nรญvel de escolaridade semelhante. Por exemplo, o baixo nรญvel de escolaridade serรก convertido em abandono escolar. Nรญveis mais elevados de educaรงรฃo serรฃo alterados para mestrado.

Aqui estรก o detalhe:

Nรญvel antigo Novo nรญvel
Prรฉ escola Dropout
sec 10 Cair fora
sec 11 Cair fora
sec 12 Cair fora
1ยบ a 4ยบ Cair fora
5th-6th Cair fora
7th-8th Cair fora
sec 9 Cair fora
HS-Graduaรงรฃo Alta graduaรงรฃo
Alguma faculdade Comunidade
Associado-acdm Comunidade
Associado Comunidade
Bacharelado Bacharelado
mestres mestres
Escola profissional mestres
Doutorado PhD
recast_data <- data_adult_rescale % > %
	select(-X) % > %
	mutate(education = factor(ifelse(education == "Preschool" | education == "10th" | education == "11th" | education == "12th" | education == "1st-4th" | education == "5th-6th" | education == "7th-8th" | education == "9th", "dropout", ifelse(education == "HS-grad", "HighGrad", ifelse(education == "Some-college" | education == "Assoc-acdm" | education == "Assoc-voc", "Community",
    ifelse(education == "Bachelors", "Bachelors",
        ifelse(education == "Masters" | education == "Prof-school", "Master", "PhD")))))))

Code Explicaรงรฃo

  • Usamos o verbo mutate da biblioteca dplyr. Mudamos os valores da educaรงรฃo com a afirmaรงรฃo ifelse

Na tabela abaixo, vocรช cria uma estatรญstica resumida para ver, em mรฉdia, quantos anos de estudo (valor z) sรฃo necessรกrios para se chegar ao bacharelado, mestrado ou doutorado.

recast_data % > %
	group_by(education) % > %
	summarize(average_educ_year = mean(educational.num),
		count = n()) % > %
	arrange(average_educ_year)

Saรญda:

## # A tibble: 6 x 3
## education average_educ_year count			
##      <fctr>             <dbl> <int>
## 1   dropout       -1.76147258  5712
## 2  HighGrad       -0.43998868 14803
## 3 Community        0.09561361 13407
## 4 Bachelors        1.12216282  7720
## 5    Master        1.60337381  3338
## 6       PhD        2.29377644   557

Reformulaรงรฃo Marital-status

Tambรฉm รฉ possรญvel criar nรญveis inferiores para o estado civil. No cรณdigo a seguir, vocรช altera o nรญvel da seguinte maneira:

Nรญvel antigo Novo nรญvel
Nunca casado Solteiro
Casado-cรดnjuge-ausente Solteiro
Casado-AF-cรดnjuge Casado
Cรดnjuge casada
Separado Separado
Divorciado
Viรบvas Viรบva
# Change level marry
recast_data <- recast_data % > %
	mutate(marital.status = factor(ifelse(marital.status == "Never-married" | marital.status == "Married-spouse-absent", "Not_married", ifelse(marital.status == "Married-AF-spouse" | marital.status == "Married-civ-spouse", "Married", ifelse(marital.status == "Separated" | marital.status == "Divorced", "Separated", "Widow")))))

Vocรช pode verificar o nรบmero de indivรญduos dentro de cada grupo.

table(recast_data$marital.status)

Saรญda:

## ##     Married Not_married   Separated       Widow
##       21165       15359        7727        1286

Etapa 4) Estatรญstica resumida

ร‰ hora de verificar algumas estatรญsticas sobre nossas variรกveis-alvo. No grรกfico abaixo, vocรช conta a porcentagem de indivรญduos que ganham mais de 50 mil de acordo com seu gรชnero.

# Plot gender income
ggplot(recast_data, aes(x = gender, fill = income)) +
    geom_bar(position = "fill") +
    theme_classic()

Saรญda:

Estatรญstica resumida

A seguir, verifique se a origem do indivรญduo afeta seus rendimentos.

# Plot origin income
ggplot(recast_data, aes(x = race, fill = income)) +
    geom_bar(position = "fill") +
    theme_classic() +
    theme(axis.text.x = element_text(angle = 90))

Saรญda:

Estatรญstica resumida

O nรบmero de horas de trabalho por gรชnero.

# box plot gender working time
ggplot(recast_data, aes(x = gender, y = hours.per.week)) +
    geom_boxplot() +
    stat_summary(fun.y = mean,
        geom = "point",
        size = 3,
        color = "steelblue") +
    theme_classic()

Saรญda:

Estatรญstica resumida

O box plot confirma que a distribuiรงรฃo do tempo de trabalho se ajusta a diferentes grupos. No box plot, ambos os sexos nรฃo possuem observaรงรตes homogรชneas.

ร‰ possรญvel verificar a densidade da jornada de trabalho semanal por tipo de escolaridade. As distribuiรงรตes apresentam vรกrios picos distintos. Isso provavelmente pode ser explicado pelo tipo de vรญnculo empregatรญcio.tracnos EUA.

# Plot distribution working time by education
ggplot(recast_data, aes(x = hours.per.week)) +
    geom_density(aes(color = education), alpha = 0.5) +
    theme_classic()

Code Explicaรงรฃo

  • ggplot(recast_data, aes( x= hours.per.week)): Um grรกfico de densidade requer apenas uma variรกvel
  • geom_density(aes(color = education), alpha =0.5): O objeto geomรฉtrico para controlar a densidade

Saรญda:

Estatรญstica resumida

Para confirmar seus pensamentos, vocรช pode realizar um teste unilateral Teste ANOVA:

anova <- aov(hours.per.week~education, recast_data)
summary(anova)

Saรญda:

##                Df Sum Sq Mean Sq F value Pr(>F)    
## education       5   1552  310.31   321.2 <2e-16 ***
## Residuals   45531  43984    0.97                   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

O teste ANOVA confirma a diferenรงa de mรฉdia entre os grupos.

Nรฃo-linearidade

Antes de executar o modelo, vocรช pode ver se o nรบmero de horas trabalhadas estรก relacionado ร  idade.

library(ggplot2)
ggplot(recast_data, aes(x = age, y = hours.per.week)) +
    geom_point(aes(color = income),
        size = 0.5) +
    stat_smooth(method = 'lm',
        formula = y~poly(x, 2),
        se = TRUE,
        aes(color = income)) +
    theme_classic()

Code Explicaรงรฃo

  • ggplot(recast_data, aes(x = age, y = hours.per.week)): Defina a estรฉtica do grรกfico
  • geom_point(aes(color= income), size =0.5): Construa o grรกfico de pontos
  • stat_smooth(): Adicione a linha de tendรชncia com os seguintes argumentos:
    • method='lm': Plote o valor ajustado se o regressรฃo linear
    • fรณrmula = y~poly(x,2): Ajustar uma regressรฃo polinomial
    • se = TRUE: Adicione o erro padrรฃo
    • aes(cor=renda): Divida o modelo por renda

Saรญda:

Nรฃo-linearidade

Resumindo, vocรช pode testar os termos de interaรงรฃo no modelo para captar o efeito de nรฃo linearidade entre o horรกrio de trabalho semanal e outros recursos. ร‰ importante detectar em que condiรงรตes o tempo de trabalho difere.

Correlaรงรฃo

A prรณxima verificaรงรฃo รฉ visualizar a correlaรงรฃo entre as variรกveis. Vocรช converte o tipo de nรญvel de fator em numรฉrico para poder traรงar um mapa de calor contendo o coeficiente de correlaรงรฃo calculado com o mรฉtodo de Spearman.

library(GGally)
# Convert data to numeric
corr <- data.frame(lapply(recast_data, as.integer))
# Plot the graphggcorr(corr,
    method = c("pairwise", "spearman"),
    nbreaks = 6,
    hjust = 0.8,
    label = TRUE,
    label_size = 3,
    color = "grey50")

Code Explicaรงรฃo

  • data.frame(lapply(recast_data,as.integer)): Converte dados em numรฉricos
  • ggcorr() plote o mapa de calor com os seguintes argumentos:
    • mรฉtodo: Mรฉtodo para calcular a correlaรงรฃo
    • nbreaks = 6: Nรบmero de pausas
    • hjust = 0.8: posiรงรฃo de controle do nome da variรกvel no grรกfico
    • label = TRUE: Adicione rรณtulos no centro das janelas
    • label_size = 3: rรณtulos de tamanho
    • color = โ€œgrey50โ€): Cor da etiqueta

Saรญda:

Correlaรงรฃo

Etapa 5) Conjunto de treinamento/teste

Qualquer supervisionado aprendizado de mรกquina A tarefa exige dividir os dados entre um conjunto de treinamento e um conjunto de teste. Vocรช pode usar a โ€œfunรงรฃoโ€ criada em outros tutoriais de aprendizagem supervisionada para criar um conjunto de treinamento/teste.

set.seed(1234)
create_train_test <- function(data, size = 0.8, train = TRUE) {
    n_row = nrow(data)
    total_row = size * n_row
    train_sample <- 1: total_row
    if (train == TRUE) {
        return (data[train_sample, ])
    } else {
        return (data[-train_sample, ])
    }
}
data_train <- create_train_test(recast_data, 0.8, train = TRUE)
data_test <- create_train_test(recast_data, 0.8, train = FALSE)
dim(data_train)

Saรญda:

## [1] 36429     9
dim(data_test)

Saรญda:

## [1] 9108    9

Etapa 6) Construa o modelo

Para ver o desempenho do algoritmo, vocรช usa o pacote glm(). O Modelo Linear Generalizado รฉ uma coleรงรฃo de modelos. A sintaxe bรกsica รฉ:

glm(formula, data=data, family=linkfunction()
Argument:
- formula:  Equation used to fit the model- data: dataset used
- Family:     - binomial: (link = "logit")			
- gaussian: (link = "identity")			
- Gamma:    (link = "inverse")			
- inverse.gaussian: (link = "1/mu^2")			
- poisson:  (link = "log")			
- quasi:    (link = "identity", variance = "constant")			
- quasibinomial:    (link = "logit")			
- quasipoisson: (link = "log")	

Vocรช estรก pronto para estimar o modelo logรญstico para dividir o nรญvel de renda entre um conjunto de recursos.

formula <- income~.
logit <- glm(formula, data = data_train, family = 'binomial')
summary(logit)

Code Explicaรงรฃo

  • fรณrmula <- renda ~ .: Crie o modelo para caber
  • logit <- glm(formula, data = data_train, family = 'binomial'): Ajusta um modelo logรญstico (family = 'binomial') com os dados data_train.
  • summary(logit): Imprime o resumo do modelo

Saรญda:

## 
## Call:
## glm(formula = formula, family = "binomial", data = data_train)
## ## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -2.6456  -0.5858  -0.2609  -0.0651   3.1982  
## 
## Coefficients:
##                           Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                0.07882    0.21726   0.363  0.71675    
## age                        0.41119    0.01857  22.146  < 2e-16 ***
## workclassLocal-gov        -0.64018    0.09396  -6.813 9.54e-12 ***
## workclassPrivate          -0.53542    0.07886  -6.789 1.13e-11 ***
## workclassSelf-emp-inc     -0.07733    0.10350  -0.747  0.45499    
## workclassSelf-emp-not-inc -1.09052    0.09140 -11.931  < 2e-16 ***
## workclassState-gov        -0.80562    0.10617  -7.588 3.25e-14 ***
## workclassWithout-pay      -1.09765    0.86787  -1.265  0.20596    
## educationCommunity        -0.44436    0.08267  -5.375 7.66e-08 ***
## educationHighGrad         -0.67613    0.11827  -5.717 1.08e-08 ***
## educationMaster            0.35651    0.06780   5.258 1.46e-07 ***
## educationPhD               0.46995    0.15772   2.980  0.00289 ** 
## educationdropout          -1.04974    0.21280  -4.933 8.10e-07 ***
## educational.num            0.56908    0.07063   8.057 7.84e-16 ***
## marital.statusNot_married -2.50346    0.05113 -48.966  < 2e-16 ***
## marital.statusSeparated   -2.16177    0.05425 -39.846  < 2e-16 ***
## marital.statusWidow       -2.22707    0.12522 -17.785  < 2e-16 ***
## raceAsian-Pac-Islander     0.08359    0.20344   0.411  0.68117    
## raceBlack                  0.07188    0.19330   0.372  0.71001    
## raceOther                  0.01370    0.27695   0.049  0.96054    
## raceWhite                  0.34830    0.18441   1.889  0.05894 .  
## genderMale                 0.08596    0.04289   2.004  0.04506 *  
## hours.per.week             0.41942    0.01748  23.998  < 2e-16 ***
## ---## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## ## (Dispersion parameter for binomial family taken to be 1)
## ##     Null deviance: 40601  on 36428  degrees of freedom
## Residual deviance: 27041  on 36406  degrees of freedom
## AIC: 27087
## 
## Number of Fisher Scoring iterations: 6

O resumo do nosso modelo revela informaรงรตes interessantes. O desempenho de uma regressรฃo logรญstica รฉ avaliado com mรฉtricas-chave especรญficas.

  • AIC (Critรฉrios de Informaรงรฃo Akaike): Isto รฉ equivalente a R2 na regressรฃo logรญstica. Mede o ajuste quando uma penalidade รฉ aplicada ao nรบmero de parรขmetros. Menor AIC valores indicam que o modelo estรก mais prรณximo da verdade.
  • Desvio nulo: ajusta o modelo apenas com o intercepto. O grau de liberdade รฉ n-1. Podemos interpretรก-lo como um valor qui-quadrado (valor ajustado diferente do teste de hipรณtese de valor real).
  • Desvio Residual: Modelo com todas as variรกveis. Tambรฉm รฉ interpretado como um teste de hipรณtese do qui-quadrado.
  • Nรบmero de iteraรงรตes do Fisher Scoring: Nรบmero de iteraรงรตes antes da convergรชncia.

A saรญda da funรงรฃo glm() รฉ armazenada em uma lista. O cรณdigo abaixo mostra todos os itens disponรญveis na variรกvel logit que construรญmos para avaliar a regressรฃo logรญstica.

# A lista รฉ muito longa, imprima apenas os trรชs primeiros elementos

lapply(logit, class)[1:3]

Saรญda:

## $coefficients
## [1] "numeric"
## 
## $residuals
## [1] "numeric"
## 
## $fitted.values
## [1] "numeric"

Cada valor pode ser extracted com o sinal $ seguido pelo nome das mรฉtricas. Por exemplo, vocรช armazenou o modelo como logit. Para exetracPara os critรฉrios AIC, vocรช usa:

logit$aic

Saรญda:

## [1] 27086.65

Etapa 7) Avalie o desempenho do modelo

Matriz de Confusรฃo

O processo de matriz de confusรฃo รฉ a melhor opรงรฃo para avaliar o desempenho da classificaรงรฃo em comparaรงรฃo com as diferentes mรฉtricas que vocรช viu antes. A ideia geral รฉ contar o nรบmero de vezes que instรขncias Verdadeiras sรฃo classificadas como Falsas.

Matriz de Confusรฃo

Para calcular a matriz de confusรฃo, primeiro vocรช precisa ter um conjunto de previsรตes para que possam ser comparadas com os alvos reais.

predict <- predict(logit, data_test, type = 'response')
# confusion matrix
table_mat <- table(data_test$income, predict > 0.5)
table_mat

Code Explicaรงรฃo

  • predizer(logit,data_test, type = 'response'): Calcula a previsรฃo no conjunto de teste. Defina type = 'response' para calcular a probabilidade de resposta.
  • table(data_test$income, prever > 0.5): Calcula a matriz de confusรฃo. prever > 0.5 significa que retornarรก 1 se as probabilidades previstas estiverem acima de 0.5, caso contrรกrio, 0.

Saรญda:

##        
##         FALSE TRUE
##   <=50K  6310  495
##   >50K   1074 1229	

Cada linha em uma matriz de confusรฃo representa um alvo real, enquanto cada coluna representa um alvo previsto. A primeira linha desta matriz considera a renda inferior a 50k (a classe Falsa): 6241 foram corretamente classificados como indivรญduos com renda inferior a 50k (Verdadeiro negativo), enquanto o restante foi erroneamente classificado como acima de 50k (Falso positivo). A segunda linha considera a renda acima de 50k, a classe positiva foi 1229 (Verdadeiro-positivo), Enquanto que o Verdadeiro negativo foi 1074.

Vocรช pode calcular o modelo precisรฃo somando o verdadeiro positivo + verdadeiro negativo sobre a observaรงรฃo total

Matriz de Confusรฃo

accuracy_Test <- sum(diag(table_mat)) / sum(table_mat)
accuracy_Test

Code Explicaรงรฃo

  • sum(diag(table_mat)): Soma da diagonal
  • sum(table_mat): Soma da matriz.

Saรญda:

## [1] 0.8277339

O modelo parece sofrer de um problema: superestima o nรบmero de falsos negativos. Isso รฉ chamado de paradoxo do teste de precisรฃo. Afirmamos que a precisรฃo รฉ a razรฃo entre as previsรตes corretas e o nรบmero total de casos. Podemos ter uma precisรฃo relativamente alta, mas um modelo inรบtil. Isso acontece quando hรก uma classe dominante. Se vocรช olhar novamente para a matriz de confusรฃo, verรก que a maioria dos casos sรฃo classificados como verdadeiros negativos. Imagine agora, o modelo classificou todas as classes como negativas (ou seja, inferiores a 50k). Vocรช teria uma precisรฃo de 75 por cento (6718/6718+2257). Seu modelo tem melhor desempenho, mas tem dificuldade para distinguir o verdadeiro positivo do verdadeiro negativo.

Nessa situaรงรฃo, รฉ preferรญvel ter uma mรฉtrica mais concisa. Podemos olhar para:

  • Precisรฃo=TP/(TP+FP)
  • Rechamada=TP/(TP+FN)

Precisรฃo vs recall

Precisรฃo analisa a precisรฃo da previsรฃo positiva. Recordar รฉ a proporรงรฃo de instรขncias positivas que sรฃo detectadas corretamente pelo classificador;

Vocรช pode construir duas funรงรตes para calcular essas duas mรฉtricas

  1. Precisรฃo de construรงรฃo
precision <- function(matrix) {
	# True positive
    tp <- matrix[2, 2]
	# false positive
    fp <- matrix[1, 2]
    return (tp / (tp + fp))
}

Code Explicaรงรฃo

  • mat[1,1]: Retorna a primeira cรฉlula da primeira coluna do quadro de dados, ou seja, o verdadeiro positivo
  • tapete[1,2]; Retorna a primeira cรฉlula da segunda coluna do data frame, ou seja, o falso positivo
recall <- function(matrix) {
# true positive
    tp <- matrix[2, 2]# false positive
    fn <- matrix[2, 1]
    return (tp / (tp + fn))
}

Code Explicaรงรฃo

  • mat[1,1]: Retorna a primeira cรฉlula da primeira coluna do quadro de dados, ou seja, o verdadeiro positivo
  • tapete[2,1]; Retorna a segunda cรฉlula da primeira coluna do data frame, ou seja, o falso negativo

Vocรช pode testar suas funรงรตes

prec <- precision(table_mat)
prec
rec <- recall(table_mat)
rec

Saรญda:

## [1] 0.712877
## [2] 0.5336518

Quando o modelo diz que รฉ um indivรญduo acima de 50 mil, estรก correto em apenas 54% dos casos e pode reivindicar indivรญduos acima de 50 mil em 72% dos casos.

Vocรช pode criar o Precisรฃo vs recall pontuaรงรฃo com base na precisรฃo e recall. O Precisรฃo vs recall รฉ uma mรฉdia harmรดnica dessas duas mรฉtricas, o que significa que dรก mais peso aos valores mais baixos.

Precisรฃo vs recall

f1 <- 2 * ((prec * rec) / (prec + rec))
f1

Saรญda:

## [1] 0.6103799

Troca entre precisรฃo e recall

ร‰ impossรญvel ter alta precisรฃo e alto recall.

Se aumentarmos a precisรฃo, o indivรญduo correto serรก melhor previsto, mas perderemos muitos deles (menor recordaรงรฃo). Em algumas situaรงรตes, preferimos maior precisรฃo do que recall. Existe uma relaรงรฃo cรดncava entre precisรฃo e recall.

  • Imagine, vocรช precisa prever se um paciente tem alguma doenรงa. Vocรช quer ser o mais preciso possรญvel.
  • Se vocรช precisar detectar possรญveis pessoas fraudulentas nas ruas por meio do reconhecimento facial, seria melhor capturar muitas pessoas rotuladas como fraudulentas, mesmo que a precisรฃo seja baixa. A polรญcia poderรก libertar o indivรญduo nรฃo fraudulento.

A curva ROC

O processo de recebedor Operacaracterรญstica curva รฉ outra ferramenta comum usada com classificaรงรฃo binรกria. ร‰ muito semelhante ร  curva de precisรฃo/recall, mas em vez de representar graficamente precisรฃo versus recall, a curva ROC mostra a taxa de verdadeiros positivos (ou seja, recall) contra a taxa de falsos positivos. A taxa de falsos positivos รฉ a proporรงรฃo de instรขncias negativas que sรฃo classificadas incorretamente como positivas. ร‰ igual a um menos a taxa verdadeiramente negativa. A taxa verdadeiramente negativa tambรฉm รฉ chamada especificidade. Daรญ os grรกficos da curva ROC sensibilidade (recall) versus 1 especificidade

Para traรงar a curva ROC, precisamos instalar uma biblioteca chamada RORC. Podemos encontrar no conda biblioteca. Vocรช pode digitar o cรณdigo:

conda instalar -cr r-rocr โ€“sim

Podemos traรงar o ROC com as funรงรตes de previsรฃo() e desempenho().

library(ROCR)
ROCRpred <- prediction(predict, data_test$income)
ROCRperf <- performance(ROCRpred, 'tpr', 'fpr')
plot(ROCRperf, colorize = TRUE, text.adj = c(-0.2, 1.7))

Code Explicaรงรฃo

  • previsรฃo (prever, data_test$income): A biblioteca ROCR precisa criar um objeto de previsรฃo para transformar os dados de entrada
  • performance(ROCRpred, 'tpr','fpr'): Retorna as duas combinaรงรตes a serem produzidas no grรกfico. Aqui, tpr e fpr sรฃo construรญdos. Para plotar precisรฃo e recall juntos, use โ€œprecโ€, โ€œrecโ€.

Saรญda:

A curva ROC

Passo 8) Melhorar o modelo

Vocรช pode tentar adicionar nรฃo linearidade ao modelo com a interaรงรฃo entre

  • idade e horas.por.semana
  • gรชnero e horas.por.semana.

Vocรช precisa usar o teste de pontuaรงรฃo para comparar os dois modelos

formula_2 <- income~age: hours.per.week + gender: hours.per.week + .
logit_2 <- glm(formula_2, data = data_train, family = 'binomial')
predict_2 <- predict(logit_2, data_test, type = 'response')
table_mat_2 <- table(data_test$income, predict_2 > 0.5)
precision_2 <- precision(table_mat_2)
recall_2 <- recall(table_mat_2)
f1_2 <- 2 * ((precision_2 * recall_2) / (precision_2 + recall_2))
f1_2

Saรญda:

## [1] 0.6109181

A pontuaรงรฃo รฉ um pouco superior ร  anterior. Vocรช pode continuar trabalhando nos dados e tentar bater a pontuaรงรฃo.

Resumo

Podemos resumir a funรงรฃo para treinar uma regressรฃo logรญstica na tabela abaixo:

Pacote Objetivo funรงรฃo Argumento
- Criar conjunto de dados de treinamento/teste create_train_set() dados, tamanho, trem
glm Treine um modelo linear generalizado glm() fรณrmula, dados, famรญlia*
glm Resuma o modelo resumo() modelo ajustado
base Fazer previsรฃo prever() modelo ajustado, conjunto de dados, tipo = 'resposta'
base Crie uma matriz de confusรฃo mesa() sim, prever()
base Criar pontuaรงรฃo de precisรฃo soma(diag(tabela())/soma(tabela()
ROCR Criar ROC: Etapa 1 Criar previsรฃo prediรงรฃo() prever(), y
ROCR Criar ROC: Etapa 2 Criar desempenho desempenho() previsรฃo(), 'tpr', 'fpr'
ROCR Criar ROC: Grรกfico de plotagem da etapa 3 enredo() desempenho()

A outra GLM tipo de modelos sรฃo:

โ€“ binรดmio: (link = โ€œlogitโ€)

โ€“ gaussiano: (link = โ€œidentidadeโ€)

โ€“ Gama: (link = โ€œinversoโ€)

โ€“ inverso.gaussiano: (link = โ€œ1/mu^2โ€)

โ€“ poisson: (link = โ€œlogโ€)

โ€“ quase: (link = โ€œidentidadeโ€, variรขncia = โ€œconstanteโ€)

โ€“ quasebinomial: (link = โ€œlogitโ€)

โ€“ quasepoisson: (link = โ€œlogโ€)

Resuma esta postagem com: