Inicio este texto referenciando a concepção de Steven Pinker, no livro “Como a mente funciona” que sintetiza os elementos desse processo e sua ligação com a lógica para atingirmos algum objetivo utilizando uma estratégia, onde ele afirma que as “Crenças são inscrições na memória, desejos são inscrições de objetivos, pensar é computação, percepções são inscrições acionadas por sensores, tentar é executar operações acionadas por um objetivo.” (Pinker, Editora Schwarcz, 2018, p. 90).
Gosto da parte “pensar é computação”. Essa tentativa de criarmos redes neurais que imitam o funcionamento do cérebro humano sempre me fascinou. Acredito que fascina qualquer pessoa quando escuta falar sobre inteligência artificial.
Como o título deste trabalho faz referência, este texto é uma tentativa de realizar uma pequena introdução na utilização de redes neurais de forma prática utilizando a ferramenta computacional R Project.
R-Project é um ambiente/ferramenta computacional que podemos também nos referir como uma linguagem de programação. O R-Project que vem progressivamente se especializando em manipulação, análise matemática/estatística e visualização gráfica de dados. Na atualidade é considerado o melhor ambiente computacional para essas finalidades. Possuindo uma vasta biblioteca de pacotes que já são instalados junto com o R-base mas não são carregados quando iniciamos o programa. Exsite também os pacotes de contribuições externas ao projeto (contributed packages), que não são instalados junto com o R-base. Estes pacotes estão disponíveis junto ao projeto CRAN
Será utilizado dois pacotes do CRAN para desenvolver essa introdução a redes neurais. O primeiro pacote que utilizaremos será o caret que possui funções diversas para treinamento e plotagem de modelos de classificação e regressão. O segundo pacote a utilizarmos é o neuralnet, onde utilizaremos para treinamento da nossa rede neural.
Abaixo segue um fluxo do passo a passo que realizaremos para criar a rede neural. O primeiro passo é criar a base de teste e treino. Consequentemente precisamos de uma base completa com as entradas para o nosso neurônio e a respectiva saída nesses dados. A rede neural que criaremos será utilizada para classificar três espécies plantas conhecida como “íris”.
O dataset de Iris é muito utilizado para testar o funcionamento de modelos clássicos de classificação. Ele foi criado a partir das características da flor Iris e o objetivo é classificar (definir a classe / rótulo) de qual é o tipo dessa flor, entre três tipos possíveis estão: Versicolor, Setosa e Virginica.
O conjunto de dados “Iris” consiste em 50 unidades amostrais de três espécies (setosa, virginica, versicolor) desta (espécie de planta) chamada íris, ou seja, temos um total de 150 unidades amostrais. Conforme imagem abaixo.
De cada uma delas mediu-se quatro variáveis morfológicas: comprimento (Length) e largura (Width) da sépala e comprimento e largura da pétala. O objetivo original é quantificar a variação morfológica em relação a essas espécies com bases nas quatro variáveis de interesse.
head(iris)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5.0 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
O processo de copiar o dataset iris para uma variável interna que chamerei de [dataset_iris]. O dataset iris já existe por padrão dentro do R-Project, em função disso não precisarei importar de nenhuma fonte externa para dentro do R-Project.
dataset_iris = iris
Agora o processo de criação de 3 (três) colunas e setar as mesmas como os valores [TRUE] ou [FALSE] conforme a espécie da cada flor e colocar um nome para cada coluna. Essa coluna será utilizada na saída da rede neural posterior nos testes com a mesma.
dataset_iris = cbind(dataset_iris,dataset_iris$Species=='setosa')
dataset_iris = cbind(dataset_iris,dataset_iris$Species=='versicolor')
dataset_iris = cbind(dataset_iris,dataset_iris$Species=='virginica')
names(dataset_iris)[6] <- 'setosa'
names(dataset_iris)[7] <- 'versicolor'
names(dataset_iris)[8] <- 'virginica'
head(dataset_iris)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species setosa
## 1 5.1 3.5 1.4 0.2 setosa TRUE
## 2 4.9 3.0 1.4 0.2 setosa TRUE
## 3 4.7 3.2 1.3 0.2 setosa TRUE
## 4 4.6 3.1 1.5 0.2 setosa TRUE
## 5 5.0 3.6 1.4 0.2 setosa TRUE
## 6 5.4 3.9 1.7 0.4 setosa TRUE
## versicolor virginica
## 1 FALSE FALSE
## 2 FALSE FALSE
## 3 FALSE FALSE
## 4 FALSE FALSE
## 5 FALSE FALSE
## 6 FALSE FALSE
O processo de treinamento consiste em dividir nosso dataset em duas partes, sendo a parte de treino ficando com 70% dos dados [dataset_treino] e o restante 30% para os testes [dataset_teste].
Observação: Caso o pacote não exista ainda no seu R-Project o mesmo deve ser instalado com o comando - install.packages("caret", dependencies=T), o mesmo encontra-se comentado no código abaixo:
#install.packages("caret", dependencies=T)
library(caret)
## Loading required package: lattice
## Loading required package: ggplot2
particao = createDataPartition(1:dim(dataset_iris)[1],p=.7)
dataset_treino = dataset_iris[particao$Resample1,]
dataset_teste = dataset_iris[- particao$Resample1,]
Criação da rede neural
Observação: Caso o pacote não exista ainda no seu R-Project o mesmo deve ser instalado com o comando - install.packages("neuralnet"), o mesmo encontra-se comentado no código abaixo:
#install.packages("neuralnet")
library(neuralnet)
modelo = neuralnet( setosa + versicolor + virginica ~ Sepal.Length + Sepal.Width + Petal.Length + Petal.Width , dataset_treino, hidden=c(5,4), act.fct = "logistic")
Função de Ativação - Função logística - Possui a função de trasnformar a saída de um neurônio antes que o sinal seja passado para a próxima camada.
\[f(x) = \frac{1}{1+e^{-x}}\] Função logística
logistica <- function(z) {
1 / (1 + exp(-z))
}
Gráfico da Função logística
x <- c(-10:10)
plot(x, logistica(x), type = "l", col = "red")
Plotagem da rede neural criada
plot(modelo, rep="best")
Realização dos testes da rede neural com apenas o registro [25] da base de teste [dataset_teste]. Estou deixando a visualização da base inteira comentada, caso queira examinar basta descomentar.
dataset_teste[25,1:5]
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 83 5.8 2.7 3.9 1.2 versicolor
#dataset_teste
teste = compute(modelo,dataset_teste[25,1:4])
resultado = as.data.frame(teste$net.result)
Tratando o resultado do teste para exibir no nome da flor
names(resultado)[1] <- 'setosa'
names(resultado)[2] <- 'versicolor'
names(resultado)[3] <- 'virginica'
resultado$class = colnames(resultado[,1:3])[max.col(resultado[,1:3], ties.method = 'first')]
resultado$class
## [1] "versicolor"
Realizando teste com toda a base de teste [dataset_teste]. E exibindo a matriz de confusão e seu percentual de acerto no teste.
teste = compute(modelo,dataset_teste[,1:4])
resultado = as.data.frame(teste$net.result)
names(resultado)[1] <- 'setosa'
names(resultado)[2] <- 'versicolor'
names(resultado)[3] <- 'virginica'
resultado$class = colnames(resultado[,1:3])[max.col(resultado[,1:3], ties.method = 'first')]
confusao = table(resultado$class,dataset_teste$Species)
confusao
##
## setosa versicolor virginica
## setosa 16 0 0
## versicolor 0 14 0
## virginica 0 2 12
Percentual de acertos = 95.45