Carregando os dados
s_dating <- read_csv("5-regressao/speed-dating/speed-dating2.csv")
## Rows: 4918 Columns: 44
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (4): field, from, career, dec
## dbl (40): iid, gender, order, pid, int_corr, samerace, age_o, age, race, spo...
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
glimpse(s_dating)
## Rows: 4,918
## Columns: 44
## $ iid <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3…
## $ gender <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
## $ order <dbl> 4, 3, 10, 5, 7, 6, 1, 2, 8, 9, 10, 9, 6, 1, 3, 2, 7, 8, 4, 5,…
## $ pid <dbl> 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 11, 12, 13, 14, 15, 1…
## $ int_corr <dbl> 0.14, 0.54, 0.16, 0.61, 0.21, 0.25, 0.34, 0.50, 0.28, -0.36, …
## $ samerace <dbl> 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1…
## $ age_o <dbl> 27, 22, 22, 23, 24, 25, 30, 27, 28, 24, 27, 22, 22, 23, 24, 2…
## $ age <dbl> 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 24, 24, 24, 24, 24, 2…
## $ field <chr> "Law", "Law", "Law", "Law", "Law", "Law", "Law", "Law", "Law"…
## $ race <dbl> 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2…
## $ from <chr> "Chicago", "Chicago", "Chicago", "Chicago", "Chicago", "Chica…
## $ career <chr> "lawyer", "lawyer", "lawyer", "lawyer", "lawyer", "lawyer", "…
## $ sports <dbl> 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3…
## $ tvsports <dbl> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 8…
## $ exercise <dbl> 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7…
## $ dining <dbl> 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,…
## $ museums <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 5…
## $ art <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5…
## $ hiking <dbl> 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 8…
## $ gaming <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4…
## $ clubbing <dbl> 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 5…
## $ reading <dbl> 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 10, 10, 10, 10, 10, 10, 10, 10,…
## $ tv <dbl> 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8…
## $ theater <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7…
## $ movies <dbl> 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 8, 8, 8, 8, 8, 8, 8, …
## $ concerts <dbl> 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 7, 7, 7, 7, 7, 7, 7, …
## $ music <dbl> 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 5…
## $ shopping <dbl> 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 8…
## $ yoga <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7…
## $ attr <dbl> 6, 7, 5, 7, 5, 4, 7, 4, 7, 5, 5, 8, 5, 7, 6, 8, 7, 5, 7, 6, 7…
## $ sinc <dbl> 9, 8, 8, 6, 6, 9, 6, 9, 6, 6, 7, 5, 8, 9, 8, 7, 5, 8, 6, 7, 9…
## $ intel <dbl> 7, 7, 9, 8, 7, 7, 7, 7, 8, 6, 8, 6, 9, 7, 7, 8, 9, 7, 8, 8, 1…
## $ fun <dbl> 7, 8, 8, 7, 7, 4, 4, 6, 9, 8, 4, 6, 6, 6, 9, 3, 6, 5, 9, 7, 7…
## $ amb <dbl> 6, 5, 5, 6, 6, 6, 6, 5, 8, 10, 6, 9, 3, 5, 7, 6, 7, 9, 4, 9, …
## $ shar <dbl> 5, 6, 7, 8, 6, 4, 7, 6, 8, 8, 3, 6, 4, 7, 8, 2, 9, 5, 5, 8, 9…
## $ like <dbl> 7, 7, 7, 7, 6, 6, 6, 6, 7, 6, 6, 7, 6, 7, 8, 6, 8, 5, 5, 8, 8…
## $ prob <dbl> 6, 5, NA, 6, 6, 5, 5, 7, 7, 6, 4, 3, 7, 8, 6, 5, 7, 6, 6, 7, …
## $ match_es <dbl> 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, N…
## $ attr3_s <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ sinc3_s <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ intel3_s <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ fun3_s <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ amb3_s <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ dec <chr> "yes", "yes", "yes", "yes", "yes", "no", "yes", "no", "yes", …
summary(s_dating)
## iid gender order pid
## Min. : 1.0 Min. :0.000 Min. : 1.00 Min. : 1
## 1st Qu.: 88.0 1st Qu.:0.000 1st Qu.: 4.00 1st Qu.: 88
## Median :273.0 Median :1.000 Median : 9.00 Median :273
## Mean :274.7 Mean :0.501 Mean : 9.26 Mean :275
## 3rd Qu.:431.0 3rd Qu.:1.000 3rd Qu.:14.00 3rd Qu.:431
## Max. :552.0 Max. :1.000 Max. :22.00 Max. :552
## NA's :10
## int_corr samerace age_o age
## Min. :-0.7300 Min. :0.0000 Min. :18.00 Min. :18.00
## 1st Qu.:-0.0300 1st Qu.:0.0000 1st Qu.:23.00 1st Qu.:23.00
## Median : 0.2100 Median :0.0000 Median :25.00 Median :25.00
## Mean : 0.1905 Mean :0.4063 Mean :25.79 Mean :25.78
## 3rd Qu.: 0.4300 3rd Qu.:1.0000 3rd Qu.:28.00 3rd Qu.:28.00
## Max. : 0.9000 Max. :1.0000 Max. :39.00 Max. :39.00
## NA's :72 NA's :61 NA's :52
## field race from career
## Length:4918 Min. :1.000 Length:4918 Length:4918
## Class :character 1st Qu.:2.000 Class :character Class :character
## Mode :character Median :2.000 Mode :character Mode :character
## Mean :2.731
## 3rd Qu.:4.000
## Max. :6.000
## NA's :20
## sports tvsports exercise dining
## Min. : 1.000 Min. : 1.000 Min. : 1.000 Min. : 1.000
## 1st Qu.: 5.000 1st Qu.: 2.000 1st Qu.: 5.000 1st Qu.: 7.000
## Median : 7.000 Median : 4.000 Median : 6.000 Median : 8.000
## Mean : 6.396 Mean : 4.527 Mean : 6.118 Mean : 7.687
## 3rd Qu.: 8.000 3rd Qu.: 7.000 3rd Qu.: 8.000 3rd Qu.: 9.000
## Max. :10.000 Max. :10.000 Max. :10.000 Max. :10.000
## NA's :36 NA's :36 NA's :36 NA's :36
## museums art hiking gaming
## Min. : 0.000 Min. : 0.000 Min. : 0.000 Min. : 0.00
## 1st Qu.: 6.000 1st Qu.: 5.000 1st Qu.: 4.000 1st Qu.: 2.00
## Median : 7.000 Median : 7.000 Median : 6.000 Median : 4.00
## Mean : 6.876 Mean : 6.595 Mean : 5.768 Mean : 4.02
## 3rd Qu.: 8.000 3rd Qu.: 8.000 3rd Qu.: 8.000 3rd Qu.: 6.00
## Max. :10.000 Max. :10.000 Max. :10.000 Max. :14.00
## NA's :36 NA's :36 NA's :36 NA's :36
## clubbing reading tv theater
## Min. : 0.000 Min. : 1.000 Min. : 1.00 Min. : 0.00
## 1st Qu.: 4.000 1st Qu.: 7.000 1st Qu.: 3.00 1st Qu.: 5.00
## Median : 6.000 Median : 8.000 Median : 6.00 Median : 7.00
## Mean : 5.726 Mean : 7.645 Mean : 5.29 Mean : 6.72
## 3rd Qu.: 8.000 3rd Qu.: 9.000 3rd Qu.: 7.00 3rd Qu.: 8.00
## Max. :10.000 Max. :13.000 Max. :10.00 Max. :10.00
## NA's :36 NA's :36 NA's :36 NA's :36
## movies concerts music shopping
## Min. : 0.00 Min. : 0.000 Min. : 1.000 Min. : 1.000
## 1st Qu.: 7.00 1st Qu.: 6.000 1st Qu.: 7.000 1st Qu.: 3.000
## Median : 8.00 Median : 7.000 Median : 8.000 Median : 6.000
## Mean : 7.98 Mean : 6.824 Mean : 7.781 Mean : 5.484
## 3rd Qu.: 9.00 3rd Qu.: 8.000 3rd Qu.: 9.000 3rd Qu.: 7.000
## Max. :10.00 Max. :10.000 Max. :10.000 Max. :10.000
## NA's :36 NA's :36 NA's :36 NA's :36
## yoga attr sinc intel
## Min. : 0.000 Min. : 0.000 Min. : 0.000 Min. : 0.000
## 1st Qu.: 2.000 1st Qu.: 5.000 1st Qu.: 6.000 1st Qu.: 6.000
## Median : 4.000 Median : 6.000 Median : 7.000 Median : 7.000
## Mean : 4.212 Mean : 6.064 Mean : 7.054 Mean : 7.266
## 3rd Qu.: 6.000 3rd Qu.: 7.000 3rd Qu.: 8.000 3rd Qu.: 8.000
## Max. :10.000 Max. :10.000 Max. :10.000 Max. :10.000
## NA's :36 NA's :118 NA's :161 NA's :166
## fun amb shar like
## Min. : 0.000 Min. : 0.000 Min. : 0.00 Min. : 0.000
## 1st Qu.: 5.000 1st Qu.: 6.000 1st Qu.: 4.00 1st Qu.: 5.000
## Median : 6.000 Median : 7.000 Median : 5.00 Median : 6.000
## Mean : 6.289 Mean : 6.697 Mean : 5.32 Mean : 6.051
## 3rd Qu.: 8.000 3rd Qu.: 8.000 3rd Qu.: 7.00 3rd Qu.: 7.000
## Max. :10.000 Max. :10.000 Max. :10.00 Max. :10.000
## NA's :197 NA's :421 NA's :643 NA's :122
## prob match_es attr3_s sinc3_s
## Min. : 0.000 Min. : 0.000 Min. : 3.000 Min. : 3.000
## 1st Qu.: 4.000 1st Qu.: 2.000 1st Qu.: 7.000 1st Qu.: 7.000
## Median : 5.000 Median : 3.000 Median : 7.000 Median : 8.000
## Mean : 5.017 Mean : 3.169 Mean : 7.077 Mean : 7.994
## 3rd Qu.: 7.000 3rd Qu.: 4.000 3rd Qu.: 8.000 3rd Qu.: 9.000
## Max. :10.000 Max. :10.000 Max. :10.000 Max. :10.000
## NA's :156 NA's :460 NA's :2874 NA's :2874
## intel3_s fun3_s amb3_s dec
## Min. : 4.000 Min. : 3.000 Min. : 3.00 Length:4918
## 1st Qu.: 8.000 1st Qu.: 7.000 1st Qu.: 7.00 Class :character
## Median : 8.000 Median : 8.000 Median : 8.00 Mode :character
## Mean : 8.207 Mean : 7.573 Mean : 7.59
## 3rd Qu.: 9.000 3rd Qu.: 9.000 3rd Qu.: 9.00
## Max. :10.000 Max. :10.000 Max. :10.00
## NA's :2874 NA's :2874 NA's :2874
Descrição das variavéis
cat("Descrição das variáveis:\n")
## Descrição das variáveis:
cat("iid: id do participante p1 no encontro\n")
## iid: id do participante p1 no encontro
cat("gender: sexo do p1, 0 = mulher, 1 = homem\n")
## gender: sexo do p1, 0 = mulher, 1 = homem
cat("order: dos vários encontros realizados em uma noite, esse foi o n-ésimo, segundo essa variável\n")
## order: dos vários encontros realizados em uma noite, esse foi o n-ésimo, segundo essa variável
cat("pid: id do participante p2\n")
## pid: id do participante p2
cat("int_corr: correlação entre os interesses de p1 e p2\n")
## int_corr: correlação entre os interesses de p1 e p2
cat("samerace: p1 e p2 são da mesma raça? 1 = sim, 0 = não\n")
## samerace: p1 e p2 são da mesma raça? 1 = sim, 0 = não
cat("age_o: idade de p2\n")
## age_o: idade de p2
cat("age: idade de p1\n")
## age: idade de p1
cat("field: campo de estudo de p1\n")
## field: campo de estudo de p1
cat("race: raça de p1. O código é Black/African American=1; European/Caucasian-American=2; Latino/Hispanic American=3; Asian/Pacific Islander/Asian-American=4; Native American=5; Other=6\n")
## race: raça de p1. O código é Black/African American=1; European/Caucasian-American=2; Latino/Hispanic American=3; Asian/Pacific Islander/Asian-American=4; Native American=5; Other=6
cat("from: de onde p1 é\n")
## from: de onde p1 é
cat("career: que carreira p1 quer seguir\n")
## career: que carreira p1 quer seguir
cat("sports, tvsports, exercise, dining, museums, art, hiking, gaming, clubbing, reading, tv, theater, movies, concerts, music, shopping, yoga: De 1 a 10, quão interessado p1 é em cada uma dessas atividades.\n")
## sports, tvsports, exercise, dining, museums, art, hiking, gaming, clubbing, reading, tv, theater, movies, concerts, music, shopping, yoga: De 1 a 10, quão interessado p1 é em cada uma dessas atividades.
cat("attr: quão atraente p1 achou p2\n")
## attr: quão atraente p1 achou p2
cat("sinc: quão sincero p1 achou p2\n")
## sinc: quão sincero p1 achou p2
cat("intel: quão inteligente p1 achou p2\n")
## intel: quão inteligente p1 achou p2
cat("fun: quão divertido p1 achou p2\n")
## fun: quão divertido p1 achou p2
cat("amb: quão ambicioso p1 achou p2\n")
## amb: quão ambicioso p1 achou p2
cat("shar: quanto p1 achou que compartilha interesses e hobbies com p2\n")
## shar: quanto p1 achou que compartilha interesses e hobbies com p2
cat("like: no geral, quanto p1 gostou de p2?\n")
## like: no geral, quanto p1 gostou de p2?
cat("prob: que probabiliade p1 acha que p2 tem de querer se encontrar novamente com p- (escala 1-10)\n")
## prob: que probabiliade p1 acha que p2 tem de querer se encontrar novamente com p- (escala 1-10)
cat("attr3_s: quanto p1 acha que é atraente\n")
## attr3_s: quanto p1 acha que é atraente
cat("sinc3_s: quanto p1 acha que é sincero\n")
## sinc3_s: quanto p1 acha que é sincero
cat("intel3_s: quanto p1 acha que é inteligente\n")
## intel3_s: quanto p1 acha que é inteligente
cat("fun3_s: quanto p1 acha que é divertido\n")
## fun3_s: quanto p1 acha que é divertido
cat("amb3_s: quanto p1 acha que é ambicioso\n")
## amb3_s: quanto p1 acha que é ambicioso
cat("dec: se houve match entre p1 e p2 - sim ou não.\n")
## dec: se houve match entre p1 e p2 - sim ou não.
Na descrição das variáveis gostaríamos de enfatizar a variável “dec” por ser a variável resposta, representando a decisão tomada por um indivíduo após um encontro de speed dating e a variável “gender” que representa o gênero do indivíduo, ela é do tipo categórica, pode assumir dois valores: “1” para masculino e “0” para feminino.
Podemos inicialmente a partir do código do Prof. Nazareno, realizar uma EDA, uma análise de regressão logística, avaliar o modelo ajustado, criar visualizações gráficas e gerar uma tabela de contingência para comparar as previsões com os valores reais em relação ao gênero, da seguinte forma:
s_dating <- read_csv("5-regressao/speed-dating/speed-dating2.csv") %>%
mutate(dec = as.factor(dec),
gender = as.factor(gender))
## Rows: 4918 Columns: 44
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (4): field, from, career, dec
## dbl (40): iid, gender, order, pid, int_corr, samerace, age_o, age, race, spo...
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
gendermodel <- glm(dec ~ gender,
data = s_dating,
family = "binomial")
tidy(gendermodel, conf.int = TRUE, exponentiate = TRUE)
## # A tibble: 2 × 7
## term estimate std.error statistic p.value conf.low conf.high
## <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 (Intercept) 0.572 0.0420 -13.3 2.00e-40 0.527 0.621
## 2 gender1 1.53 0.0582 7.36 1.87e-13 1.37 1.72
glance(gendermodel)
## # A tibble: 1 × 8
## null.deviance df.null logLik AIC BIC deviance df.residual nobs
## <dbl> <int> <dbl> <dbl> <dbl> <dbl> <int> <int>
## 1 6678. 4917 -3312. 6627. 6640. 6623. 4916 4918
pR2(gendermodel)
## fitting null model for pseudo-r2
## llh llhNull G2 McFadden r2ML
## -3.311624e+03 -3.338863e+03 5.447805e+01 8.158173e-03 1.101615e-02
## r2CU
## 1.483102e-02
expectativa_realidade <- augment(gendermodel,
type.predict = "response")
expectativa_realidade <- expectativa_realidade %>%
mutate(genderNum = ifelse(gender == "1", 1, 0))
ggplot(expectativa_realidade, aes(x = genderNum, y = ..count.., fill = factor(genderNum))) +
geom_bar(alpha = 0.5, position = "dodge") +
geom_text(aes(label = ..count..), stat = "count", position = position_dodge(width = 0.9), vjust = -0.5) +
xlab("Gênero") +
ylab("Contagem") +
scale_fill_manual(values = c("#999999", "#E69F00"), labels = c("Feminino", "Masculino")) +
theme_minimal()
## Warning: The dot-dot notation (`..count..`) was deprecated in ggplot2 3.4.0.
## ℹ Please use `after_stat(count)` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
expectativa_realidade <- expectativa_realidade %>%
mutate(categoria_prevista = ifelse(.fitted > 0.5, "1", "0"))
table(expectativa_realidade$categoria_prevista, expectativa_realidade$gender)
##
## 0 1
## 0 2454 2464
Como anteriormente já disponiblizamos informações básicas sobre cada variável, agora, analisaremos algumas variáveis categóricas usando a função table() para verificar as frequências das categorias.
Depois vamos visualizr a distribuição da idade usando um histograma, também calcularemos a matriz de correlação entre as variáveis numéricas usando a função cor() e as exibiremomos.
No final, optamos por investigar a relação entre a variável “like” (quanto p1 gostou de p2) e a decisão de match. Plotaremos mais um histograma mostrando a distribuição de gostar de p2, com as barras coloridas de acordo com a decisão de match.
OBS: Como o código anterior não completa todas as lacunas, daí vimos a necessidade de acrescer esta EDA para facilitar o entendimento e compreensão dos resultados.
table(s_dating$gender) # Frequência das categorias de sexo
##
## 0 1
## 2454 2464
table(s_dating$race) # Frequência das categorias de raça
##
## 1 2 3 4 6
## 244 2843 399 1111 301
table(s_dating$samerace) # Frequência das categorias de mesma raça
##
## 0 1
## 2920 1998
ggplot(s_dating, aes(x = age)) +
geom_histogram(fill = "blue", color = "white", bins = 20) +
xlab("Idade") +
ylab("Frequência") +
ggtitle("Distribuição de Idade")
## Warning: Removed 52 rows containing non-finite values (`stat_bin()`).
cor_matrix <- cor(s_dating[, c("int_corr", "attr", "sinc", "intel", "fun", "amb", "shar", "like")])
print(cor_matrix)
## int_corr attr sinc intel fun amb shar like
## int_corr 1 NA NA NA NA NA NA NA
## attr NA 1 NA NA NA NA NA NA
## sinc NA NA 1 NA NA NA NA NA
## intel NA NA NA 1 NA NA NA NA
## fun NA NA NA NA 1 NA NA NA
## amb NA NA NA NA NA 1 NA NA
## shar NA NA NA NA NA NA 1 NA
## like NA NA NA NA NA NA NA 1
ggplot(s_dating, aes(x = like, fill = dec)) +
geom_histogram(position = "identity", alpha = 0.7, bins = 20) +
xlab("Gostou de P2") +
ylab("Contagem") +
scale_fill_manual(values = c("blue", "red"), labels = c("Não Match", "Match")) +
ggtitle("Distribuição de Gostar de P2 por Decisão de Match")
## Warning: Removed 122 rows containing non-finite values (`stat_bin()`).
O relatório de regressão logística busca entender como a variável “gender”(gênero-uma pessoa) está relacionada à decisão de ter um segundo encontro (“dec”-decisão se aceitar ou não).Nesse caso, o modelo tenta prever a probabilidade de um indivíduo decidir ter um segundo encontro com base no seu gênero.
Coeficientes: O relatório exibe os coeficientes estimados do modelo de regressão logística. Esses coeficientes representam o efeito do gênero na probabilidade de decidir ter um segundo encontro.
Intervalos de confiança: O relatório também apresenta intervalos de confiança para os coeficientes estimados. Esses intervalos fornecem uma faixa plausível de valores para os coeficientes, com um certo nível de confiança.
Medidas resumidas: O relatório inclui medidas resumidas do modelo de regressão logística, como deviance, AIC (critério de informação de Akaike) e outros. Essas medidas ajudam a avaliar o ajuste do modelo aos dados.
Pseudo R²: O relatório calcula o pseudo R² do modelo de regressão logística. O pseudo R² é uma medida de quão bem o modelo se ajusta aos dados. Ele fornece uma estimativa da proporção da variabilidade na variável resposta que é explicada pelas variáveis independentes.
No final o código também cria uma visualização gráfica usando um gráfico de barras empilhadas. Esse gráfico mostra a contagem das previsões do modelo de regressão logística em relação ao gênero. Ele permite comparar as frequências das previsões para cada categoria de gênero.
sf_dating <- read_csv("5-regressao/speed-dating/speed-dating2.csv")
## Rows: 4918 Columns: 44
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (4): field, from, career, dec
## dbl (40): iid, gender, order, pid, int_corr, samerace, age_o, age, race, spo...
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
proporcao_teste <- 0.3
set.seed(123)
indices_teste <- createDataPartition(sf_dating$dec, times = 1, p = proporcao_teste, list = FALSE)
dados_treino <- sf_dating[-indices_teste, ] # Subconjunto dos dados para treinamento
dados_teste <- sf_dating[indices_teste, ] # Subconjunto dos dados para teste
Observando os resultados abaixo, podemos interpretar os efeitos das variáveis explicativas observando os coeficientes estimados e seus intervalos de confiança. Os valores de odds ratio maiores que 1 indicam um efeito positivo na chance de match, enquanto valores menores que 1 indicam um efeito negativo. A magnitude do efeito é indicada pelo valor do Odds Ratio. Quanto maior o valor, maior é a magnitude do efeito da variável explicativa nas chances de match.
variaveis_explicativas <- c("fun", "shar", "dec", "attr", "amb")
dados <- select(dados_treino, dec, gender, all_of(variaveis_explicativas)) %>%
mutate(dec = as.factor(dec), gender = as.factor(gender))
modelo <- glm(dec ~ ., data = dados, family = "binomial")
resultado <- tidy(modelo, conf.int = TRUE, exponentiate = TRUE)
print(resultado)
## # A tibble: 6 × 7
## term estimate std.error statistic p.value conf.low conf.high
## <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 (Intercept) 0.00360 0.275 -20.4 9.71e-93 0.00208 0.00612
## 2 gender1 1.27 0.0922 2.62 8.88e- 3 1.06 1.52
## 3 fun 1.25 0.0354 6.21 5.44e-10 1.16 1.34
## 4 shar 1.36 0.0288 10.6 2.68e-26 1.28 1.44
## 5 attr 1.78 0.0339 17.0 6.36e-65 1.67 1.90
## 6 amb 0.801 0.0334 -6.63 3.25e-11 0.750 0.855
ggplot(resultado, aes(x = term, y = estimate)) +
geom_point() +
geom_errorbar(aes(ymin = conf.low, ymax = conf.high), width = 0.2) +
coord_flip() +
xlab("Variável") +
ylab("Odds Ratio") +
ggtitle("Magnitude dos Efeitos nas Chances de Match")
modelo <- glm(dec ~ ., data = dados, family = "binomial")
pr2 <- pR2(modelo)
## fitting null model for pseudo-r2
print(pr2)
## llh llhNull G2 McFadden r2ML
## -1447.9080320 -1982.5605795 1069.3050948 0.2696778 0.3076831
## r2CU
## 0.4134184
previsoes <- predict(modelo, newdata = dados, type = "response")
previsoes_binarias <- ifelse(previsoes > 0.5, 1, 0)
matriz_confusao <- table(dados$dec, previsoes_binarias)
acuracia <- sum(diag(matriz_confusao)) / sum(matriz_confusao)
print(acuracia)
## [1] 0.7489684
verdadeiros_positivos <- matriz_confusao[2, 2]
falsos_positivos <- matriz_confusao[1, 2]
precisao <- verdadeiros_positivos / (verdadeiros_positivos + falsos_positivos)
print(precisao)
## [1] 0.7178602
VP <- matriz_confusao[2, 2] # Verdadeiros positivos
VN <- matriz_confusao[1, 1] # Verdadeiros negativos
classificacoes_corretas <- VP + VN
print(classificacoes_corretas)
## [1] 2178
VP <- matriz_confusao[2, 2] # Verdadeiros positivos
FN <- matriz_confusao[2, 1] # Falsos negativos
recall <- VP / (VP + FN)
print(recall)
## [1] 0.6736842
VP <- matriz_confusao[2, 2] # Verdadeiros positivos
FP <- matriz_confusao[1, 2] # Falsos positivos
FN <- matriz_confusao[2, 1] # Falsos negativos
precisao <- VP / (VP + FP)
recall <- VP / (VP + FN)
fscore <- 2 * (precisao * recall) / (precisao + recall)
print(fscore)
## [1] 0.695071
auc <- roc(dados$dec, previsoes)$auc
## Setting levels: control = no, case = yes
## Setting direction: controls < cases
print(auc)
## Area under the curve: 0.8316
O valor de R² ajustado (pR2) do modelo é 0.269 (McFadden), que representa a proporção da variabilidade explicada pelas variáveis explicativas incluídas no modelo de regressão logística. Então, podemos inferir que quanto mais próximo de 1 for o valor de pR2, melhor é o ajuste do modelo aos dados, mas também é dito por McFadden, D. (1973) (https://scholar.google.com/scholar?q=Conditional+logit+analysis+of+qualitative+choice+behavior+Daniel+McFadden) que em alguns casos os valores entre 0,2 e 0,4 podem ser considerados aceitáveis.
A acuráncia do modelo é representativa com 74.89%.
Como podemos notar o valor da AUC é igual a 83.16% e este aproxima-se bastante de 1, indicando um melhor desempenho do modelo em termos de separação entre as classes positiva e negativa.
Os fatores nos dados têm efeito positivos porque a taxa de verdadeiros positivos é maior, quanto a magnitude o modelo apresenta valores consideráveis nos cálculos das métricas tendo um resultado entre 70% a 83%.