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.:
A saรญda da funรงรฃo estรก sempre entre 0 e 1. Verifique a imagem abaixo
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
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
- 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:
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
- 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]]
## ## [[2]]
## ## [[3]]
## ## [[4]]
## ## [[5]]
## ## [[6]]
Nota: Use o botรฃo seguinte para navegar para o prรณximo grรกfico
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:
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:
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:
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:
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:
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:
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.
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
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
- 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 pontuaรงรฃo com base na precisรฃo e recall. O
รฉ uma mรฉdia harmรดnica dessas duas mรฉtricas, o que significa que dรก mais peso aos valores mais baixos.
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:
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โ)





















