#~~~~~~~~~~~~~~~~ 1 - IMPORTAÇÂO DOS DADOS~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Definir diretório aonde encontra-se a planilha
setwd("C:/Trabalho_IVs_SR")
#Importar a planilha e armazenar dentro do objeto dados
dados=read.table("planilha_ivs_COMPLETA.csv", header = T, sep=",")
#Remover dadps com problemas (nessa planilha, os ídices Ctr1 e LWCI estão comprometidos)
dados=subset(dados, select = -c(Ctr1, LWCI))
#Definir como fator de analise a coluna que contém a variavel resposta
dados$especie=factor(dados$especie)
#~~~~~~~~~~~~~~~~ 2 - PARTICIONAMENTO TREINO/TESTE~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Divisao aleatoria do conjunto de dados para treinamento (70%) e teste (30%)
# A sequencia de comandos abaixo realiza o sorteio dentro de cada classe,
# Ou seja, para cada espécie 21 amostras são sorteadas para treinamento e 9 para teste
# O sorteio foi pensado dessa forma para assegur que existam representantes de cada classe
# durante o treinamento dos modelos
# A funcao "particionamento" foi construida para realizar essa tarefa. O sorteio é feito
# dentro de cada nivel do fator
# Essa funcao é generica e pode ser aplicada a qualqer base de dados, considerando
# os seguintes argumentos:
# "dados": Base de dados que sera particionada
# "dados_fator" : Coluna da base de dados de armazena a variavel que constitui o fator de analise
# (nesse caso a coluna com a identificacao das especies).
# "proporcao_treino" : valor decimal indicando a proporcao destinada ao conjunto de treinamento
particionamento=function(dados, dados_fator, proporcao_treino){
fator=factor(dados_fator)
niveis_fatores=levels(fator)
f=function(niveis_fatores){
for(i in 1:length(niveis_fatores)){
a=subset(dados,dados_fator==niveis_fatores[i])
sorteio = sample(1:nrow(a), proporcao_treino*nrow(a), replace = FALSE)
treino= data.frame(); treino = a[sorteio,];teste = data.frame(); teste = a[-sorteio,]
amostras=list(treino,teste)}
return(amostras)}
treino=c()
teste=c()
for(i in 1:length(niveis_fatores)){
t=f(niveis_fatores[i])
treino=rbind(treino,t[[1]])
teste=rbind(teste,t[[2]])
amostragem=list(treino,teste)}
return(amostragem)}
particoes=particionamento(dados, dados$especie, 0.7)
# A funcao "particionamento" retorna um objeto do tipo "list", com duas listas internas.
# A primeira lista, [[1]], armazena o subconjunto de treinamento,
# enquanto a segunda, [[2]], os dados de teste.
# Dessa forma, particoes[[1]] resgata os dados de treino e particoes[[2]],
# resgata os dados de teste.
#Parcela de dados para treinamento
dados_treino=data.frame(particoes[[1]])
length(dados_treino$especie) #210
## [1] 210
summary(dados_treino$especie) #treinamento 70% (21 repeticoes)
## Acoita Amora Araca Cedro Cinanomo Inga Ipeamare Iperoxo
## 21 21 21 21 21 21 21 21
## Pitangue Platano
## 21 21
#Parcela para teste/validacao
dados_teste=data.frame(particoes[[2]])
length(dados_teste$especie) #90
## [1] 90
summary(dados_teste$especie) #teste 30% (9 repeticoes)
## Acoita Amora Araca Cedro Cinanomo Inga Ipeamare Iperoxo
## 9 9 9 9 9 9 9 9
## Pitangue Platano
## 9 9
#~~~~~~~~~~~~~~~~ 3 - TREINAR E VALIDAR OS MODELOS COM TODOS OS INDICES~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 3.1 - Random Forest - RF
library(randomForest)
## randomForest 4.7-1.1
## Type rfNews() to see new features/changes/bug fixes.
rf=randomForest(especie ~.,data=dados_treino, ntree=1000, mtry=10)
# ntree: Número de árvores aleatórias criadas durante no treinamento
# mtry: Número de variáveis sorteadas para compor cada árvore
# ref: https://www.rdocumentation.org/packages/randomForest/versions/4.7-1.1/topics/randomForest
table(predict(rf),dados_treino$especie)
##
## Acoita Amora Araca Cedro Cinanomo Inga Ipeamare Iperoxo Pitangue
## Acoita 21 0 0 0 0 0 0 0 0
## Amora 0 20 0 0 0 0 0 0 0
## Araca 0 0 20 0 0 0 0 0 0
## Cedro 0 0 0 21 0 0 0 0 0
## Cinanomo 0 0 0 0 19 0 0 0 0
## Inga 0 0 0 0 0 21 0 0 0
## Ipeamare 0 0 1 0 0 0 21 0 0
## Iperoxo 0 0 0 0 0 0 0 21 0
## Pitangue 0 0 0 0 0 0 0 0 21
## Platano 0 1 0 0 2 0 0 0 0
##
## Platano
## Acoita 0
## Amora 2
## Araca 0
## Cedro 2
## Cinanomo 2
## Inga 0
## Ipeamare 0
## Iperoxo 1
## Pitangue 0
## Platano 14
rf
##
## Call:
## randomForest(formula = especie ~ ., data = dados_treino, ntree = 1000, mtry = 10)
## Type of random forest: classification
## Number of trees: 1000
## No. of variables tried at each split: 10
##
## OOB estimate of error rate: 5.24%
## Confusion matrix:
## Acoita Amora Araca Cedro Cinanomo Inga Ipeamare Iperoxo Pitangue
## Acoita 21 0 0 0 0 0 0 0 0
## Amora 0 20 0 0 0 0 0 0 0
## Araca 0 0 20 0 0 0 1 0 0
## Cedro 0 0 0 21 0 0 0 0 0
## Cinanomo 0 0 0 0 19 0 0 0 0
## Inga 0 0 0 0 0 21 0 0 0
## Ipeamare 0 0 0 0 0 0 21 0 0
## Iperoxo 0 0 0 0 0 0 0 21 0
## Pitangue 0 0 0 0 0 0 0 0 21
## Platano 0 2 0 2 2 0 0 1 0
## Platano class.error
## Acoita 0 0.00000000
## Amora 1 0.04761905
## Araca 0 0.04761905
## Cedro 0 0.00000000
## Cinanomo 2 0.09523810
## Inga 0 0.00000000
## Ipeamare 0 0.00000000
## Iperoxo 0 0.00000000
## Pitangue 0 0.00000000
## Platano 14 0.33333333
#Avaliacao desempenho sobre os dados de teste do Random Forest
confusao_rf=table(predict(rf,dados_teste),dados_teste$especie)
confusao_rf
##
## Acoita Amora Araca Cedro Cinanomo Inga Ipeamare Iperoxo Pitangue
## Acoita 9 0 0 0 0 0 0 0 0
## Amora 0 8 0 0 0 0 0 0 0
## Araca 0 0 8 0 0 0 0 0 0
## Cedro 0 0 0 9 0 0 0 0 0
## Cinanomo 0 0 0 0 9 2 0 0 0
## Inga 0 0 0 0 0 7 0 0 0
## Ipeamare 0 0 1 0 0 0 9 0 0
## Iperoxo 0 0 0 0 0 0 0 9 0
## Pitangue 0 0 0 0 0 0 0 0 9
## Platano 0 1 0 0 0 0 0 0 0
##
## Platano
## Acoita 0
## Amora 0
## Araca 0
## Cedro 0
## Cinanomo 0
## Inga 0
## Ipeamare 0
## Iperoxo 1
## Pitangue 0
## Platano 8
acerto_rf=sum(diag(confusao_rf))/sum(confusao_rf)
acerto_rf
## [1] 0.9444444
# 3.2 - Support Vector Machine - SVM
#install.packages("e1071", dependencies=T)
library(e1071)
m_svm=svm(especie~.,dados_treino, kernel="polynomial", gamma=0.1, cost=10)
#Informações sobre os hiperparametros:
# https://www.rdocumentation.org/packages/e1071/versions/1.7-11/topics/svm
#Avaliacao desempenho sobre os dados de teste do SVM
confusao_svm=table(predict(m_svm,dados_teste),dados_teste$especie)
confusao_svm
##
## Acoita Amora Araca Cedro Cinanomo Inga Ipeamare Iperoxo Pitangue
## Acoita 9 0 0 0 0 0 0 0 0
## Amora 0 8 0 0 0 0 0 0 0
## Araca 0 0 8 0 0 0 0 0 0
## Cedro 0 0 0 9 0 0 0 0 0
## Cinanomo 0 0 0 0 9 1 0 0 0
## Inga 0 0 0 0 0 8 0 0 0
## Ipeamare 0 0 1 0 0 0 9 2 0
## Iperoxo 0 0 0 0 0 0 0 6 0
## Pitangue 0 0 0 0 0 0 0 0 9
## Platano 0 1 0 0 0 0 0 1 0
##
## Platano
## Acoita 0
## Amora 1
## Araca 0
## Cedro 0
## Cinanomo 1
## Inga 0
## Ipeamare 0
## Iperoxo 1
## Pitangue 0
## Platano 6
acerto_svm=sum(diag(confusao_svm))/sum(confusao_svm)
acerto_svm
## [1] 0.9
# 3.3 - Artificial Neural Network - ANN
#install.packages("neuralnet", dependencies=T)
library(neuralnet)
#Ao rodar a rede neural perceptron do pacote neuralnet, melhores resultados são obtidos
#com os dados normalizados
#Normalização dos dados
treino_nnet=data.frame(scale(dados_treino[,-236]),especie=dados_treino$especie)
teste_nnet=data.frame(scale(dados_teste[,-236]),especie=dados_teste$especie)
#Criacao do modelo com a rede neural perceptron do pacote neuralnet
nnet=neuralnet(especie~., treino_nnet, hidden = c(59,39,26,17,7), linear.output = F,
threshold = 0.01,
stepmax = 1e+05, rep = 1, startweights = NULL,
learningrate.limit = NULL, learningrate.factor = list(minus = 0.5, plus = 1.2))
# hidden = c(59,39,26,17,7) - Numero de neuronios em cada camada da rede. Como recomendação
# usa-se a regra dos 2/3 (A primeira camada tem 2/3 do numero de amostras.
# A segunda camada de neuronios possui 2/3 da primeira e assim sucessivamente)
# Sobre os demais hiperparametros:
# https://www.rdocumentation.org/packages/neuralnet/versions/1.44.2/topics/neuralnet
pred_treino=as.data.frame(nnet$net.result)
names(pred_treino)=levels(treino_nnet$especie)
pred_treino$class=colnames(pred_treino[,1:10])[max.col(pred_treino[,1:10], ties.method = 'first')]
confusao_treino=table(pred_treino$class,treino_nnet$especie)
confusao_treino
##
## Acoita Amora Araca Cedro Cinanomo Inga Ipeamare Iperoxo Pitangue
## Acoita 21 0 0 0 0 0 0 0 0
## Amora 0 21 0 0 0 0 0 0 0
## Araca 0 0 21 0 0 0 0 0 0
## Cedro 0 0 0 21 0 0 0 0 0
## Cinanomo 0 0 0 0 21 0 0 0 0
## Inga 0 0 0 0 0 21 0 0 0
## Ipeamare 0 0 0 0 0 0 21 0 0
## Iperoxo 0 0 0 0 0 0 0 21 0
## Pitangue 0 0 0 0 0 0 0 0 21
## Platano 0 0 0 0 0 0 0 0 0
##
## Platano
## Acoita 0
## Amora 0
## Araca 0
## Cedro 0
## Cinanomo 0
## Inga 0
## Ipeamare 0
## Iperoxo 0
## Pitangue 0
## Platano 21
#Avaliacao desempenho sobre os dados de teste da ANN
ypred = neuralnet::compute(nnet, teste_nnet)
ypred = as.data.frame(ypred$net.result)
names(ypred)=levels(teste_nnet$especie)
ypred$class = colnames(ypred[,1:10])[max.col(ypred[,1:10], ties.method = 'first')]
confusao_nnet = table(ypred$class,teste_nnet$especie)
confusao_nnet
##
## Acoita Amora Araca Cedro Cinanomo Inga Ipeamare Iperoxo Pitangue
## Acoita 9 0 0 0 0 1 0 0 0
## Amora 0 6 0 1 0 0 1 0 0
## Araca 0 0 8 0 0 1 1 0 0
## Cedro 0 0 0 8 0 0 0 0 0
## Cinanomo 0 0 0 0 9 3 0 0 0
## Inga 0 0 1 0 0 3 0 0 0
## Ipeamare 0 0 0 0 0 0 7 0 0
## Iperoxo 0 0 0 0 0 0 0 9 0
## Pitangue 0 2 0 0 0 0 0 0 9
## Platano 0 1 0 0 0 1 0 0 0
##
## Platano
## Acoita 1
## Amora 2
## Araca 0
## Cedro 1
## Cinanomo 1
## Inga 0
## Ipeamare 0
## Iperoxo 2
## Pitangue 0
## Platano 2
acerto_nnet=sum(diag(confusao_nnet))/sum(confusao_nnet)
acerto_nnet
## [1] 0.7777778
#~~~~~~~~~~~~~~~~ 4 - TREINAR E VALIDAR OS MODELOS COM OS INDICES SELECIONADOS~~~~~~~~~~~~~~~~~~~~~
#4.1 Ranking de importancia Random Forest
# Resgata os scores das variaveis preditoras junto ao modelo RF treinado
importancia=importance(rf)
ranking=data.frame(importancia)
ranking=data.frame(rownames(ranking),ranking$MeanDecreaseGini)
names(ranking)
## [1] "rownames.ranking." "ranking.MeanDecreaseGini"
ranking=ranking[order(ranking[,2],decreasing = T),]
#Plotar gráfico com o índice de GINI para avaliar o "ponto de corte" no número de preditores
plot(ranking$ranking.MeanDecreaseGini, xlab= "Número de preditores", ylab= " Mean Decrease GINI")

