---
title: "Caso 06: Classificador de digitos - CART e Ensembles"
output:
  html_document: default
  pdf_document: default
---
## autor: *Rodrigo A. Scarpel*

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
  
___
  
### Pacotes do R utilizados:
+ Caret (https://cran.r-project.org/web/packages/caret/index.html)
+ Rpart (https://cran.r-project.org/web/packages/rpart/index.html)
+ Rpart.plot (https://cran.r-project.org/web/packages/rpart.plot/index.html)
+ Partykit (https://cran.r-project.org/web/packages/partykit/index.html)

```{r include = TRUE, message=FALSE, warning=FALSE}
library(caret)
library(rpart)
library(rpart.plot)
library(partykit)
```


___  
  
### Etapa 1: Selecao dos dados  
  
```{r include = TRUE}
load(file="df_classificador.Rdata")
str(DADOS)
```
  
  
___  

### Etapa 2: Pre-processamento (ja realizado nos casos anteriores)  
  

___  

### Etapa 3: Transformacao dos dados  
  

#### Divisao dos dados em amostras de treinamento e de teste do modelo:  
  
  Nesta etapa os dados serao divididos de forma a ficar 60% para treinamento do modelo e 40% para teste do modelo. Assim:

  
```{r include = TRUE}
set.seed(326)
Treino.Index <- createDataPartition(y = DADOS$y, p = 0.6, 
                                    times = 1,list = FALSE)
treino <- DADOS[Treino.Index,]
teste <- DADOS[-Treino.Index,]
message('Distribuicao das classes na base de treino:');table(treino$y)
message('')
message('Distribuicao das classes na base de teste:');table(teste$y)
```
  
___  

### Etapa 4: Mineracao dos dados  
  

___

#### CART:  
  
  Para criar a árvore de regressão e classificação (CART) as etapas são: 1. Utilizando validação cruzada (5-fold), identificar o número ideal de nós terminais da árvore (para evitar overfitting); 2. Fazer a poda da árvore utilizando o índice de complexidade. 3. Gerar a árvore podada.  


- Tamanho ideal da árvore pelo pacote rpart:  

```{r}
set.seed(123)
fit.cart <- rpart(y~., method="class", data=treino)
printcp(fit.cart)
plotcp(fit.cart)
```
  
  
- Validacao cruzada:
  
```{r include = TRUE, fig.width=12}
set.seed(123)
fit.CART = train(y ~ .,method ='rpart',
               trControl=trainControl(method='cv',number = 5),
               metric     = "Accuracy",
               tuneLength = 5,
               data       = treino)
fit.CART
plot(fit.CART)
plot(as.party(fit.CART$finalModel), type="extended",use.n=F)
prp(fit.CART$finalModel,type = 4,extra = 4,box.palette="auto",faclen = 0)
```
   
   
- Poda da árvore e vizualização da árvore podada:  

```{r include = TRUE, fig.width=12}
fit <- rpart(y ~ ., data=treino)
pfit<- prune(fit.cart, cp=0.01202749)
plot(as.party(pfit), type="extended",use.n=F)
prp(pfit,type = 4,extra = 4,box.palette="auto",faclen = 0)
pfit<- prune(fit.cart, cp=0.014)
plot(as.party(pfit), type="extended",use.n=F)
prp(pfit,type = 4,extra = 4,box.palette="auto",faclen = 0)
```


- Resultado do classificador:   
   
```{r}
x_1 = seq(0,0.5,0.001)
x_2 = seq(0,0.6,0.001)
z = data.frame(expand.grid(x_1,x_2))
colnames(z) = c("x_1","x_2")
P.CLASS.cart <- predict(pfit,newdata = z,type = "class")
plot(z,col=unclass(P.CLASS.cart))
P.CLASS.CART <- predict(fit.CART,newdata = z)
plot(z,col=unclass(P.CLASS.CART))
```

___

#### Classificador *Bagging*:
  
  
Para criar o Bagging as etapas são: 1. Utilizando validação cruzada (10-fold), identificar o número ideal árvores; 2. Gerar o modelo com o número ideal de árvores.  
  
  
- Validacao cruzada (50, 100, 150 e 200 árvores):  
  
  
```{r include = TRUE}
set.seed(123)
modellist <- list()
for (ntree in c(50,100,150,200)){
  fit.BAG <- train(y ~ ., method='treebag', 
                   trControl=trainControl(method="cv",number=5),
                   metric = 'Accuracy',
                   data       = treino,
                   ntree = ntree)
  key <- toString(ntree)
  modellist[[key]] <- fit.BAG
}
resultados <- resamples(modellist)
summary(resultados)
dotplot(resultados)
```
  
  
- *Bagging* com 200 árvores:

```{r include = TRUE}
set.seed(123)
fit.BAG = train(y ~ .,method ='treebag',
               trControl=trainControl(method="cv",number=5),
               metric     = "Accuracy",
               data       = treino,
               ntree = 200,
               importance=TRUE)
fit.BAG
plot(varImp(fit.BAG))
```
  
  

___

#### *Random Forest*:
  
Para criar o Random Forest as etapas são: 1. Utilizando validação cruzada (5-fold), identificar o número ideal variáveis por árvore; 2. Gerar o modelo com o número ideal de variáveis por árvore.
  
  
- Validação cruzada (1 a 2 variáveis por árvore):  
  

```{r include = TRUE}
set.seed(123)
fit.RF = train(y ~ . + I(x_1*x_2) + I(x_1^2) + I(x_2^2) + 
                 log(x_1+0.001) + log(x_2+0.001),
               method ='rf',
               trControl=trainControl(method="cv",number=5),
               metric     = "Accuracy",
               data       = treino,
               tuneGrid = expand.grid(mtry = 1:4))
plot(fit.RF)
```
  
    
- Resultado:  
  

```{r include = TRUE}
set.seed(123)
fit.RF = train(y ~ . + I(x_1*x_2) + I(x_1^2) + I(x_2^2) + 
                 log(x_1+0.001) + log(x_2+0.001),
               method ='rf',
               trControl=trainControl(method="cv",number=5),
               metric     = "Accuracy",
               data       = treino,
               importance=TRUE,
               tuneGrid = expand.grid(mtry = 2))
fit.RF
plot(varImp(fit.RF))
```  
  

- Resultado do classificador:   
   
```{r}
x_1 = seq(0,0.5,0.001)
x_2 = seq(0,0.6,0.001)
z = data.frame(expand.grid(x_1,x_2))
colnames(z) = c("x_1","x_2")
P.CLASS.RF <- predict(fit.RF,newdata = z)
plot(z,col=unclass(P.CLASS.RF))
```  
  
___  
  
#### Comparação dos desempenhos (validação cruzada):  


```{r include = TRUE}
resultados <- resamples(list(CART=fit.CART,BAG=fit.BAG,RF=fit.RF))
dotplot(resultados)
```
   
- Performance consolidada, no conjunto treino:  
  
```{r}
Prev.treino <- predict(fit.CART,newdata = treino)
confusionMatrix(factor(Prev.treino), factor(treino$y))
```   
   
___ 
  
  
### Etapa 5: Avaliacao dos resultados (conjunto de teste)  
  
```{r include = TRUE}
Prev.teste <- predict(fit.CART,newdata = teste)
confusionMatrix(factor(teste$y), factor(Prev.teste))
```
   
Portanto, não verifica-se a ocorrencia de *overfitting*.  
___   
   
#### Aplicacao da regra de classificacao:  
   

Qual sera a classificacao de um digito com:\
- x_1: 0.1253\
- x_2: 0.2714

```{r include = TRUE}
nova.observacao = data.frame(
  x_1 = 0.1253,
  x_2 = 0.2714)
predict(fit.CART,nova.observacao)
predict(fit.CART,nova.observacao,type = "prob")
```
  
Portanto, será da classe 2.

___ 


