Olá!
Hoje apresentamos uma aplicação de rede neural artificial no R. Para um entendimento teórico do assunto, recomendamos a leitura de 2 livros:
e
Neste exemplo, utilizamos o pacote NNET e a base disponível no repositório da UCI Bank Marketing Data Set.
Sobre a base de dados, ela contém 45.211 registros com 21 atributos, descritos abaixo:
Variáveis independentes:
1 - age - Idade
2 - job - Tipo de trabalho
3 - marital : Estado Civil
4 - education - Escolaridade
5 - default - Crédito em atraso?
6 - housing - Possui financiamento imobiliário?
7 - loan - Possui empréstimo pessoal?
8 - contact - meio de contato
9 - month - mês do contato
10 - day_of_week - dia da semana do contato
11 - duration - tempo da ligação
12 - campaign - quantidade de contatos
13 - pdays: tempo de contato decorrido desde a última tentativa (o valor 999 indica que o cliente nunca foi contactado antes)
14 - previous - número de contatos antes desta companha
15 - poutcome - indicação de sucesso da última campanha
Variável alvo/ variável dependente
16 - y - O cliente efetuou algum depósito?
Vamos ao código em R. Teremos 2 arquivos: um para rodar a rede e outro que nos dará suporte à visualização. Os dois arquivos estão em nosso GitHub com os nomes de NN.R para o primeiro e plot.net.R para o segundo, sendo que este último foi atualizado deste outro repositório: https://gist.github.com/fawda123'.
Primeiramente, instalamos a biblioteca nnet, e chamamos o arquivo plot.net.R com o comando source. Também lemos a base com o comando read.csv (veja que renomeamos a base para banco_UMF).
install.packages("nnet")
library(nnet)
source("./plot.net.R")
base <- read.csv("banco_UMF.csv",header = TRUE, sep = ';')
Agora, fazemos um reconhecimento da base.
> names(base)
[1] "age" "job" "marital" "education" "default" "balance"
[7] "housing" "loan" "contact" "day" "month" "duration"
[13] "campaign" "pdays" "previous" "poutcome" "deposito"
> head(base)
age job marital education default balance housing loan contact day month
1 58 management married tertiary no 2143 yes no unknown 5 may
2 44 technician single secondary no 29 yes no unknown 5 may
3 33 entrepreneur married secondary no 2 yes yes unknown 5 may
4 47 blue-collar married unknown no 1506 yes no unknown 5 may
5 33 unknown single unknown no 1 no no unknown 5 may
6 35 management married tertiary no 231 yes no unknown 5 may
duration campaign pdays previous poutcome deposito
1 261 1 -1 0 unknown no
2 151 1 -1 0 unknown no
3 76 1 -1 0 unknown no
4 92 1 -1 0 unknown no
5 198 1 -1 0 unknown no
6 139 1 -1 0 unknown no
>
Vemos que todas as variáveis foram carregas e que também temos algumas variáveis que são categóricas, como job ou education. Para rodar uma rede neural, todas as variáveis devem ser numéricas. Logo, precisamos executar alguma outra função que faça a conversão das variáveis categóricas em contínuas. Uma técnica que podemos utilizar é converter estas variáveis em dummies, que nada mais são do que uma binarização de cada um dos termos presentes nos dados categóricos. Podemos fazer isso facilmente no R, utilizando a função model.matrix(), como abaixo.
dummies <- as.data.frame(
model.matrix(
~ job + marital + education + default + housing
+ loan + contact + month + poutcome + deposito -1 ,
data=base)
)
base2 <- cbind(base$age,base$balance,base$day,base$duration,
base$campaign,base$pdays,base$previous,dummies)
Note que criamos um data frame para inserir as variáveis dummies e, na sequência, criamos uma variável chamada base2 que recebe este novo dado concatenado por coluna com o nosso alvo e as demais variáveis numéricas que não foram binarizadas. Ao verificar nossa nova base, temos um total de 43 variáveis preditoras, contra as 16 iniciais.
> names(base2)
[1] "base$age" "base$balance" "base$day"
[4] "base$duration" "base$campaign" "base$pdays"
[7] "base$previous" "jobadmin." "jobblue-collar"
[10] "jobentrepreneur" "jobhousemaid" "jobmanagement"
[13] "jobretired" "jobself-employed" "jobservices"
[16] "jobstudent" "jobtechnician" "jobunemployed"
[19] "jobunknown" "maritalmarried" "maritalsingle"
[22] "educationsecondary" "educationtertiary" "educationunknown"
[25] "defaultyes" "housingyes" "loanyes"
[28] "contacttelephone" "contactunknown" "monthaug"
[31] "monthdec" "monthfeb" "monthjan"
[34] "monthjul" "monthjun" "monthmar"
[37] "monthmay" "monthnov" "monthoct"
[40] "monthsep" "poutcomeother" "poutcomesuccess"
[43] "poutcomeunknown" "depositoyes"
Agora, vamos utilizar a biblioteca caret para separar a base entre treinamento e teste para treinar a rede e fazer uma avaliação dos resultados.
set.seed(611)
library(caret)
inTrain <- createDataPartition(y=base2$depositoyes,p = 0.70, list=FALSE)
training <- base2[inTrain,]
testing <- base2[-inTrain,]
dim(training); dim(testing)
Separamos agora as variáveis preditoras (x_training) do nosso alvo (y_training).
x_training <- training[,-44]
y_training <- training$depositoyes
x_testing <- testing[,-44]
Agora, chamamos a função nnet() que treina a rede neural. Em nosso exemplo, a rede possui uma camada intermediária com 5 neurônios e 1.000 interações para treinamento.
nn1<-nnet(x_training,y_training,size=5,linout=T,
rang = 0.1,decay = 5e-2, maxit = 1000)
Agora, utilizamos a função predict() para rodar nossa rede treinada na base de teste (x_testing). Na sequencia concatenamos o alvo com os valores preditos e escrevemos os resultados em um arquivo .csv
prediction <- predict(nn1,x_testing)
evaluation <- cbind(prediction,testing$depositoyes)
write.csv2(evaluation,file='evaluation_2.csv')
Para visualizar a rede, chamamos a função plot.nnet(), importada do arquivo plot.net.R. Nossa rede armazenada no objeto nn1 é passada como parâmetro da função. Também configuramos para que pesos negativos ficassem em vermelho e os positivos, em azul.
plot.nnet(nn1,pos.col='darkgreen',neg.col='darkblue',alpha.val=0.3,rel.rsc=5,
circle.cex=1,cex=1,
circle.col='brown')
Com este destaque, podemos ver que a variável poutcomeunknown é majoritariamente negativa, ou seja, termos o desconhecimento de como foi o contato na última campanha afete negativamente o desempenho da campanha atual, assim como os meses de novembro e setembro.
Um abraço e até o próximo post!
Curiosa a visualização. Ok, caso esteja trabalhando com um multilayer perceptron a coisa irá ficar bem confusa, mas ainda assim tem um valor didático interessante.
ResponderExcluirNo aguardo do post sobre DBN. :)
Evandro, isto que você comentou é alvo de muita discussão nas redes neurais. Visualizar a rede em si geralmente é bem difícil, ainda mais nesta complexidade que você mencionou. Mas já dá para entender alguma coisa...o interessante é saber avaliar os pesos e evitar o overfit.
ResponderExcluirSobre o DBN, vou pensar em alguma aplicação e posto aqui :) Abraço
simple and perfect.
ResponderExcluirPHP Training in Chennai
Redes Neurais, IA são assuntos que adoro, gostaria de ver mais posts sobre o assunto e sempre com uma abordagem técnica, seja com R ou Python.
ResponderExcluirExcelente post !
PHP is an excellent programming language used widely by most of the web developers. Your article made me learn PHP certification. Thanks for the motivation.
ResponderExcluirRegards:
Best PHP training in chennai
PHP Training
Excellent blog!! Such an interesting content to read, your idea made to take Web Designing Certifications. Keep updating more ideas. Thank you.
ResponderExcluirRegards:
web design training course
web designing institute