```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```

# Regressão vs Classificação

Regressão: queremos prever uma variável numérica
Classificação: queremos prever uma variável categórica

O que muda?

- Modelo
- Estimação (função de perda)
- Métrica

# Regressão logística

Seja Y uma variável que pode assumir duas categorias.

Por exemplo: Y = 1 (bom cliente), Y = 0 (mau cliente)

Antes, estávamos modelando

$$
E(Y|X)
$$

O que queremos é modelar 

$$
P(Y = 1| X)
$$

Então

$$
P(Y = 1| X) \approx f(X)
$$

Na regressão linear:

$$
f(x) = \beta_0 + \beta_1x_1 + \beta_2x_2 + ... + \beta_px_p
$$

> Por que não podemos usar essa mesma função para uma variável categórica?

Vamos usar então

$$
f(x) = \frac{1}{1 + e^{-( \beta_0 +  \beta_1*x_1 + \beta_2*x_2 + ... + \beta_p * x_p)}}
$$

```{r}
f <- function(x) 1/(1 + exp(-x))
tibble(
  x = seq(-10, 10, 0.1),
  y = f(x)
) %>% 
  ggplot(aes(x = x, y = y)) +
  geom_line() +
  theme_minimal()
```

Equivalentemente

$$
P(Y = 1| X) \approx \frac{1}{1 + e^{-( \beta_0 +  \beta_1*x_1 + \beta_2*x_2 + ... + \beta_p * x_p)}}
$$
e

$$
\log \left(\frac{P(Y = 1| X)}{1 - P(Y = 1| X)}\right) \approx \beta_0 +  \beta_1*x_1 + \beta_2*x_2 + ... + \beta_p * x_p
$$

Minimizar 

$$
L(y, \hat{f}(x))
$$

Antes, tínhamos

$$
L(y, f(x)) = \sum(y - f(x))^2
$$

Agora, queremos maximizar

$$
L = -\prod_{i:Y_i = 1} P(Y_i=1|X_i) \prod_{i:Y_i = 0} (1 - P(Y_i=1|X_i))
$$

Portanto, como

$$
P(Y = 1| X) \approx f(X)
$$

vamos minimizar

$$
L(y, f(x)) = - \prod_{i:Y_i = 1} f(x_i) \prod_{i:Y_i = 0} (1 - f(x_i)))
$$

Previsões: probabilidade estimada de P(Y = 1|X). 
Precisamos definir então quando escolhemos Y = 1 e Y = 0.

# Pacotes

```{r}
# install.packages("rsample")
# install.packages("skimr")

library(tidyverse)
library(recipes)
library(caret)
library(rsample)
library(skimr)
```

# Banco de dados

```{r}
data("credit_data")
glimpse(credit_data)
```

```{r}
skim(credit_data)

credit_data %>% 
  group_by(Status) %>% 
  skim()
```

# Ajustando modelos

```{r}
receita <- recipe(Status ~ ., data = credit_data) %>%
  step_meanimpute(all_numeric(), -all_outcomes()) %>%
  step_modeimpute(all_nominal(), -all_outcomes()) %>%
  step_dummy(all_nominal(), -all_outcomes()) %>%
  step_corr(all_predictors()) %>%
  step_nzv(all_predictors())

modelo <- train(
  receita, 
  credit_data, 
  method = "glm", 
  family = binomial
)

modelo
varImp(modelo)
```

# Avaliando o modelo

```{r}
credit_data %>% 
  mutate(pred = predict(modelo, credit_data)) %>% 
  count(Status, pred) 
```

- sensibilidade: taxa de *true positives", entre os bons clientes, quantos foram previstos como bons clientes.

- especificidade: taxa de *true negatives", entre os maus clientes, quantos foram previstos como maus clientes.

- área sob a curva ROC


```{r}
# Sensibilidade
2930/(2930+270)

# Especificidade
605/(605+649)

# Curva ROC
library(pROC)

tibble(
  obs = credit_data$Status,
  prob_predita = modelo$finalModel$fitted.values,
  class_predita = ifelse(prob_predita >= 0.5, "good", "bad")
) %>% View()

plot.roc(
  credit_data$Status, 
  modelo$finalModel$fitted.values, 
  legacy.axes = TRUE
)

a <- pROC::roc(
  credit_data$Status, 
  modelo$finalModel$fitted.values
)

a$thresholds
a$sensitivities
a$specificities
```

# Exercício

Ajuste um modelo de regressão logística p/ prever o churn de funcionários no banco de dados `attrition`.

```{r}
library(tidyverse)
library(recipes)
library(caret)
library(rsample)


data(attrition, package = "rsample")
glimpse(attrition)

skim(attrition)
```

```{r}
receita <- recipe(Attrition ~ ., data = attrition) %>%
  step_dummy(all_nominal(), -all_outcomes()) %>%
  step_corr(all_predictors()) %>%
  step_nzv(all_predictors())

modelo <- train(
  receita,
  attrition,
  method = "glm",
  family = binomial
)

modelo

attrition %>% 
  mutate(
    predicao = predict(modelo, attrition)
  ) %>% 
  count(Attrition, predicao)

114/(123 + 114)
1201/(1201+32)

attrition %>% 
  count(Attrition) %>% 
  mutate(prop = n/sum(n))

attrition %>% 
  mutate(
    predicao = predict(modelo, attrition),
    acerto = ifelse(predicao == Attrition, 1, 0)
  ) %>% 
  summarise(acc = mean(acerto))

pROC::roc(
  attrition$Attrition, 
  modelo$finalModel$fitted.values
)
```

