O objetivo principal deste relatório é de propor um modelo de rede neural, tal que consiga classificar de forma mais eficaz a variável qualitativa em estudo. A ideia por trás dos algoritmos apresentados é de manipular a base de dados tal que consiga melhorar a capacidade de entendimento da rede neural para os dados, como por exemplo, utilizando bootstrap, ou até mesmo criando novas variáveis. Outro ponto a ser discutido, é na escolha no número de camadas de cada rede neural, afim de estudar na relação do aumento de número de camadas com o aumento da acurácia.
Esse famoso conjunto de dados de íris, é fornecido pelo software R, representando as medidas em centímetros das variáveis comprimento e largura da sépala e comprimento e largura da pétala, respectivamente, para 50 flores de cada uma das 3 espécies de íris. As espécies são Iris setosa, versicolor e virginica.
Setando uma semente e criando as bases de teste e treinamento do banco, essa vai ser a primeira base inical do banco de dados. Como dito na sessão anterior, vai ser feito testes baseados nessas manipulações. Porém, por enquanto essa vai ser a principal.
library(keras)
library(tidyverse)
## ── Attaching packages ───────────────────────────────────────────────────────── tidyverse 1.2.1 ──
## ✔ ggplot2 3.2.1 ✔ purrr 0.3.2
## ✔ tibble 2.1.3 ✔ dplyr 0.8.3
## ✔ tidyr 0.8.3 ✔ stringr 1.4.0
## ✔ readr 1.3.1 ✔ forcats 0.4.0
## ── Conflicts ──────────────────────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
library(ggplot2)
library(e1071)
#Base de dados inicial
set.seed(123)
base <- iris %>%
mutate(Set = sample(x = c("train", "test"),
size = n(),
replace = TRUE,
prob = c(.8,.2))) %>%
sample_frac(1, replace = FALSE)
Train_Features <- base %>%
filter(Set == "train") %>%
select(-Species, -Set) %>%
mutate_all(function(x) (x-min(x))/(max(x) - min(x))) %>%
as.matrix()
Train_Labels <- base %>%
filter(Set == "train") %>%
select(Species) %>%
mutate(Species = as.numeric(Species) - 1) %>%
as.matrix() %>%
to_categorical()
Test_Features <- base %>%
filter(Set == "test") %>%
select(-Species, -Set) %>%
mutate_all(function(x) (x-min(x))/(max(x) - min(x))) %>%
as.matrix()
Test_Labels <- base %>%
filter(Set == "test") %>%
select(Species) %>%
mutate(Species = as.numeric(Species) - 1) %>%
as.matrix() %>%
to_categorical()
Nesta sessão, será mostrada uma alternativa de modelo de redes neural, utilizando a base de dados geradas na sessão anterior. Uma das abordagens dessa sessão é de ficar manipulando alguns parâmetros do modelo, tal que, ache uma melhor combinação, em termos de funcionalidade, em outras palavras, que seja menos custoso para o processo.
Apresentando uma rede neural com 3 camadas, com a camada incial apresentando 20 neurônios utilizando a função relu, a segunda camada com 10 neurônios também utilizando a relu, e por último a terceira camada com 3 neurônios restantes com a função de ativação softmax, presente no final do processamento do modelo. É visto no gráfico que, aparentemente o gráifco não apresentou overfitting
model <- keras_model_sequential()
model %>%
layer_dense(units= 20, activation = "relu", input_shape = ncol(Train_Features)) %>%
layer_dense(units= 10, activation = "relu") %>%
layer_dense(units = 3, activation = "softmax")
summary(model)
## Model: "sequential"
## ___________________________________________________________________________
## Layer (type) Output Shape Param #
## ===========================================================================
## dense (Dense) (None, 20) 100
## ___________________________________________________________________________
## dense_1 (Dense) (None, 10) 210
## ___________________________________________________________________________
## dense_2 (Dense) (None, 3) 33
## ===========================================================================
## Total params: 343
## Trainable params: 343
## Non-trainable params: 0
## ___________________________________________________________________________
model %>% compile(loss = "categorical_crossentropy",
optimizer = optimizer_adagrad(),
metrics = c('accuracy')
)
Foi utilizando no código abaixo, uma condição de parada no algoritmo, tal que, após as realizações dos resultados, se com isso for atingido o esperado, o programa vaiparar. Podemos observar pelo gráfico abaixo que não conseguimos alcançar o resultado esperado, por isso, certas mudanças podem ser feitas tal que consiga melhorar a acurácia do modelo.
history <- model %>% fit(Train_Features, Train_Labels,
validation_split = 0.20,
verbose = 1,
epochs=300, batch_size = 5,
shuffle = TRUE,
callbacks = list(
callback_early_stopping(monitor = "val_acc", min_delta = 0.01,
patience = 100,
verbose=0,
mode = "auto",
restore_best_weights = TRUE)
))
plot(history)
model %>% evaluate(Test_Features,Test_Labels)
## $loss
## [1] 0.3734305
##
## $acc
## [1] 0.862069
Trocando agora o número e neurônios iniciais e com a mesmsa função de ligação.
model <- keras_model_sequential()
model %>%
layer_dense(units= 32, activation = "relu", input_shape = ncol(Train_Features)) %>%
layer_dense(units= 25, activation = "relu") %>%
layer_dense(units = 3, activation = "softmax")
summary(model)
## Model: "sequential_1"
## ___________________________________________________________________________
## Layer (type) Output Shape Param #
## ===========================================================================
## dense_3 (Dense) (None, 32) 160
## ___________________________________________________________________________
## dense_4 (Dense) (None, 25) 825
## ___________________________________________________________________________
## dense_5 (Dense) (None, 3) 78
## ===========================================================================
## Total params: 1,063
## Trainable params: 1,063
## Non-trainable params: 0
## ___________________________________________________________________________
model %>% compile(loss = "categorical_crossentropy",
optimizer = optimizer_adagrad(),
metrics = c('accuracy')
)
Como podemos observar pelo gráfico, que apenas mudar no número de neurônios por camada não muda muito a situação do problema, mesmo com o modelo conseguir aprender bem o algoritmo, sem a presença de overfitting (aparentemente), não necessariamente apresentou bons resultados em termos de acurácia.
history <- model %>% fit(Train_Features, Train_Labels,
validation_split = 0.20,
verbose = 1,
epochs=300, batch_size = 5,
shuffle = TRUE,
callbacks = list(
callback_early_stopping(monitor = "val_acc", min_delta = 0.01,
patience = 100,
verbose=0,
mode = "auto",
restore_best_weights = TRUE)
))
plot(history)
model %>% evaluate(Test_Features,Test_Labels)
## $loss
## [1] 0.4323574
##
## $acc
## [1] 0.9655172
Nesta seção será utilizada uma técnica comumente utilziada na aplicação de redes neurais, com o objetivo de aumentar a base de dados trabalhada atráves de realizações de bootstrap, visando por final aumentar a acurácia do modelo.
A ideia principal é de replicar 2 vezes (no caso do códigos abaixo) a amostra de treinamento, denominado de “new_data1”, como a base de treinamento é composta de 121 observações, então “new_data1” apresenta 242 observações. Posteriormente, vai ser criada novas bases de treinamento, denominadas de “Train_Features_Augmented” e “Train_Labels_Augmented”, que no mesmo caso anterior, corresponde a parte númerica do treinamento e a parte representativa das espécies, respectivamente. Essas novas bases, é nada mais nada menos que as bases anteriores só que com o adicional de “new_data1”. A ideia por trás dessas operações é de gerar novas informações e de uma forma que com isso “alimentar” a rede neural com mais dessas informações.
#Bootstrap
new_data_1 <- base %>% filter(Set == "train") %>%
sample_frac(2, replace = TRUE) %>%
mutate_if(is.numeric, function(x) x + rnorm(length(x), mean = 0, sd = sd(x)))
new_data <- new_data_1
Train_Features_Augmented <- base %>%
filter(Set == "train") %>%
bind_rows(new_data) %>%
select(-Species, -Set) %>%
mutate_all(function(x) (x-min(x))/(max(x) - min(x))) %>%
as.matrix()
Train_Labels_Augmented <- base %>%
filter(Set == "train") %>%
bind_rows(new_data) %>%
select(Species) %>%
mutate(Species = as.numeric(Species) - 1) %>%
as.matrix() %>%
to_categorical()
Após isso, podemos formar um novo modelo, utilizando as mesmas linhas de código abaixo. pode ser feito uma aplicação na mudança no número de neurônios, afim de encontrar certa influência na acurácia. Neste primeiro caso, foi começado no algorítmo, a primeira camada com 50 neurônios, utilizando a função de ativação “relu”. A segunda camada, com 25 neurônios, também usando a função “relu” e por último usando 3 neurônios na terceira camada, com a função softmax.
model <- keras_model_sequential()
model %>%
layer_dense(units= 50, activation = "relu", input_shape = ncol(Train_Features_Augmented)) %>%
layer_dense(units= 25, activation = "relu") %>%
layer_dense(units = 3, activation = "softmax")
summary(model)
## Model: "sequential_2"
## ___________________________________________________________________________
## Layer (type) Output Shape Param #
## ===========================================================================
## dense_6 (Dense) (None, 50) 250
## ___________________________________________________________________________
## dense_7 (Dense) (None, 25) 1275
## ___________________________________________________________________________
## dense_8 (Dense) (None, 3) 78
## ===========================================================================
## Total params: 1,603
## Trainable params: 1,603
## Non-trainable params: 0
## ___________________________________________________________________________
model %>% compile(loss = "categorical_crossentropy",
optimizer = optimizer_adagrad(),
metrics = c('accuracy')
)
history <- model %>% fit(Train_Features_Augmented, Train_Labels_Augmented,
validation_split = 0.20,
verbose = 1,
epochs=300, batch_size = 5,
shuffle = TRUE,
callbacks = list(
callback_early_stopping(monitor = "val_acc", min_delta = 0.01,
patience = 100,
verbose=0,
mode = "auto",
restore_best_weights = TRUE)
))
plot(history)
model %>% evaluate(Test_Features,Test_Labels)
## $loss
## [1] 0.1918266
##
## $acc
## [1] 0.862069
Utilizando os mesmos códigos vistos anteriormente, apenas alterando o número de neurônios e adicionando mais uma camada na rede neural, temos que:
model <- keras_model_sequential()
model %>%
layer_dense(units= 30, activation = "relu", input_shape = ncol(Train_Features_Augmented)) %>%
layer_dense(units= 20, activation = "relu") %>%
layer_dense(units= 10, activation = "relu") %>%
layer_dense(units = 3, activation = "softmax")
summary(model)
## Model: "sequential_3"
## ___________________________________________________________________________
## Layer (type) Output Shape Param #
## ===========================================================================
## dense_9 (Dense) (None, 30) 150
## ___________________________________________________________________________
## dense_10 (Dense) (None, 20) 620
## ___________________________________________________________________________
## dense_11 (Dense) (None, 10) 210
## ___________________________________________________________________________
## dense_12 (Dense) (None, 3) 33
## ===========================================================================
## Total params: 1,013
## Trainable params: 1,013
## Non-trainable params: 0
## ___________________________________________________________________________
model %>% compile(loss = "categorical_crossentropy",
optimizer = optimizer_adagrad(),
metrics = c('accuracy')
)
history <- model %>% fit(Train_Features_Augmented, Train_Labels_Augmented,
validation_split = 0.20,
verbose = 1,
epochs=300, batch_size = 5,
shuffle = TRUE,
callbacks = list(
callback_early_stopping(monitor = "val_acc", min_delta = 0.01,
patience = 100,
verbose=0,
mode = "auto",
restore_best_weights = TRUE)
))
plot(history)
model %>% evaluate(Test_Features,Test_Labels)
## $loss
## [1] 0.3896622
##
## $acc
## [1] 0.862069
Nesta sessão, apresenta uma abordagem de forma bem mais prática do que a da sessão anterior, sendo de fácil implementação. Ao contrário da outra que fez aumentar a base de dados atráves de realizações de bootstrap, esta vertente, teve uma ação bem mais intuitiva, que atráves de um conhecimento a priori dos dados trabalhados, fez apenas criar novas variáveis e adicionar nas bases de treinamento e teste. Estas novas variáveis são dadas pelos códigos abaixo:
#Mudança de base criando novas variáveis
base_ext <- base %>% mutate(Sepal.Product = Sepal.Length*Sepal.Width,
Sepal.Ratio = Sepal.Length/Sepal.Width,
Petal.Product = Petal.Length*Petal.Width,
Petal.Ratio = Petal.Length/Petal.Width)
A vantagem dessa técnica é que não precisou aumentar o número de observações de uma base anteriormente pequena de dados, ou seja, ficando menos custoso computacionalmente. Agora, aplicando os mesmos códigos para a geração dos resultados, criando novas bases de treinamento e teste, utilizando o memso raciocínio discutido no início, temos os códigos dados por:
Train_Features <- base_ext %>%
filter(Set == "train") %>%
select(-Species, -Set) %>%
mutate_all(function(x) (x-min(x))/(max(x) - min(x))) %>%
as.matrix()
Train_Labels <- base_ext %>%
filter(Set == "train") %>%
select(Species) %>%
mutate(Species = as.numeric(Species) - 1) %>%
as.matrix() %>%
to_categorical()
Test_Features <- base_ext %>%
filter(Set == "test") %>%
select(-Species, -Set) %>%
mutate_all(function(x) (x-min(x))/(max(x) - min(x))) %>%
as.matrix()
Test_Labels <- base_ext %>%
filter(Set == "test") %>%
select(Species) %>%
mutate(Species = as.numeric(Species) - 1) %>%
as.matrix() %>%
to_categorical()
Apesar desse ganho computacional, ainda podemos testar duas propostas de modelos utilizando essa nova base_ext, sendo esses modelos com números de neurônios distintos. Outra abordagem que pode ser feito é no aumento de número de camadas.
Aprensentando algumas mudanças em relações ao modelos já propostos, esta rede neural é feita de 4 camadas, sendo a primeira com 50 neurônios, na segunda camada foi diminuido o número de neurônios pela metade, já na terceira e quarta camada, foi gerado com 12 e 3 neurônios, respectivamente. A respeito das funções de ativação de cada camada, foi utlizada a função relu nas três primeiras camadas, só na camada final que foi utilizada a função softmax. Este padrão de funções de ativação é bem padrão e sendo frequentemente na prática.
#Modelo com 4 camadas
model <- keras_model_sequential()
model %>%
layer_dense(units= 50, activation = "relu", input_shape = ncol(Train_Features)) %>%
layer_dense(units= 25, activation = "relu") %>%
layer_dense(units= 12, activation = "relu") %>%
layer_dense(units = 3, activation = "softmax")
summary(model)
## Model: "sequential_4"
## ___________________________________________________________________________
## Layer (type) Output Shape Param #
## ===========================================================================
## dense_13 (Dense) (None, 50) 450
## ___________________________________________________________________________
## dense_14 (Dense) (None, 25) 1275
## ___________________________________________________________________________
## dense_15 (Dense) (None, 12) 312
## ___________________________________________________________________________
## dense_16 (Dense) (None, 3) 39
## ===========================================================================
## Total params: 2,076
## Trainable params: 2,076
## Non-trainable params: 0
## ___________________________________________________________________________
model %>% compile(loss = "categorical_crossentropy",
optimizer = optimizer_adagrad(),
metrics = c('accuracy')
)
De fato, houve uma melhora significante em relação à acurácia dos modelos anteriores.
history <- model %>% fit(Train_Features, Train_Labels,
validation_split = 0.20,
verbose = 1,
epochs=300, batch_size = 5,
shuffle = TRUE,
callbacks = list(
callback_early_stopping(monitor = "val_acc", min_delta = 0.01,
patience = 100,
verbose = 0,
mode = "auto",
restore_best_weights = TRUE)
))
plot(history)
model %>% evaluate(Test_Features,Test_Labels)
## $loss
## [1] 0.2445095
##
## $acc
## [1] 1
Outra opção de fazermos é de esquecer no número de camadas que modelo pode ter, e sim na quantidade de neurônios que precisa tal que a rede neural ainda apresente uma boa capacidade de classificação.
#Modelo com 3 camadas
model <- keras_model_sequential()
model %>%
layer_dense(units= 20, activation = "relu", input_shape = ncol(Train_Features)) %>%
layer_dense(units= 10, activation = "relu") %>%
layer_dense(units = 3, activation = "softmax")
summary(model)
## Model: "sequential_5"
## ___________________________________________________________________________
## Layer (type) Output Shape Param #
## ===========================================================================
## dense_17 (Dense) (None, 20) 180
## ___________________________________________________________________________
## dense_18 (Dense) (None, 10) 210
## ___________________________________________________________________________
## dense_19 (Dense) (None, 3) 33
## ===========================================================================
## Total params: 423
## Trainable params: 423
## Non-trainable params: 0
## ___________________________________________________________________________
model %>% compile(loss = "categorical_crossentropy",
optimizer = optimizer_adagrad(),
metrics = c('accuracy')
)
history <- model %>% fit(Train_Features, Train_Labels,
validation_split = 0.20,
verbose = 1,
epochs=300, batch_size = 5,
shuffle = TRUE,
callbacks = list(
callback_early_stopping(monitor = "val_acc", min_delta = 0.01,
patience = 100,
verbose = 0,
mode = "auto",
restore_best_weights = TRUE)
))
plot(history)
model %>% evaluate(Test_Features,Test_Labels)
## $loss
## [1] 0.08933428
##
## $acc
## [1] 1
Neste tópico, será discutido uma técnica de classificação de machine learning, denominada de SVM (Support Vector Machines). Esse método tem abordagem para classificação, que foi desenvolvida na literatura por volta da década de 1990 pela comunidade de ciência da computação e que cresceu em popularidade desde então. Uma de suas vantagens é que ele pode tanto realizar classificações lineares quanto classificações não lineares. O SVM é uma generalização de um classificador simples e intuitivo chamado classificador de margem máxima (“maximal margin classifier”). Esse classificador de margem máxima, de uma forma mais simples, sem variáveis de forma quadrática, é dado por esse problema de otimização:
\[\begin{equation} \overset{\textit{Maximize} \quad M}{\beta_{0}, \beta_{1},\cdots, \beta_{p}, \epsilon_{1},\cdots,\epsilon_{n}} \end{equation}\] \[\begin{equation} \mathrm{\textit{Sujeito a}}\quad \sum_{j=1}^{p} \beta_{j}^{2} = 1, \end{equation}\] \[\begin{equation} y_{i}(\beta_{0} + \sum_{j=1}^{p}\beta_{j1}x_{ij} \ge M(1-\epsilon_i), \end{equation}\] \[\begin{equation} \epsilon_{i} \ge 0, \quad \sum_{i=1}^{n} \le C, \end{equation}\]
As variáveis \(\epsilon_1, ... ,\epsilon_n\), fazem essa questão de “relaxamento” que foi imposta na terceira equação.
Como mencionado antes, o SVM é uma generalização do classificador de margem máxima, que por fim, é uma generalizaçao do SVC. O objetivo do SVM é de ampliar ainda mais o limite não linear entre as classes, como por exemplo, utilizando Kernel. Com isso, podemos dizer pela seção anterior que as equações anteriores, representando a solução para o problema do SVC, são apenas os produtos internos das observações (em oposição às próprias observações). O produto interno entre 2 r-vetores \(a\) e \(b\) é definido como \(\langle a,b \rangle = \sum_{i=1}^{r}a_{i}b_{i}\). Portanto, o produto interno de duas observações \(x_{i}\), \(x_{i'}\) é dado por: \[\begin{equation} \langle x_{i},x_{i'} \rangle =\sum_{j=1}^{P}x_{ij}x_{i'j}, \qquad (1) \end{equation}\] • A representação linear do SVC poder ser representada por: \[\begin{equation} f(x) = \beta_0 + \sum_{i=1}^{n}\alpha_{i}\langle x_{i},x_{i} \rangle, \qquad (2) \end{equation}\]
• Para estimar os parâmetros \(\alpha_1, ..., \alpha_n\) e \(\beta_0\), tudo o que precisamos é a \({n \choose 2}\) de produtos internos \(\langle x_{i},x_{i'} \rangle\) entre todos os pares de observações de treinamento.
Observe que em (2), para avaliar a função \(f(x)\), precisamos calcular o produto interno entre o novo ponto \(x\) e cada um dos pontos de treinamento \(x_i\). No entanto, verifica-se que \(\alpha_i\) é diferente de zero apenas para os vetores de suporte na solução - isto é, se uma observação de treinamento não for um vetor de suporte, então seu \(\alpha_i\) é igual a zero. Então, se \(\mathcal{S}\) é a coleção de índices desses pontos de suporte, podemos reescrever qualquer função de solução do formulário (2) como: \[\begin{equation} f(x) = \beta_0 + \sum_{i \in \mathcal{S}}\alpha_{i}\langle x_{i},x_{i} \rangle, \qquad (3) \end{equation}\]
Agora, suponha que toda vez que o produto interno em (1) aparecer na representação linear dada por (2), podemos substituirmos por uma generalização do produto interno dada por: \[\begin{equation} K(x_i,x_{i'}) \qquad (4) \end{equation}\] onde \(K\) é alguma função que é referida como um kernel, em outras palavras, uma função que quantifica a similaridade de duas observações. Como por exemplo: \ \[\begin{equation} K(x_i,x_{i'}) = \sum_{j=1}^{p}x_{ij}x_{i'j} \qquad (5) \end{equation}\] que representa novamente a ideia do SVC, é conhecida como um kernel linear porque o SVC é linear nas características. Essa ideia pode ser repetida novamente, reescrevendo a equação (4), pegando a parte \(\sum_{j=1}^{p}x_{ij}x_{i'j}\) e substituindo tal que: \[\begin{equation} K(x_i,x_{i'}) = (1+\sum_{j=1}^{p}x_{ij}x_{i'j} )^{d} \qquad (6) \end{equation}\] isso é conhecido como kernel polinomial de grau \(d\), sendo \(d\) um inteiro positivo. Esse resultado pode nos levar a um limite de decisão muito mais flexível, em relação ao linear simples.
O núcleo polinomial mostrado em (5) é um exemplo de um possível kernel não-linear. Outra escolha popular é o kernel radial, que assume a forma: \[\begin{equation} K(x_i,x_{i'}) = \mathrm{exp}\left(-\gamma \sum_{j=1}^{p}(x_{ij} - x_{i'j})^{2}\right) . \qquad (7) \end{equation}\]
A base utilizada pra esse modelo é a mesma base inicial nas sessões anteriores, sem nenhuma modificação. Antes de aplicarmos o modelo, podemos observar a posição de cada tipo de espécie em relação a algumas variáves.
attach(iris)
qplot(Petal.Length, Petal.Width, data=iris, color=Species)
Definindo agora o modelo SVM, usando a função tune, no qual vai testar n modelos, com varias combinações de parâmetros informados pela função, pra diferentes tipos de kernel. Os dados de treinamento e teste. Apesar de terem ja sido definidos anteriormente, algumas altereações foram feitas na parte estrutural do data.frame, tal que conseguisse satisfazer as condições impostas pela função SVM.
labels_train<- base %>% filter(Set == "train") %>%
select(Species, -Set)
Train_iris <- Train_Features %>% as.data.frame() %>% bind_cols(labels_train)
labels_test<- base %>% filter(Set == "test") %>%
select(Species, -Set)
Test_iris <- Test_Features %>% as.data.frame() %>% bind_cols(labels_test)
best_model<- tune(svm, Species~., data = Train_iris,
ranges = list(cost=0.1^(1:9),gamma=c(0.1,0.4,0.8,1,2,3), kernel=c("linear", "sigmoid", "radial")) )
Utilizando a função summary, podemos realmente ver essas operações funcionando, no qual foram testados no total 162 tipos de modelo, com diferentes parâmetros.
summary(best_model)
##
## Parameter tuning of 'svm':
##
## - sampling method: 10-fold cross validation
##
## - best parameters:
## cost gamma kernel
## 0.1 0.1 linear
##
## - best performance: 0.03333333
##
## - Detailed performance results:
## cost gamma kernel error dispersion
## 1 1e-01 0.1 linear 0.03333333 0.05826716
## 2 1e-02 0.1 linear 0.12435897 0.09036213
## 3 1e-03 0.1 linear 0.67564103 0.15553442
## 4 1e-04 0.1 linear 0.69230769 0.17240293
## 5 1e-05 0.1 linear 0.69230769 0.17240293
## 6 1e-06 0.1 linear 0.69230769 0.17240293
## 7 1e-07 0.1 linear 0.69230769 0.17240293
## 8 1e-08 0.1 linear 0.69230769 0.17240293
## 9 1e-09 0.1 linear 0.69230769 0.17240293
## 10 1e-01 0.4 linear 0.03333333 0.05826716
## 11 1e-02 0.4 linear 0.12435897 0.09036213
## 12 1e-03 0.4 linear 0.67564103 0.15553442
## 13 1e-04 0.4 linear 0.69230769 0.17240293
## 14 1e-05 0.4 linear 0.69230769 0.17240293
## 15 1e-06 0.4 linear 0.69230769 0.17240293
## 16 1e-07 0.4 linear 0.69230769 0.17240293
## 17 1e-08 0.4 linear 0.69230769 0.17240293
## 18 1e-09 0.4 linear 0.69230769 0.17240293
## 19 1e-01 0.8 linear 0.03333333 0.05826716
## 20 1e-02 0.8 linear 0.12435897 0.09036213
## 21 1e-03 0.8 linear 0.67564103 0.15553442
## 22 1e-04 0.8 linear 0.69230769 0.17240293
## 23 1e-05 0.8 linear 0.69230769 0.17240293
## 24 1e-06 0.8 linear 0.69230769 0.17240293
## 25 1e-07 0.8 linear 0.69230769 0.17240293
## 26 1e-08 0.8 linear 0.69230769 0.17240293
## 27 1e-09 0.8 linear 0.69230769 0.17240293
## 28 1e-01 1.0 linear 0.03333333 0.05826716
## 29 1e-02 1.0 linear 0.12435897 0.09036213
## 30 1e-03 1.0 linear 0.67564103 0.15553442
## 31 1e-04 1.0 linear 0.69230769 0.17240293
## 32 1e-05 1.0 linear 0.69230769 0.17240293
## 33 1e-06 1.0 linear 0.69230769 0.17240293
## 34 1e-07 1.0 linear 0.69230769 0.17240293
## 35 1e-08 1.0 linear 0.69230769 0.17240293
## 36 1e-09 1.0 linear 0.69230769 0.17240293
## 37 1e-01 2.0 linear 0.03333333 0.05826716
## 38 1e-02 2.0 linear 0.12435897 0.09036213
## 39 1e-03 2.0 linear 0.67564103 0.15553442
## 40 1e-04 2.0 linear 0.69230769 0.17240293
## 41 1e-05 2.0 linear 0.69230769 0.17240293
## 42 1e-06 2.0 linear 0.69230769 0.17240293
## 43 1e-07 2.0 linear 0.69230769 0.17240293
## 44 1e-08 2.0 linear 0.69230769 0.17240293
## 45 1e-09 2.0 linear 0.69230769 0.17240293
## 46 1e-01 3.0 linear 0.03333333 0.05826716
## 47 1e-02 3.0 linear 0.12435897 0.09036213
## 48 1e-03 3.0 linear 0.67564103 0.15553442
## 49 1e-04 3.0 linear 0.69230769 0.17240293
## 50 1e-05 3.0 linear 0.69230769 0.17240293
## 51 1e-06 3.0 linear 0.69230769 0.17240293
## 52 1e-07 3.0 linear 0.69230769 0.17240293
## 53 1e-08 3.0 linear 0.69230769 0.17240293
## 54 1e-09 3.0 linear 0.69230769 0.17240293
## 55 1e-01 0.1 sigmoid 0.13333333 0.09781565
## 56 1e-02 0.1 sigmoid 0.67564103 0.15553442
## 57 1e-03 0.1 sigmoid 0.69230769 0.17240293
## 58 1e-04 0.1 sigmoid 0.69230769 0.17240293
## 59 1e-05 0.1 sigmoid 0.69230769 0.17240293
## 60 1e-06 0.1 sigmoid 0.69230769 0.17240293
## 61 1e-07 0.1 sigmoid 0.69230769 0.17240293
## 62 1e-08 0.1 sigmoid 0.69230769 0.17240293
## 63 1e-09 0.1 sigmoid 0.69230769 0.17240293
## 64 1e-01 0.4 sigmoid 0.17500000 0.13861083
## 65 1e-02 0.4 sigmoid 0.62564103 0.18224379
## 66 1e-03 0.4 sigmoid 0.69230769 0.17240293
## 67 1e-04 0.4 sigmoid 0.69230769 0.17240293
## 68 1e-05 0.4 sigmoid 0.69230769 0.17240293
## 69 1e-06 0.4 sigmoid 0.69230769 0.17240293
## 70 1e-07 0.4 sigmoid 0.69230769 0.17240293
## 71 1e-08 0.4 sigmoid 0.69230769 0.17240293
## 72 1e-09 0.4 sigmoid 0.69230769 0.17240293
## 73 1e-01 0.8 sigmoid 0.25769231 0.15522883
## 74 1e-02 0.8 sigmoid 0.58397436 0.19763398
## 75 1e-03 0.8 sigmoid 0.69230769 0.17240293
## 76 1e-04 0.8 sigmoid 0.69230769 0.17240293
## 77 1e-05 0.8 sigmoid 0.69230769 0.17240293
## 78 1e-06 0.8 sigmoid 0.69230769 0.17240293
## 79 1e-07 0.8 sigmoid 0.69230769 0.17240293
## 80 1e-08 0.8 sigmoid 0.69230769 0.17240293
## 81 1e-09 0.8 sigmoid 0.69230769 0.17240293
## 82 1e-01 1.0 sigmoid 0.29935897 0.16852054
## 83 1e-02 1.0 sigmoid 0.55128205 0.19928006
## 84 1e-03 1.0 sigmoid 0.69230769 0.17240293
## 85 1e-04 1.0 sigmoid 0.69230769 0.17240293
## 86 1e-05 1.0 sigmoid 0.69230769 0.17240293
## 87 1e-06 1.0 sigmoid 0.69230769 0.17240293
## 88 1e-07 1.0 sigmoid 0.69230769 0.17240293
## 89 1e-08 1.0 sigmoid 0.69230769 0.17240293
## 90 1e-09 1.0 sigmoid 0.69230769 0.17240293
## 91 1e-01 2.0 sigmoid 0.31538462 0.15258864
## 92 1e-02 2.0 sigmoid 0.50256410 0.18281909
## 93 1e-03 2.0 sigmoid 0.69230769 0.17240293
## 94 1e-04 2.0 sigmoid 0.69230769 0.17240293
## 95 1e-05 2.0 sigmoid 0.69230769 0.17240293
## 96 1e-06 2.0 sigmoid 0.69230769 0.17240293
## 97 1e-07 2.0 sigmoid 0.69230769 0.17240293
## 98 1e-08 2.0 sigmoid 0.69230769 0.17240293
## 99 1e-09 2.0 sigmoid 0.69230769 0.17240293
## 100 1e-01 3.0 sigmoid 0.34038462 0.15104435
## 101 1e-02 3.0 sigmoid 0.49423077 0.17185785
## 102 1e-03 3.0 sigmoid 0.69230769 0.17240293
## 103 1e-04 3.0 sigmoid 0.69230769 0.17240293
## 104 1e-05 3.0 sigmoid 0.69230769 0.17240293
## 105 1e-06 3.0 sigmoid 0.69230769 0.17240293
## 106 1e-07 3.0 sigmoid 0.69230769 0.17240293
## 107 1e-08 3.0 sigmoid 0.69230769 0.17240293
## 108 1e-09 3.0 sigmoid 0.69230769 0.17240293
## 109 1e-01 0.1 radial 0.14102564 0.08877170
## 110 1e-02 0.1 radial 0.69230769 0.17240293
## 111 1e-03 0.1 radial 0.69230769 0.17240293
## 112 1e-04 0.1 radial 0.69230769 0.17240293
## 113 1e-05 0.1 radial 0.69230769 0.17240293
## 114 1e-06 0.1 radial 0.69230769 0.17240293
## 115 1e-07 0.1 radial 0.69230769 0.17240293
## 116 1e-08 0.1 radial 0.69230769 0.17240293
## 117 1e-09 0.1 radial 0.69230769 0.17240293
## 118 1e-01 0.4 radial 0.10769231 0.11163584
## 119 1e-02 0.4 radial 0.69230769 0.17240293
## 120 1e-03 0.4 radial 0.69230769 0.17240293
## 121 1e-04 0.4 radial 0.69230769 0.17240293
## 122 1e-05 0.4 radial 0.69230769 0.17240293
## 123 1e-06 0.4 radial 0.69230769 0.17240293
## 124 1e-07 0.4 radial 0.69230769 0.17240293
## 125 1e-08 0.4 radial 0.69230769 0.17240293
## 126 1e-09 0.4 radial 0.69230769 0.17240293
## 127 1e-01 0.8 radial 0.18846154 0.17158532
## 128 1e-02 0.8 radial 0.69230769 0.17240293
## 129 1e-03 0.8 radial 0.69230769 0.17240293
## 130 1e-04 0.8 radial 0.69230769 0.17240293
## 131 1e-05 0.8 radial 0.69230769 0.17240293
## 132 1e-06 0.8 radial 0.69230769 0.17240293
## 133 1e-07 0.8 radial 0.69230769 0.17240293
## 134 1e-08 0.8 radial 0.69230769 0.17240293
## 135 1e-09 0.8 radial 0.69230769 0.17240293
## 136 1e-01 1.0 radial 0.32115385 0.16931519
## 137 1e-02 1.0 radial 0.69230769 0.17240293
## 138 1e-03 1.0 radial 0.69230769 0.17240293
## 139 1e-04 1.0 radial 0.69230769 0.17240293
## 140 1e-05 1.0 radial 0.69230769 0.17240293
## 141 1e-06 1.0 radial 0.69230769 0.17240293
## 142 1e-07 1.0 radial 0.69230769 0.17240293
## 143 1e-08 1.0 radial 0.69230769 0.17240293
## 144 1e-09 1.0 radial 0.69230769 0.17240293
## 145 1e-01 2.0 radial 0.69230769 0.15840815
## 146 1e-02 2.0 radial 0.70064103 0.15417374
## 147 1e-03 2.0 radial 0.70064103 0.15417374
## 148 1e-04 2.0 radial 0.70064103 0.15417374
## 149 1e-05 2.0 radial 0.70064103 0.15417374
## 150 1e-06 2.0 radial 0.70064103 0.15417374
## 151 1e-07 2.0 radial 0.70064103 0.15417374
## 152 1e-08 2.0 radial 0.70064103 0.15417374
## 153 1e-09 2.0 radial 0.70064103 0.15417374
## 154 1e-01 3.0 radial 0.70064103 0.15417374
## 155 1e-02 3.0 radial 0.70064103 0.15417374
## 156 1e-03 3.0 radial 0.70064103 0.15417374
## 157 1e-04 3.0 radial 0.70064103 0.15417374
## 158 1e-05 3.0 radial 0.70064103 0.15417374
## 159 1e-06 3.0 radial 0.70064103 0.15417374
## 160 1e-07 3.0 radial 0.70064103 0.15417374
## 161 1e-08 3.0 radial 0.70064103 0.15417374
## 162 1e-09 3.0 radial 0.70064103 0.15417374
Com isso, o melhor modelo proposto para a classificação das espécies de plantas é:
best_model$best.model
##
## Call:
## best.tune(method = svm, train.x = Species ~ ., data = Train_iris,
## ranges = list(cost = 0.1^(1:9), gamma = c(0.1, 0.4, 0.8,
## 1, 2, 3), kernel = c("linear", "sigmoid", "radial")))
##
##
## Parameters:
## SVM-Type: C-classification
## SVM-Kernel: linear
## cost: 0.1
##
## Number of Support Vectors: 47
Plotando agora o modelo selecionado e vizualizando com os dados
model<- svm(Species~., data=Train_iris, type="C-classification", kernel="linear", cost=0.1)
plot(model, data=Train_iris, Petal.Width~Petal.Length)
Agora podemos gerar a tabela de confusão, afim de calcular a acurácia do modelo proposto, com o objetivo de superar os resultados anteriores dos modelos de redes neurais.
prediction<-predict(model,Test_iris)
xtab<-table(Test_iris$Species, prediction)
xtab
## prediction
## setosa versicolor virginica
## setosa 11 0 0
## versicolor 0 7 0
## virginica 0 0 11
#Acurácia
Ac<-sum(diag(xtab)) / nrow(Test_iris)
Ac
## [1] 1
Com a tabela acima, é evidente que houve uma boa qualidade no ajuste utilizando o método SVM. À acurácia foi de satisfatória, apresentando eficiência computacional.
Em suma, a aplicação dos modelos de redes neurais foi de forma geral satisfatória, sendo algumas abordagens com maior destaque do que outras. Entre as opções apresentadas, a de maior eficácia foi a terceira abordagem, apresentando um bom custo computacional, sem precisar aumentar a base de dados e mais rápido que a segunda abordagem. Em comparação com o outro método de classificação, denominado na literatura de SVM, computacionalmente foi ligeiramente menos eficaz, no qual, o SVM apresentou uma implementação mais fácil e uma melhor velocidade de execução, com uma eficácia tão boa quanto os demais modelos.