#Quanto maior o índice de GINI mais relevante é a variável
head(ranking,20) #Mostrar as 20 primeiras linhas do objeto ranking
## rownames.ranking. ranking.MeanDecreaseGini
## 180 SB1420 4.646938
## 50 MVI 3.822940
## 178 SB1200 3.761037
## 181 SB1450 3.430822
## 167 SR833_1649 3.164739
## 53 MCARI1510 3.067699
## 2 AFRI1600 2.925117
## 177 SB1120 2.903208
## 179 SB1400 2.828553
## 185 SB1540 2.792149
## 182 SB1490 2.732887
## 183 SB1510 2.701665
## 218 SB910 2.640938
## 91 NDMI 2.542725
## 220 SB990 2.509670
## 219 SB930 2.317181
## 122 MSI 1.963154
## 155 DSWI_1 1.954123
## 7 AR750_850 1.944875
## 228 WET 1.845721
# Grafico opcional para visualizar as variáveis mais importantes
varImpPlot(rf)

#Filtrar (Por exemplo) as 10 variaveis mais importantes
var=as.character(ranking[1:10,1])
#Aplicar a selecao de variaveis sobre o conjunto de dados treino
selecao_treino=dados_treino[,var[]]
selecao_treino =data.frame(selecao_treino,especie=dados_treino$especie)
head(selecao_treino)
## SB1420 MVI SB1200 SB1450 SR833_1649 MCARI1510 AFRI1600
## 20 0.2328185 0.6783276 0.5490159 0.2056960 1.513549 -0.05955238 -0.4350953
## 21 0.2174971 0.6596526 0.5304922 0.1963648 1.513406 -0.05213464 -0.4514931
## 4 0.2468327 0.6974400 0.5549001 0.2250736 1.462303 -0.07071857 -0.4323397
## 9 0.2436155 0.7112731 0.5194206 0.2056841 1.386189 -0.06778746 -0.4681777
## 15 0.2249213 0.6400222 0.5360963 0.2032251 1.551487 -0.05717062 -0.4385034
## 23 0.2351394 0.6781678 0.5537630 0.2129303 1.473557 -0.05868277 -0.4430847
## SB1120 SB1400 SB1540 especie
## 20 0.5873234 0.3202901 0.3086413 Acoita
## 21 0.5583793 0.3100394 0.2823689 Acoita
## 4 0.5827512 0.3337514 0.3191585 Acoita
## 9 0.5452921 0.3293867 0.3000632 Acoita
## 15 0.5761419 0.3133014 0.2803870 Acoita
## 23 0.5682686 0.3198699 0.3049400 Acoita
#Aplicar a selecao de variaveis sobre o conjunto de dados teste
selecao_teste=dados_teste[,var[]]
selecao_teste =data.frame(selecao_teste,especie=dados_teste$especie)
head(selecao_teste)
## SB1420 MVI SB1200 SB1450 SR833_1649 MCARI1510 AFRI1600
## 5 0.2404670 0.6935337 0.5433676 0.2251143 1.480904 -0.07146529 -0.4317878
## 8 0.2456984 0.6936780 0.5127410 0.2100551 1.491303 -0.06028026 -0.4635366
## 11 0.2436912 0.6775980 0.5499068 0.2108449 1.466020 -0.06068689 -0.4347588
## 16 0.2397257 0.6680299 0.5455996 0.2102325 1.481646 -0.05760962 -0.4401471
## 19 0.2297520 0.6554117 0.5365095 0.2047166 1.587894 -0.05025108 -0.4364687
## 22 0.2231307 0.6556364 0.5431486 0.2041344 1.544419 -0.05252724 -0.4392763
## SB1120 SB1400 SB1540 especie
## 5 0.5848209 0.3395051 0.3248342 Acoita
## 8 0.5439228 0.3275356 0.3054879 Acoita
## 11 0.5732949 0.3280475 0.3050638 Acoita
## 16 0.5678229 0.3284755 0.2925872 Acoita
## 19 0.5806264 0.3113537 0.2918864 Acoita
## 22 0.5878295 0.3204495 0.2809013 Acoita
##############################################################################
#4.2 Rodar novamente os modelos, agora com o banco de dados reduzido
# Construir novamente os modelos, aplicando agora os subconjuntos selecao_treino e selecao_teste