Neste problema, utilizaremos dados românticos descritos e disponíveis aqui: https://github.com/nazareno/ciencia-de-dados-1/tree/master/5-regressao/speed-dating
Especialmente, atente para uma coluna chamada dec, que diz se houve match entre os dois participantes do encontro – isso é: ambos disseram que gostariam de se encontrar novamente depois: https://github.com/nazareno/ciencia-de-dados-1/blob/master/5-regressao/speed-dating/speed-dating2.csv
Sua missão é utilizar regressão logística em um conjunto de variáveis explicativas que você escolher (com no mínimo 4 variáveis) para responder o seguinte com esses dados em um RMarkdown:
Que fatores nos dados têm efeito re;evante na chance do casal ter um match? Descreva se os efeitos são positivos ou negativos e sua magnitude.
Lembre que temos apenas uma amostra de encontros.
Lembre de fazer um descritivo das variáveis antes, e de escrever o relatório de maneira que alguém que saiba sobre regressão mas não sabe nada sobre os dados entenda.
Registered S3 method overwritten by 'dplyr':
method from
print.rowwise_df
[30m── [1mAttaching packages[22m ─────────────────────────────────────────────────────────── tidyverse 1.2.1 ──[39m
[30m[32m✔[30m [34mggplot2[30m 3.2.0 [32m✔[30m [34mpurrr [30m 0.3.2
[32m✔[30m [34mtibble [30m 2.1.3 [32m✔[30m [34mdplyr [30m 0.8.3
[32m✔[30m [34mtidyr [30m 0.8.3 [32m✔[30m [34mstringr[30m 1.4.0
[32m✔[30m [34mreadr [30m 1.3.1 [32m✔[30m [34mforcats[30m 0.4.0[39m
[30m── [1mConflicts[22m ────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
[31m✖[30m [34mdplyr[30m::[32mfilter()[30m masks [34mstats[30m::filter()
[31m✖[30m [34mdplyr[30m::[32mlag()[30m masks [34mstats[30m::lag()[39m
Attaching package: ‘modelr’
The following object is masked from ‘package:broom’:
bootstrap
here() starts at /cloud/project/5-regressao
Registered S3 method overwritten by 'GGally':
method from
+.gg ggplot2
Attaching package: ‘GGally’
The following object is masked from ‘package:dplyr’:
nasa
Classes and Methods for R developed in the
Political Science Computational Laboratory
Department of Political Science
Stanford University
Simon Jackman
hurdle and zeroinfl functions by Achim Zeileis
dados = read_csv(here::here("speed-dating/speed-dating2.csv"))
Parsed with column specification:
cols(
.default = col_double(),
field = [31mcol_character()[39m,
from = [31mcol_character()[39m,
career = [31mcol_character()[39m,
attr3_s = [33mcol_logical()[39m,
sinc3_s = [33mcol_logical()[39m,
intel3_s = [33mcol_logical()[39m,
fun3_s = [33mcol_logical()[39m,
amb3_s = [33mcol_logical()[39m,
dec = [31mcol_character()[39m
)
See spec(...) for full column specifications.
10220 parsing failures.
row col expected actual file
1847 attr3_s 1/0/T/F/TRUE/FALSE 8.00 '/cloud/project/5-regressao/speed-dating/speed-dating2.csv'
1847 sinc3_s 1/0/T/F/TRUE/FALSE 10.00 '/cloud/project/5-regressao/speed-dating/speed-dating2.csv'
1847 intel3_s 1/0/T/F/TRUE/FALSE 9.00 '/cloud/project/5-regressao/speed-dating/speed-dating2.csv'
1847 fun3_s 1/0/T/F/TRUE/FALSE 10 '/cloud/project/5-regressao/speed-dating/speed-dating2.csv'
1847 amb3_s 1/0/T/F/TRUE/FALSE 10 '/cloud/project/5-regressao/speed-dating/speed-dating2.csv'
.... ........ .................. ...... ...........................................................
See problems(...) for more details.
dados = dados %>%
filter(!is.na(attr), !is.na(fun), !is.na(intel), !is.na(sinc), !is.na(amb), !is.na(shar), !is.na(prob), !is.na(like)) %>%
mutate(dec = case_when(.$dec == "no" ~ 0,
.$dec == "yes" ~ 1))
glimpse(dados)
Observations: 4,101
Variables: 44
$ iid [3m[38;5;246m<dbl>[39m[23m 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,…
$ gender [3m[38;5;246m<dbl>[39m[23m 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ order [3m[38;5;246m<dbl>[39m[23m 4, 3, 5, 7, 6, 1, 2, 8, 9, 10, 9, 6, 1, 3, 2, 7, 8, 4, 5, 6, 5, 2, 7, 3, 4, 10, …
$ pid [3m[38;5;246m<dbl>[39m[23m 11, 12, 14, 15, 16, 17, 18, 19, 20, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 11, …
$ int_corr [3m[38;5;246m<dbl>[39m[23m 0.14, 0.54, 0.61, 0.21, 0.25, 0.34, 0.50, 0.28, -0.36, 0.29, 0.18, 0.10, -0.21, …
$ samerace [3m[38;5;246m<dbl>[39m[23m 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,…
$ age_o [3m[38;5;246m<dbl>[39m[23m 27, 22, 23, 24, 25, 30, 27, 28, 24, 27, 22, 22, 23, 24, 25, 30, 27, 28, 24, 27, …
$ age [3m[38;5;246m<dbl>[39m[23m 21, 21, 21, 21, 21, 21, 21, 21, 21, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, …
$ field [3m[38;5;246m<chr>[39m[23m "Law", "Law", "Law", "Law", "Law", "Law", "Law", "Law", "Law", "law", "law", "la…
$ race [3m[38;5;246m<dbl>[39m[23m 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,…
$ from [3m[38;5;246m<chr>[39m[23m "Chicago", "Chicago", "Chicago", "Chicago", "Chicago", "Chicago", "Chicago", "Ch…
$ career [3m[38;5;246m<chr>[39m[23m "lawyer", "lawyer", "lawyer", "lawyer", "lawyer", "lawyer", "lawyer", "lawyer", …
$ sports [3m[38;5;246m<dbl>[39m[23m 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,…
$ tvsports [3m[38;5;246m<dbl>[39m[23m 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 8, 8, 8, 8, 8, 8, 8, 8,…
$ exercise [3m[38;5;246m<dbl>[39m[23m 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,…
$ dining [3m[38;5;246m<dbl>[39m[23m 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 8, 8, 8, 8, 8…
$ museums [3m[38;5;246m<dbl>[39m[23m 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 5, 5, 5, 5, 5, 5, 5, 5,…
$ art [3m[38;5;246m<dbl>[39m[23m 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5,…
$ hiking [3m[38;5;246m<dbl>[39m[23m 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 8, 8, 8, 8, 8, 8, 8, 8,…
$ gaming [3m[38;5;246m<dbl>[39m[23m 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,…
$ clubbing [3m[38;5;246m<dbl>[39m[23m 5, 5, 5, 5, 5, 5, 5, 5, 5, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 5, 5, 5, 5, 5, 5, 5, 5,…
$ reading [3m[38;5;246m<dbl>[39m[23m 6, 6, 6, 6, 6, 6, 6, 6, 6, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 7, 7, 7, 7, 7…
$ tv [3m[38;5;246m<dbl>[39m[23m 9, 9, 9, 9, 9, 9, 9, 9, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 8, 8, 8, 8, 8, 8,…
$ theater [3m[38;5;246m<dbl>[39m[23m 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, 7, 7, 7, 7, 7, 7, 7,…
$ movies [3m[38;5;246m<dbl>[39m[23m 10, 10, 10, 10, 10, 10, 10, 10, 10, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7,…
$ concerts [3m[38;5;246m<dbl>[39m[23m 10, 10, 10, 10, 10, 10, 10, 10, 10, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,…
$ music [3m[38;5;246m<dbl>[39m[23m 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 5, 5, 5, 5, 5, 5, 5, 5,…
$ shopping [3m[38;5;246m<dbl>[39m[23m 8, 8, 8, 8, 8, 8, 8, 8, 8, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 8, 8, 8, 8, 8, 8, 8, 8,…
$ yoga [3m[38;5;246m<dbl>[39m[23m 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, 7, 7, 7, 7, 7, 7, 7,…
$ attr [3m[38;5;246m<dbl>[39m[23m 6, 7, 7, 5, 4, 7, 4, 7, 5, 5, 8, 5, 7, 6, 8, 7, 5, 7, 6, 7, 9, 7, 9, 8, 7, 9, 8,…
$ sinc [3m[38;5;246m<dbl>[39m[23m 9, 8, 6, 6, 9, 6, 9, 6, 6, 7, 5, 8, 9, 8, 7, 5, 8, 6, 7, 9, 7, 9, 7, 9, 9, 9, 7,…
$ intel [3m[38;5;246m<dbl>[39m[23m 7, 7, 8, 7, 7, 7, 7, 8, 6, 8, 6, 9, 7, 7, 8, 9, 7, 8, 8, 10, 9, 9, 9, 10, 9, 9, …
$ fun [3m[38;5;246m<dbl>[39m[23m 7, 8, 7, 7, 4, 4, 6, 9, 8, 4, 6, 6, 6, 9, 3, 6, 5, 9, 7, 7, 8, 7, 7, 7, 8, 9, 7,…
$ amb [3m[38;5;246m<dbl>[39m[23m 6, 5, 6, 6, 6, 6, 5, 8, 10, 6, 9, 3, 5, 7, 6, 7, 9, 4, 9, 8, 9, 9, 9, 7, 9, 9, 9…
$ shar [3m[38;5;246m<dbl>[39m[23m 5, 6, 8, 6, 4, 7, 6, 8, 8, 3, 6, 4, 7, 8, 2, 9, 5, 5, 8, 9, 7, 7, 7, 9, 7, 9, 7,…
$ like [3m[38;5;246m<dbl>[39m[23m 7, 7, 7, 6, 6, 6, 6, 7, 6, 6, 7, 6, 7, 8, 6, 8, 5, 5, 8, 8, 8, 8, 8, 8, 8, 9, 8,…
$ prob [3m[38;5;246m<dbl>[39m[23m 6, 5, 6, 6, 5, 5, 7, 7, 6, 4, 3, 7, 8, 6, 5, 7, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7,…
$ match_es [3m[38;5;246m<dbl>[39m[23m 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, NA, NA, NA, NA, NA, NA,…
$ attr3_s [3m[38;5;246m<lgl>[39m[23m NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
$ sinc3_s [3m[38;5;246m<lgl>[39m[23m NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
$ intel3_s [3m[38;5;246m<lgl>[39m[23m NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
$ fun3_s [3m[38;5;246m<lgl>[39m[23m NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
$ amb3_s [3m[38;5;246m<lgl>[39m[23m NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
$ dec [3m[38;5;246m<dbl>[39m[23m 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,…
skimr::skim(dados)
Skim summary statistics
n obs: 4101
n variables: 44
── Variable type:character ─────────────────────────────────────────────────────────────────────────
variable missing complete n min max empty n_unique
career 38 4063 4101 2 77 0 215
field 13 4088 4101 3 51 0 145
from 28 4073 4101 2 58 0 171
── Variable type:logical ───────────────────────────────────────────────────────────────────────────
variable missing complete n mean count
amb3_s 4101 0 4101 NaN 4101
attr3_s 4101 0 4101 NaN 4101
fun3_s 4101 0 4101 NaN 4101
intel3_s 4101 0 4101 NaN 4101
sinc3_s 4101 0 4101 NaN 4101
── Variable type:numeric ───────────────────────────────────────────────────────────────────────────
variable missing complete n mean sd p0 p25 p50 p75 p100 hist
age 37 4064 4101 25.7 3.23 18 23 25 28 38 ▁▇▆▇▃▁▁▁
age_o 43 4058 4101 25.72 3.32 18 23 25 28 39 ▁▇▆▇▃▁▁▁
amb 0 4101 4101 6.68 1.84 0 5.5 7 8 10 ▁▁▁▇▇▇▇▆
art 28 4073 4101 6.59 2.33 0 5 7 8 10 ▁▁▃▇▃▆▇▇
attr 0 4101 4101 6.05 1.94 0 5 6 7 10 ▁▁▂▇▆▆▅▃
clubbing 28 4073 4101 5.72 2.46 0 4 6 8 10 ▃▂▃▇▆▆▇▅
concerts 28 4073 4101 6.81 2.14 0 6 7 8 10 ▁▁▂▅▆▆▆▇
dec 0 4101 4101 0.42 0.49 0 0 0 1 1 ▇▁▁▁▁▁▁▆
dining 28 4073 4101 7.69 1.77 1 7 8 9 10 ▁▁▁▂▂▅▅▇
exercise 28 4073 4101 6.13 2.35 1 5 6 8 10 ▅▃▃▆▇▇▇▇
fun 0 4101 4101 6.27 1.99 0 5 6 8 10 ▁▁▂▇▇▇▆▅
gaming 28 4073 4101 4.04 2.65 0 2 4 6 14 ▆▇▆▆▂▁▁▁
gender 0 4101 4101 0.5 0.5 0 0 0 1 1 ▇▁▁▁▁▁▁▇
hiking 28 4073 4101 5.66 2.54 0 4 6 8 10 ▂▃▅▇▆▅▆▆
iid 0 4101 4101 273.48 184.73 1 87 271 433 552 ▇▇▁▆▃▅▃▇
int_corr 52 4049 4101 0.19 0.31 -0.73 -0.03 0.21 0.43 0.9 ▁▂▅▆▇▇▅▁
intel 0 4101 4101 7.25 1.59 0 6 7 8 10 ▁▁▁▃▅▇▇▆
like 0 4101 4101 6.03 1.86 0 5 6 7 10 ▁▁▂▇▇▇▅▂
match_es 348 3753 4101 3.1 2.4 0 2 3 4 10 ▇▇▆▆▁▁▁▂
movies 28 4073 4101 7.94 1.72 0 7 8 9 10 ▁▁▁▁▂▃▅▇
museums 28 4073 4101 6.89 2.11 0 6 7 8 10 ▁▁▂▅▃▇▆▇
music 28 4073 4101 7.8 1.88 1 7 8 9 10 ▁▁▁▂▂▃▃▇
order 0 4101 4101 9.09 5.61 1 4 8 13 22 ▇▇▅▆▅▃▃▂
pid 8 4093 4101 273.74 184.24 1 88 273 433 552 ▇▇▁▆▃▅▃▇
prob 0 4101 4101 5.04 2.18 0 4 5 7 10 ▂▂▂▇▃▃▂▁
race 13 4088 4101 2.75 1.23 1 2 2 4 6 ▁▇▁▁▃▁▁▁
reading 28 4073 4101 7.65 2.06 1 7 8 9 13 ▁▁▁▅▃▇▁▁
samerace 0 4101 4101 0.4 0.49 0 0 0 1 1 ▇▁▁▁▁▁▁▆
shar 0 4101 4101 5.3 2.16 0 4 5 7 10 ▁▂▂▇▅▃▂▂
shopping 28 4073 4101 5.51 2.59 1 4 6 7 10 ▇▃▅▆▆▆▅▆
sinc 0 4101 4101 7.03 1.81 0 6 7 8 10 ▁▁▁▅▆▇▇▆
sports 28 4073 4101 6.37 2.53 1 5 7 8 10 ▃▂▃▃▅▅▆▇
theater 28 4073 4101 6.69 2.28 0 5 7 8 10 ▁▁▂▆▃▆▅▇
tv 28 4073 4101 5.32 2.47 1 3 6 7 10 ▇▃▃▆▇▆▆▃
tvsports 28 4073 4101 4.55 2.81 1 2 4 7 10 ▇▃▂▂▂▂▂▃
yoga 28 4073 4101 4.17 2.72 0 2 3 6 10 ▇▆▆▆▃▃▂▃
Após essa análise rápida, vamos analisar melhor alguns dos dados no próximo tópico.
Faremos a análise das informações que o participante dá uma nota de 1 a 10 no formulário que recebe. Essas informações são as seguintes:
As quantidades para cada resposta foram:
dados %>%
ggplot(aes(attr)) +
geom_bar() +
scale_x_continuous(breaks=seq(0, 10, 1))
dados %>%
ggplot(aes(sinc)) +
geom_bar() +
scale_x_continuous(breaks=seq(0, 10, 1))
dados %>%
ggplot(aes(intel)) +
geom_bar() +
scale_x_continuous(breaks=seq(0, 10, 1))
dados %>%
ggplot(aes(fun)) +
geom_bar() +
scale_x_continuous(breaks=seq(0, 10, 1))
dados %>%
ggplot(aes(amb)) +
geom_bar() +
scale_x_continuous(breaks=seq(0, 10, 1))
dados %>%
ggplot(aes(shar)) +
geom_bar() +
scale_x_continuous(breaks=seq(0, 10, 1))
dados %>%
ggplot(aes(like)) +
geom_bar() +
scale_x_continuous(breaks=seq(0, 10, 1))
dados %>%
ggplot(aes(prob)) +
geom_bar() +
scale_x_continuous(breaks=seq(0, 10, 1))
Com isso, temos material para inferir que talvez essas variáveis se relacionem e possam influenciar no match, visto que essas distribuições das respostas se aproximam de uma distribuição normal. Veremos também o número de decisões “não” (0 no gráfico) e “sim” (1 no gráfico)
# decisoes (0 = no, 1 = yes)
dados %>%
ggplot(aes(dec)) +
geom_bar() +
scale_x_continuous(breaks=seq(0, 1, by = 1))
Visto isso, parece que há alguma relação entre as variáveis escolhidas e a decisão de se encontrar novamente. Já podemos passar para a modelagem.
modelo1 <- glm(dec ~ attr + fun + intel + sinc + amb + shar + like + prob,
data = dados,
family = "binomial")
tidy(modelo1, conf.int = TRUE)
tidy(modelo1, conf.int = TRUE, exponentiate = TRUE)
glance(modelo1)
pR2(modelo1)
llh llhNull G2 McFadden r2ML r2CU
-1888.4241414 -2793.2364426 1809.6246024 0.3239297 0.3567773 0.4795981
dec = 0,43 attr + 0,12 fun - 0,04 intel - 0,23 sinc - 0,21 amb + 0,15 shar + 0,62 like + 0,16 prob - 5,99
Descrevendo se os efeitos são positivos ou negativos e sua magnitude:
Tudo isso aconteceria caso a regressão fosse linear. Como não é, precisamos EXPONENCIAR.
dec = exp(1.54 * attr) * exp(1.13 * fun) * exp(0.95 * intel) * exp(0.79 * sinc) * exp(0.80 * amb) * exp(1.16 * shar) * exp(1.85 * like) * exp(1.18 * prob) * 0.002
Descrevendo se os efeitos são positivos ou negativos e sua magnitude:
Plotando o gráfico para a regressão utilizando apenas dec e fun:
dados %>% ggplot(aes(fun, dec))+geom_jitter(size=0.5)+geom_smooth(method = "glm",
method.args = list(family = "binomial"),
se = FALSE)
dados %>%
mutate(dec = as.factor(dec),
gender = as.factor(gender))
gendermodel = glm(dec ~ gender,
data = dados,
family = "binomial")
tidy(gendermodel, conf.int = TRUE, exponentiate = TRUE)
glance(gendermodel)
pR2(gendermodel)
llh llhNull G2 McFadden r2ML r2CU
-2.760453e+03 -2.793236e+03 6.556702e+01 1.173675e-02 1.586093e-02 2.132106e-02
expectativa_realidade <- augment(gendermodel,
type.predict = "response")
expectativa_realidade %>%
mutate(genderNum = ifelse(gender == "1", 1, 0)) %>%
ggplot(aes(x = gender )) +
geom_count(aes(y = genderNum), alpha = 0.5) +
geom_line(aes(y = .fitted))
expectativa_realidade = expectativa_realidade %>%
mutate(categoria_prevista = ifelse(.fitted > .5, "1", "0"))
table(expectativa_realidade$categoria_prevista, expectativa_realidade$gender)
0 1
0 2068 2033