RENATO MAIA CHACON
UMA ANÁLISE DA FERRAMENTA LUDWIG, APLICADA NO CONTEXTO DA CIÊNCIA DOS DADOS E MODELOS DE DEEP LEARNING
NATAL 2019
UNIVERSIDADE FEDERAL DO RIO GRANDE DO NORTE CENTRO DE TECNOLOGIA
DEPARTAMENTO DE ENGENHARIA DE COMPUTAÇÃO E AUTOMAÇÃO – DCA
RENATO MAIA CHACON
UMA ANÁLISE DA FERRAMENTA LUDWIG, APLICADA NO CONTEXTO DA CIÊNCIA DOS DADOS E MODELOS DE DEEP LEARNING
Trabalho de conclusão de curso de Engenharia de Computação da Universidade Federal do Rio Grande do Norte, apresentado como requisito parcial para obtenção do grau de Bacharel em Engenharia de Computação
Orientador: Ivanovitch Medeiros Dantas da Silva
Universidade Federal do Rio Grande do Norte – UFRN Departamento de Engenharia de Computação e Automação – DCA
Curso de Engenharia de Computação
NATAL 2019
RENATO MAIA CHACON
UMA ANÁLISE DA FERRAMENTA LUDWIG, APLICADA NO CONTEXTO DA CIÊNCIA DOS DADOS E MODELOS DE DEEP LEARNING
Trabalho de conclusão de curso apresentado à Universidade Federal do Rio Grande do Norte, como requisito para a obtenção do grau de Bacharel em Engenharia de Computação.
Banca Examinadora:
Prof. Dr. Ivanovitch Medeiros Dantas da Silva – Orientador UFRN
MSc. Marianne Batista Diniz da Silva – Avaliadora externa
MSc. Aguinaldo Bezerra – Avaliador externo
Dedico este trabalho à memória do meu avô, Erasmo Galvão Chacon.
AGRADECIMENTOS
Ao meu orientador Ivanovitch Medeiros Dantas da Silva por todo o empenho, disponibilidade e atenção dados a este trabalho. Suas referências e conselhos foram fundamentais ao enriquecimento dos assuntos aqui tratados.
Aos meus pais e irmã, por todo o amor, companheirismo e compreensão nos momentos de ausência no decorrer do curso. À minha avó Lúcia, pelo amor incondicional e empenho para que eu tivesse todas as ferramentas necessárias para dar continuidade aos estudos.
À Larissa, minha amada companheira, por estar comigo do início ao fim desta jornada. Sua presença, carinho e dedicação foram essenciais e me deram ânimo nos momentos mais difíceis. Obrigado por acreditar em mim.
À minha cadela Bella, por me fazer companhia e abrilhantar o ambiente com sua presença. À Baruc, também pela ilustre presença descontraindo até mesmo momentos de tensão.
Aos meus amigos Felipe, Rebeca e Jair, pela constante amizade durante todo esse período do curso. Obrigado por serem compreensivos, não me cobrarem e me quererem tão bem.
Aos colegas de curso, cujo empenho e solidariedade foram de suma importância para alcançar minhas metas: André, Nathan, Glauco, Isolda, Matheus, Lukas, Denis, Jairo, Anderson, Renan, Genilson, Jonathan, Otávio, Vanessa, Reinaldo, Renato e Leonardo.
Aos professores do DCA Luiz Affonso H. Guedes e Carlos Manuel Dias Viegas, pela visível preocupação e dedicação ao meu engrandecimento profissional como engenheiro. Ao professor Diogo Pinheiro Fernandes Pedrosa, por toda a ajuda prestada enquanto coordenador e também ex-coordenador.
RESUMO
A ciência de dados está diretamente associada ao atual contexto de aumento de dados gerados, visto que é utilizada para compreensão desses. Por meio dela, informações são extraídas de diversas formas a fim de atender a diferentes interesses. Diante do cenário de crescente democratização do conhecimento, surgiram ferramentas que visam auxiliar usuários(as) em projetos na área de ciência de dados. Nessas circunstâncias, a Uber desenvolveu o Ludwig, uma ferramenta de deep learning que não demanda conhecimento aprofundado de programação. O objetivo deste trabalho é analisá-la com o intuito de medir seu potencial por meio de modelos de classificação e regressão. A metodologia abordada consiste na instalação do Ludwig e uso de diferentes abordagens para verificar seu desempenho. Concluiu-se que embora cumpra sua proposta de treinar e testar modelos de deep learning sem necessitar de programação, o Ludwig ainda precisa de ajustes para se tornar mais atrativo a usuários inexperientes.
ABSTRACT
Data science is directly associated to the context of increasing income of data, given that this subject aims to the understanding of it. Through this issue, information is extracted by several means in order to accomplish different interests. Considering the knowledge’s growing democratization process, some tools were developed with the purpose to help users on their data science projects. In this scenario, Uber elaborated Ludwig, a deep learning tool which doesn’t demand profound knowledge in programming skills. The aim of this study is to analyze it in the interest of measuring its potential by classification and regression models. The methods consist of installing Ludwig and using different approaches to verify its performance. In conclusion, although Ludwig fulfills its purpose on training and testing deep learning models without the need to write code, it still needs adjustments in order to become more attractive to unexperienced users.
LISTA DE FIGURAS
Figura 1. Pipeline de ciência dos dados...4
Figura 2. Duas estratégias diferentes para lidar com valores vazios ...6
Figura 3. Métodos...7
Figura 4. AEDs...9
Figura 5. Gerando correlograma por meio da correlação entre colunas...10
Figura 6. Gerando dummies de duas colunas de tipo categóricas...10
Figura 7. Feature Engineering para criar nova coluna a partir da manipulação das demais...11
Figura 8. Métodos de aprendizado e seus respectivos modelos...12
Figura 9. Clusterização...13
Figura 10. Interface básica de uma rede neural...14
Figura 11. Soma ponderada...15
Figura 12. Predição de múltiplas entradas e saídas...16
Figura 13. Hidden layers...18
Figura 14. Resumo do funcionamento da arquitetura utilizada no Ludwig...22
Figura 15. Primeira tentativa realizada...28
Figura 16. Resultado do treinamento do modelo n°1 do dataset Titanic...28
Figura 17. Tentativa n°2 realizada no dataset do Titanic...30
Figura 18. Resultado do treinamento do modelo nº 2 do dataset Titanic...30
Figura 19. Tabela de scores fornecida pelo Kaggle...31
Figura 20. Curvas de aprendizado...32
Figura 21. Tentativa n°1 realizada no dataset TMDB...34
Figura 23. Tentativa n°2 realizada no dataset TMDB...35 Figura 24. Resultado do treinamento do modelo nº 2 do dataset TMDB...35 Figura 25. Tentativa n°1 realizada no dataset de análise de sentimentos...36 Figura 26. Resultado do treinamento do modelo nº 1 do dataset de análise de sentimentos...37 Figura 27. Tentativa n°2 realizada no dataset de análise de sentimentos...37 Figura 28. Resultado do treinamento do modelo nº 2 do dataset de análise de sentimentos...38 Figura 29. Comparação de performance em diferentes modelos de classificação....38 Figura 30. Comparação de acurácia em diferentes modelos de classificação...39 Figura 31. Curva ROC...40
LISTA DE TABELAS
Tabela 1. Descrição das colunas do dataset Titanic...3 Tabela 2. Argumentos para datasets...24 Tabela 3. Descrição das colunas do dataset TMDB...33
LISTA DE ABREVIATURAS E SIGLAS
AED Análise Exploratória de Dados CNN Convolutional Neural Network
CSV Comma-Separated Values
GPU Graphics Processing Units HDF5 Hierarchical Data Format JSON JavaScript Objects Notation RNN Recurrent Neural Network
ROC Receiver Operating Characteristic Curve SQL Structured Query Language
TMDB The Movie Database
SUMÁRIO 1 INTRODUÇÃO 1 1.1 Motivação 1 1.2 Objetivos 2 1.3 Estrutura do Trabalho 2 2 FUNDAMENTAÇÃO TEÓRICA 3 2.1 Coleta 4 2.2 Limpeza 5
2.3 Análise Exploratória de Dados (AED) 8
2.4 Aprendizado de Máquina 11 2.4.1 Aprendizado supervisionado 12 2.4.2 Aprendizado não-supervisionado 13 2.4.3 Aprendizado semi-supervisionado 14 2.4.4 Aprendizado reforçado 14 2.4.5 Redes Neurais 14 2.4.6 Deep learning 19 3 A FERRAMENTA 20 3.1 Arquitetura 21 3.2 Instalação 22 3.3 Pré-processamento 22 3.4 Train 24 3.5 Predict 25 3.6 Test 26 3.7 Experiment 26 3.8 Visualize 26 4 RESULTADOS 27
4.1 Titanic: Machine Learning from Disaster 27
4.2 TMDB 5000 Movie Dataset 32
4.3 Sentiment Analysis 36
5 CONCLUSÃO 40
1 INTRODUÇÃO
O crescimento exponencial das tecnologias tem permitido o desenvolvimento de hardwares cada vez mais potentes que, juntamente com a evolução da microeletrônica, têm gerado novos dispositivos. O alto poder computacional desses aparelhos possibilita um poder de comunicação elevado, gerando milhões de dados e, consequentemente, o desafio do que fazer com eles. A Ciência de Dados é uma área do conhecimento computacional que aborda diversas áreas de estudo, com destaque para a estatística e aprendizado de máquina (GROS, 2015). Devido à compreensão e aplicação de técnicas de programação serem de suma importância, essa área tem atraído grande quantidade de estudantes e profissionais da área no Brasil e exterior.
Tanto a necessidade quanto o crescimento do interesse pela ciência de dados se devem ao constante aumento de dados no cotidiano em geral, seja ele na internet, nas indústrias ou no comércio (GROS, 2015). Dessa forma, sua aplicação pode abranger casos diversos, tais como: uma escola interessada em analisar desempenho estudantil dos alunos para prever casos de evasão e reprovação; um supermercado que deseja obter o perfil dos clientes com base nos produtos que compram a fim de decidir que tipo de produto ofertar futuramente, dentre outros. A ideia consiste na extração de dados aliada à análise virtual e estatística dos mesmos, permitindo que sejam utilizadas ferramentas de inteligência artificial não só para compreender o que está sendo analisado, como também para prever seu comportamento futuro.
1.1 Motivação
A mineração de dados surge como uma tentativa de agregar valor à ideia anteriormente apresentada, fornecendo um direcionamento ao questionamento sobre o que fazer com todo o volume de dados disponível. A mineração de dados tem como objetivo final auxiliar no processo de decisão a partir dos dados trabalhados (HAN; KAMBER; PEI, 2011). Para assegurar a eficiência da decisão, é preciso garantir que
os dados sejam tratados adequadamente após coletados, podendo ser por meio da remoção de outliers, feature engineering e detecção de padrões.
Existem diversas ferramentas disponíveis para mineração de dados, tanto sem custo, quanto pagas. Entre as mais comumente usadas e difundidas estão Orange 31, Tableau2 e Power BI3, cabendo ao usuário selecionar a que melhor se adeque às suas pretensões por meio de seus dados. Independente da ferramenta escolhida, a premissa é sempre a mesma: não é possível inferir informações “a olho nu” dos dados que se têm em mãos, sendo necessária a mineração de dados aliada a conhecimentos em programação e estatística para gerar melhores análises (HAN; KAMBER; PEI, 2011).
1.2 Objetivos
Embora facilitem o tratamento de dados a fim de obter resultados a partir dos mesmos, essas ferramentas ainda demandam conhecimento e práticas de programação. Sendo assim, a inclusão de novos usuários a essas tecnologias é ainda mais prejudicada, o que dificulta o acesso de pessoas que não cursaram áreas de estudo relacionadas à computação, mas que se interessam pelo tema. Considerando esse cenário, este trabalho objetiva explorar a ferramenta open source de deep learning desenvolvida pela Uber4, que possibilita fazer análises automáticas com conhecimento mínimo em programação: o Ludwig5. Além disso, será verificada a possibilidade da utilidade desta a usuários inexperientes na área.
1.3 Estrutura do Trabalho
O presente trabalho faz no capítulo 1 uma contextualização acerca da ciência de dados, evidenciando sua importância e difusão, além de expor obstáculos que as ferramentas de mineração de dados representam a usuários inexperientes. Em seguida, o capítulo 2 descreve a fundamentação teórica por trás da ciência de dados,
1 https://orange.biolab.si/ 2 https://www.tableau.com/ 3 https://powerbi.microsoft.com/pt-br/ 4 https://www.uber.com/br/pt-br/ 5 https://eng.uber.com/introducing-ludwig/
descrevendo as etapas envolvidas no processo. O capítulo 3 aborda a ferramenta Ludwig, enquanto o 4 consiste de um estudo de caso sobre a mesma, demonstrando seu uso para solucionar três problemas distintos. Por fim, o capítulo 5 é reservado para as conclusões e implicações sobre o trabalho, seguido pelas referências.
2 FUNDAMENTAÇÃO TEÓRICA
Este capítulo visa esclarecer o pipeline de ciência de dados (Figura 1), ou seja, as etapas que a compõem. Serão explicados processos iniciais como a coleta de dados até etapas finais envolvendo suas predições. Com o intuito de enriquecer a explicação, o dataset da competição do Kaggle6 referente ao Titanic será utilizado na prova de conceito (Tabela 1). A competição “Titanic: Machine Learning from Disaster” diz respeito ao desastre que culminou no naufrágio do Titanic, em 15 de abril de 1912. De um total de 2224 passageiros, 1502 morreram. Essa competição consiste na análise de diversos dados sobre cada passageiro do Titanic, objetivando ao fim prever os que sobreviveram à tragédia.
Tabela 1. Descrição das colunas do dataset Titanic.
Fonte: elaborada pelo autor
Anexadas, constam linhas de código de um notebook referente ao dataset de tripulantes do Titanic a fim de ilustrar etapas e técnicas abordadas. A implementação dos exemplos abordados será na linguagem Python7, usando bibliotecas amplamente conhecidas como Pandas8, Matplotlib9 e Seaborn10.
Figura 1. Pipeline de ciência dos dados. Fonte - Elaborada pelo autor
2.1 Coleta
Os dados podem ser coletados de diferentes maneiras, podendo vir em diferentes formatos. São classificados, de acordo com sua estrutura, como estruturados e não estruturados, sendo os do tipo estruturado de mais fácil compreensão (RUSSOM, 2007) por estarem geralmente organizados de maneira similar às planilhas do Excel. Arquivos comma-separated values (CSV) são comumente utilizados para armazenar dados estruturados. Amplamente utilizado por estudantes e pesquisadores, é facilmente obtido por meio de arquivos em competições no Kaggle, estudos de caso no Datacamp11 e até mesmo instituições governamentais. 7 https://www.python.org/ 8 https://pandas.pydata.org/ 9 https://matplotlib.org/ 10 https://seaborn.pydata.org/ 11 https://www.datacamp.com/
No entanto, estima-se que somente 15% a 20% dos dados gerados são estruturados (RUSSOM, 2007). Em outros termos, a maioria dos dados disponíveis se encontra de forma não organizada, caracterizando-se por não possuir formato definido. Devido a essa complexidade, são exigidos profissionais e softwares mais capacitados para empregar algoritmos e técnicas a fim de garantir a qualidade da coleta e armazenamento.
Existem outras maneiras de obter dados além dos convencionais downloads de arquivos de datasets já prontos para uso. Por meio do processo de Web Scraping é possível extrair informações de páginas da Web, visto que as mesmas são escritas em HTML. Em se tratando de textos não estruturados, bibliotecas de fácil instalação como Beautiful Soup, requests e html5lib são usadas para retirar a informação de forma mais estruturada. O uso de Application Programming Interfaces (APIs) é uma outra forma comumente usada de coleta, permitindo ao usuário obter o dado de forma estruturada sem necessidade de scraping. Twitter e Facebook por exemplo, oferecem acesso às suas informações por meio de seus APIs, permitindo acesso a informações em tempo real.
A linguagem de programação Structured Query Language (SQL) desempenha uma importante função na área de ciência de dados. SQL é uma linguagem simples e eficiente, usada principalmente para recuperar dados para posterior análise. Sua vantagem consiste na rapidez desse processo de recuperação de dados, facilitado por poderem ser acessados diretamente de onde estão armazenados. Sendo assim, o SQL possibilita armazenar os dados em bancos de dados e então manipulá-los. 2.2 Limpeza
O processo de limpeza de dados prepara-os para análise, sendo essencial para que possam ser melhor compreendidos. Após obtidos, dificilmente os dados se encontram “limpos” a ponto de não ser necessário modificá-los. As principais características em um dataset que justificam sua limpeza são: valores ausentes, dados duplicados, outliers, problemas envolvendo indexação, inconsistências envolvendo nomes das colunas e a maneira como essas estão organizadas. Essa etapa exige um maior conhecimento de computação e estatística, visto que é requerido saber manipular os dados através de funções e bibliotecas, bem como entender o impacto gerado no modelo.
Durante esse processo, algumas bibliotecas permitem uma melhor visualização dos dados a fim de facilitar tomadas de decisão sobre os mesmos. A biblioteca Pandas, por sua vez, permite a leitura de diversos formatos de dados, como CSV, hierarchical data format (HDF5) e Excel. Quando utilizada para leitura de arquivos (Figura 3A), tem como resultado sua principal estrutura para armazenamento de dados: o Dataframe. Esta estrutura possui um vasto número de atributos e métodos que são utilizados para consultas em relação ao número de linhas e colunas de um dataset, detecção e remoção de valores faltantes, plotagens, tipos de coluna, dentre outros (Figura 3B, 3C e 3D). Uma outra estrutura utilizada pelo Pandas é Series, originada quando uma coluna de um Dataframe é selecionada. Embora Series também disponha de atributos e métodos, eles não são em sua totalidade igualmente aplicáveis ao Dataframe, cabendo ao programador saber aplicá-los.
Diferentes estratégias podem ser adotadas para solucionar tais problemas. Os valores ausentes, por exemplo, consistem em valores vazios que prejudicam todo o dataset em relação à visualização e predição. De acordo com as situações em que se encontra, diferentes estratégias podem ser consideradas ao lidar com eles. Em determinado contexto, o usuário pode optar tanto por retirar as linhas contendo esses valores como também por transformar esses valores na média ou mediana da coluna em que se encontram (Figura 2). As linhas duplicadas, por sua vez, prejudicam o modelo, visto que o tornam tendencioso quando treinado com fins preditivos, além de aumentar o custo computacional.
Figura 2. Duas estratégias diferentes para lidar com valores vazios: substituindo-os pela média da coluna ou simplesmente deletando linhas que os contém.
’
Figura 3. Métodos. A) Importando biblioteca Pandas, lendo arquivos CSV e obtendo nº de linhas e colunas. B) Obtendo nomes das colunas e imprimindo primeiras linhas do dataset contendo colunas específicas. C) Imprimindo quantidade e tipo de valores não nulos em cada coluna. D) Obtendo soma de valores não nulos em cada coluna.
Fonte: elaborada pelo autor A)
B)
C)
2.3 Análise Exploratória de Dados (AED)
AED é uma etapa crucial para a ciência de dados. Suas ferramentas consistem basicamente de gráficos, tabelas e plotagens. De maneira geral, AED usa a informação oriunda dos estágios de limpeza e análise para plotar distribuições das variáveis, transformá-las, procurar por relações entre as mesmas e gerar resumos estatísticos para todas elas (O’NEIL & SCHUTT, 2013). Por se tratar de uma análise, são empregadas diferentes estratégias de visualização dos dados por meio de bibliotecas como Seaborn (Figura 4A) e Matplotlib (Figura 4B). A finalidade com a qual são utilizadas é permitir enxergar padrões que determinem detecção de outliers (Figura 4C), correlação entre variáveis (Figura 4D), padrões, entre outros.
As descobertas por meio de AED são utilizadas em contextos variados, de informações importantes para predição de dados até apresentações para pessoas leigas na área em questão. Para este último caso, as plotagens constituem uma importante ferramenta de inclusão graças a recursos como correlogramas (Figura 5), pairplots e boxplots, que facilitam a compreensão das variáveis e suas relações com as demais.
Tendo em vista que o processo de AED refere-se à busca por informações relevantes, cabe ao programador não se contentar com as informações das colunas fornecidas pelo dataset em que trabalha. Isso significa que as colunas possuem informações, as quais, se manipuladas adequadamente, podem agregam mais valor a si ou até mesmo gerar novas colunas. Essa manipulação é representada pelo termo feature engineering, considerada uma prática essencial no preparo de dados para modelos de aprendizado de máquina (ZHENG, 2018).
A codificação de colunas categóricas em numéricas demonstra a importância dessa prática, visto que possibilita o uso desses dados para fazer correlações, mapas de calor e inserção em modelos de aprendizado de máquina. Através do método get_dummies da biblioteca Pandas, são criadas colunas para cada valor categórico da coluna selecionada, contendo apenas valores binários. Esses indicam se o valor pertencente à coluna consta ou não na linha em questão (Figura 6).
Figura 4. AEDs. A) Método swarmplot da biblioteca Seaborn, indicando a distribuição de idade por sexo. B) Histograma no qual verifica-se a distribuição por idade de não sobreviventes. C) Gráfico de dispersão onde evidencia-se que as maiores tarifas foram pagas por pessoas de 1ª classe e que estas possuem maior incidência de sobrevivência. D) Preparando o dataset a fim de verificar a correlação da coluna ‘Survived’ com as restantes. Fonte: elaborada pelo autor
A) B)
Figura 5. Gerando correlograma por meio da correlação entre colunas. Fonte - Elaborada pelo autor
Figura 6. Gerando dummies de duas colunas de tipo categóricas. Fonte - Elaborada pelo autor
A alteração ou criação de colunas por meio da interpretação e entendimento das demais é outra prática de feature engineering bastante valorizada. A exemplo do dataset até então utilizado, a coluna Cabin (cabine) contém 147 valores diferentes de um total de 204. Tamanha variância em valores categóricos não traz relevância para a coluna em questão se usada em um modelo, pois comprometeria o processo de treinamento e, consequentemente, a performance do modelo (ZHENG, 2018). Uma maneira intuitiva de contornar essa situação seria criar uma coluna para os conveses, que consistem apenas da primeira letra das cabines (Figura 7).
Figura 7. Feature engineering para criar nova coluna a partir da manipulação das demais. Fonte - Elaborada pelo autor
2.4 Aprendizado de Máquina
O aprendizado de máquina (em inglês, machine learning) objetiva o entendimento dos dados de um determinado problema por meio de modelos matemáticos. O aprendizado se dá por meio da exposição de dados escolhidos pelo usuário ao modelo que, por sua vez, poderá ser usado para predição e entendimento de dados recém observados (VANDERPLAS, 2016). Recomenda-se dar início a esse processo após alguns dados relevantes terem sido levantados no processo de AED, de maneira a facilitar o aprendizado. Existem várias bibliotecas disponíveis para uso de machine learning, sendo Scikit-Learn12, PyTorch13, Tensorflow14 e Keras15 as mais
12 https://scikit-learn.org/stable/ 13 https://pytorch.org/
14 https://www.tensorflow.org/ 15 https://keras.io/
conhecidas. O aprendizado é classificado como supervisionado, não supervisionado, semi-supervisionado ou reforçado (Figura 8).
Figura 8. Métodos de aprendizado e seus respectivos modelos.
Fonte – Adaptado de (https://www.paladion.net/blogs/5-minute-guide-to-ai-in-cyber-security)
2.4.1 Aprendizado supervisionado
Este tipo de aprendizagem caracteriza problemas cujos dados são rotulados, de forma que a partir dos mesmos o modelo possa aplicar rótulos a dados ainda não conhecidos (VANDERPLAS, 2016). Em outros termos, o aprendizado supervisionado leva em consideração a informação que detém e a transforma na qual deseja-se obter. Casos como a classificação de e-mails em spam ou não exemplificam essa relação entre entrada e saída envolvendo rotulação.
Desta forma, o dataset pode ser dividido entre features e target. O target corresponde à coluna de valores da variável a ser prevista, enquanto as features são as variáveis de predição usadas para prever o target. De acordo com o comportamento da variável target, o problema é considerado de classificação ou regressão. Se discreta e de natureza categórica como o exemplo do spam, o modelo é de classificação. Caso contínua, a exemplo da variação de preços, trata-se de regressão.
2.4.2 Aprendizado não-supervisionado
A aprendizagem não supervisionada é responsável por agrupar dados de maneira que encontre padrões e retorne-os ao usuário. Esse método é oposto ao supervisionado, visto que não objetiva predições ao procurar por padrões. A tarefa de agrupar um conjunto de dados, conhecida como clustering, consiste de um exemplo de aprendizado não-supervisionado. Nela, características específicas são analisadas e transformadas em rótulos de forma que cada uma esteja associada a um rótulo específico (Figura 9). Embora existam diferentes métodos de aprendizado não-supervisionado, todos podem ser considerados uma forma de clustering.
Figura 9. Clusterização. Fonte - Adaptado de (GÉRON, 2017)
Tendo em vista que não possui funções preditivas, o dataset utilizado nesse tipo de aprendizado não é composto por uma coluna target. Organiza-se de forma que features engloba todas as colunas e samples representa suas linhas. Assim, seus samples são considerados pontos em um espaço n-dimensional, onde a dimensão é dada pelo número de features.
2.4.3 Aprendizado semi-supervisionado
O aprendizado semi-supervisionado, como seu nome sugere, é um intermédio entre o supervisionado e não-supervisionado. Esse método objetiva utilizar o máximo de dados não rotulados em situações em que poucos dados rotulados estão disponíveis. Ultimamente, tem sido pesquisado em conjunto com tecnologias de deep learning, por permitirem uso abundante de amostras não rotuladas (YOSHIYAMA & SAKURAI, 2017).
2.4.4 Aprendizado reforçado
O método reforçado possui um sistema de aprendizado conhecido como agente, o qual é incumbido de observar o ambiente e tomar decisões. A depender dessas decisões, o agente é recompensado ou penalizado, na forma de recompensas negativas. O sistema então aprende por si próprio qual a melhor estratégia a ser tomada para que obtenha o maior número de recompensas. Esse processo de tomada de decisão é denominado policy (GÉRON, 2017).
2.4.5 Redes Neurais
Redes neurais referem-se a um conjunto de modelagens que, de forma genérica, se utiliza da multiplicação para realizar operações sobre dados de entrada (em inglês, inputs) e pesos (em inglês, weights) e gerar um dado de saída (em inglês, output) (Figura 10). Os inputs têm suas informações interpretadas com o uso dos pesos. Estes por sua vez representam a sensibilidade entre inputs e predições, dado que um valor alto atribuído a um peso aumenta a predição com relação ao input.
Figura 10. Interface básica de uma rede neural. Fonte: elaborada pelo autor
Para garantir a acurácia de suas predições, as redes neurais podem combinar vários inputs simultaneamente. Ou seja, quanto mais bem informada a rede, melhores serão suas decisões. Consequentemente, é preciso que o total de predições seja somado a cada multiplicação dos inputs por seus respectivos pesos (Figura 11). Esse processo é conhecido como soma ponderada ou pré-ativação, e mede a força da interação entre entradas e pesos (KRIEGESKORTE & GOLAN, 2019). Quando aplicado, inputs e pesos são utilizados como vetores por facilitam as operações entre si.
Figura 11. Soma ponderada. Fonte: elaborada pelo autor
Existem outras formas nas quais a rede neural se apresenta. É possível haver predições com múltiplos inputs e outputs, em que por exemplo existem diferentes pesos para cada nó de um input específico, ou seja, um número de somatórios de pesos independentes dos inputs. Por último, é viável prever por meio das próprias predições (outputs), utilizando-se das mesmas como input para outra rede.
Figura 12. Predição de múltiplas entradas e saídas. Fonte: adaptado de (TRASK, 2016)
Após feitas as predições, é necessário garantir que os resultados atenderam às expectativas. Para essa ocasião, o cálculo do erro é uma medida comumente adotada que mede a informação perdida e possui diversas formas. O erro médio quadrado (mean squared error) é uma técnica bastante utilizada e útil, visto que, ao elevar o erro ao quadrado, o força a ser positivo. Além disso, uma outra vantagem que apresenta é a de penalizar erros significativos e suavizar erros de valores pequenos. Por essas razões, o MSE se adequa a qualquer problema de predição. Em casos particulares de regressão, pode se comportar como um estimador das suas variâncias (O’NEIL & SCHUTT, 2013).
Dentre os diferentes métodos de aprendizado neural, o quente e frio (hot and cold) se destaca por sua simplicidade. De acordo com TRASK (2016), hot and cold significa balancear os pesos a fim de verificar a direção na qual o erro é reduzido em sua maioria e movê-los nessa direção, repetindo o processo até que o erro seja igual a 0. Entretanto, esse método é de baixa eficiência, pois requer várias predições para que um único peso seja atualizado. Outro agravante é a possibilidade de não prever o valor desejado. Isso ocorre pois, apesar de saber em que direção mover o peso, o hot and cold desconhece o quanto precisa movê-lo. Assim, um valor arbitrário
denominado step_amount é escolhido e não há garantia de que o valor correto seja aprendido.
O gradiente descendente (gradient descent) é um método que não sofre dos problemas citados anteriormente, uma vez que permite o cálculo da direção e quantia do peso a serem mudados para minimizar o erro (TRASK, 2016). A interação entre peso e erro é melhor entendida com o uso de derivadas em que, dada a curva de erro, informam o quanto o erro será afetado pela mudança do peso em certo ponto. Considera-se que a derivada significa a inclinação da curva ou reta em dado ponto e sempre aponta para a direção oposta do menor ponto. Dessa forma, se a inclinação é positiva, o peso deve ser diminuído a fim de minimizar o erro e vice-versa. Entretanto, em algumas ocasiões as predições alternam bastante à cada passo, o que ocasiona um distanciamento da resposta almejada. Essas ocasionais divergências são geradas por inputs demasiado grandes, fazendo com que o peso atualizado também seja grande até mesmo se o erro for pequeno. Devido ao erro ser muito sensível ao peso, qualquer mudança neste afetará a predição de forma significativa. Uma maneira de impedir que os pesos atualizados se sobrecarreguem é por meio da multiplicação dos mesmos por uma fração denominada alpha (learning rate). Por não possuir valor fixo, recomenda-se que sejam feitas tentativas com diferentes valores a fim de obter um resultado satisfatório (TRASK, 2016)
O gradient descent é uma técnica utilizada para otimização em redes neurais. Entretanto, há casos em que o conjunto de treinamento é otimizado e o de predições (ou testes), não. Isso ocorre devido às últimas etapas de treinamento se sobreporem às nuances do conjunto de treinamento, o que acaba por comprometer o conjunto de teste (AGGARWAL, 2018). A solução para esse problema é denominada early stopping, na qual uma parte do conjunto de treinamento é mantida em espera, formando o conjunto de validação. Dessa forma, o treinamento é aplicado no conjunto de treinamento enquanto monitora-se o erro do modelo no de validação. Ainda de acordo com AGGARWAL (2018), em alguma etapa do treinamento, o erro começará a subir no conjunto de validação, mesmo que no de treinamento esteja diminuindo. Esse é a etapa do processo que causará a sobreposição (em inglês, overfitting), sendo necessário interrompê-la. Apesar de interrompido o processo, os melhores valores computados nos dados de validação são registrados.
De maneira geral, as interações nas redes neurais são representadas da seguinte forma: à esquerda, são colocadas as camadas de input representadas pelas
chamadas features. À direita, encontram-se as camadas de output, ou seja, as predições do modelo em questão. Assim sendo, todas as camadas que não forem de input ou output são consideradas camadas escondidas (em inglês, hidden layers). Elas são chamadas assim porque enquanto as outras duas camadas correspondem a valores conhecidos cujos dados podem ser armazenados, as hidden layers não correspondem a algo que se tem dados sobre ou que possa ser observado. Cada feature é representada por um nó, assim como o output gerado por elas. Nas hidden layers, cada nó representa as informações agregadas dos inputs, o que permite ao modelo detectar interações entre as features (HAYKIN, 2009). Ou seja, ao invés de afetarem a predição de forma direta e separada, as features se encaminham para os nós na hidden layer onde são agrupadas de acordo com a interação que possuem entre si e então usadas para gerar um output (Figura 13).
Figura 13. Hidden layers. Fonte - Adaptado de (NIELSEN, 2015)
Para que a predição gerada seja satisfatória, é preciso aplicar nas hidden layers uma função de ativação. Isso se faz necessário porque as funções de ativação permitem ao modelo detectar não linearidades entre os dados que chegam aos nós da hidden layer, a fim de que a partir daí sejam produzidos os dados de saída da camada em questão. Não linearidades correspondem a informações de natureza não dedutiva, embora ainda sejam de importância para que uma boa predição seja feita com base na compreensão desses dados.
Assim como o forward propagation envia dados pela hidden layer até a camada de output, backpropagation usa o erro gerado nessa camada e propaga-o para trás,
para as camadas de input por meio das hidden layers. Dessa maneira, calcula sequencialmente as inclinações dos pesos ao redor da predição até os demais vindos dos inputs. Em outros termos, obtém o gradiente para todos os pesos, fazendo com que sejam atualizados (AGGARWAL, 2018). Como precisa do erro de predição para calcular as inclinações, o backpropagation só pode ser feito após o forward propagation. Em razão da eficiência computacional, as inclinações são geralmente calculadas em um subconjunto dos dados denominado batch. Assim, diferentes batches são usados para as próximas atualizações e, uma vez que todos os dados são utilizados, o processo é iniciado novamente. Cada vez que isso acontece equivale a um epoch. O gradient descent, por exemplo, usa todos os dados para calcular cada inclinação enquanto o stochastic gradient descent utiliza um batch de cada vez para cálculo da inclinação.
A biblioteca Keras é amplamente utilizada no processo de criação e optimização de redes neurais. Possui um próprio pipeline de etapas no qual, primeiramente, é definida a arquitetura da rede. Nela, são especificados aspectos como a quantidade de camadas, nós por camada, funções de ativação, dentre outros. Em seguida, o modelo é compilado por meio da função de perda escolhida. O treinamento é a etapa composta pelo ciclo de backpropagation e otimização de pesos e, por último, tem-se a etapa de predição.
2.4.6 Deep learning
Deep learning refere-se a um aprendizado específico inserido em uma sub-área do aprendizado de máquina. Usa redes neurais para lidar com predições supervisionadas e não-supervisionadas (TRASK, 2016). Esse aprendizado se difere dos demais por utilizar múltiplas camadas como forma de aprendizado e, assim, agregar uma informação ainda mais significativa. Essas múltiplas camadas são quase sempre aprendidas por meio de redes neurais, de maneira que a informação passa por diversos filtros sucessivos para, ao fim, servir a alguma utilidade específica. Deep learning utiliza otimizadores (em inglês, optimizers) para implementar backpropagation, permitindo o ajustamento de pesos por meio de feedbacks para diminuir o erro em questão (CHOLLET, 2017).
Ainda de acordo com CHOLLET (2017), deep learning é um conceito antigo que só foi evidenciado no início dos anos 2010 e, desde então, tem quebrado paradigmas em áreas complexas do aprendizado de máquina, como:
a) Classificação de imagens; b) Reconhecimento de fala; c) Transcrição manuscrita;
d) Assistentes digitais, como Amazon Alexa e Google Now; e) Melhorias em buscas na web;
f) Direção autônoma de veículos em níveis quase humanos.
Para desempenhar algumas de suas funções, umas mais que outras, o deep learning faz uso de codificadores e decodificadores. Codificadores são utilizados para mapear dados de entrada de maneira que gerem representações das features, enquanto os decodificadores utilizam essas representações como entrada para processá-las e, por fim, tomar uma decisão e gerar dados de saída. Convolutional neural networks (CNN) e Recurrent neural network (RNN) são redes comumente utilizadas como codificadores e/ou decodificadores. CNNs são geralmente associados a problemas de reconhecimento de imagens e classificação de objetos e RNNs a predições de séries temporais, tradução de máquina, dentre outros.
3 A FERRAMENTA
No decorrer dos últimos anos, observou-se a diversificação do uso de deep learning em serviços de aprendizado de máquina. Por se tratar de uma multinacional que promove comunicação, localização e transações ao redor do mundo, a Uber tem investido cada vez mais nesse cenário. Tendo em mente a democratização do deep learning e se embasando em diversas bibliotecas open-source, disponibilizou ferramentas como o Pyro e Horovod. Seu produto mais recente nesse meio, o Ludwig, é tido como uma caixa de ferramentas de deep learning na qual o usuário dispõe de várias funcionalidades para construir o seu modelo. Quando desenvolvida, foi implementada em cima do Tensorflow.
Com o propósito de servir como uma ferramenta genérica ao lidar com problemas de deep learning de diferentes naturezas, vários outros softwares como Caffe, Scikit-Learn, MLib, etc, serviram como inspiração. Dessa forma, se diferencia de bibliotecas específicas por não estar presa a modelos e arquiteturas. Seus princípios, de acordo com a própria Uber, são:
a) Não exigir habilidades de programação; b) Ser útil em diversos casos de uso;
c) Possibilitar a usuários com experiência possuem total controle dos processos, enquanto novatos terão facilidade no uso;
d) Facilidade em adicionar novas arquiteturas ao modelo bem como novos tipos de feature;
e) Disponibilizar visualizações padronizadas para compreensão dos processos envolvidos em um modelo de deep learning.
3.1 Arquitetura
Composto por codificadores e decodificadores, o Ludwig usa os primeiros para mapear os dados tratados para os tensores e os últimos para mapear tensores para dados não tratados. Os tensores são entendidos como matrizes n-dimensionais de tipos de dados. É permitido aos codificadores e decodificadores suportarem diversos tipos de dados, nos quais cada tipo possui sua respectiva função de pré-processamento. Por essa razão, o Ludwig possui uma extensa arquitetura na qual todas as saídas de seus codificadores são concatenadas por meio de um combinador padrão, o qual as processa por meio de camadas conectadas em que pode aprender combinações não-lineares das mesmas. Depois, os tensores são retornados como entrada para os decodificadores (Figura 14).
Figura 14. Resumo do funcionamento da arquitetura utilizada no Ludwig. Fonte - Adaptado de (https://eng.uber.com/introducing-ludwig/)
3.2 Instalação
O Ludwig requer que os seguintes pacotes estejam instalados: numpy, pandas, scipy, scikit-learn, scikit-image, spacy, tensorflow, matplotlib, seaborn, Cython, h5py, tqdm, tabulate e PyYAML. Por ter sido desenvolvido e testado usando Python 3, sua instalação também é essencial. Pode ser instalado pelo terminal por meio do comando “pip install ludwig” ou pelo código fonte do seu repositório “git clone [email protected]:uber/ludwig.git”. O arquivo requirements.txt possui os pacotes necessários citados anteriormente, incluindo o Tensorflow. Entretanto, não se trata do que permite GPUs (do inglês Graphics Processing Units), sendo necessário substituí-lo por “tensorflow-gpu”.
3.3 Pré-processamento
Para treinar os modelos, é necessário fornecer apenas dois arquivos: um CSV e outro YAML (Ain't Markup Language). Esse último é uma linguagem de marcação rápida, a qual possui sintaxe simples e legível. Enquanto o arquivo CSV contém o dataset, o YAML é escrito pelo próprio usuário e deve, obrigatoriamente, especificar as colunas usadas como features e a(s) coluna(s) target. Os demais campos são
preenchidos a critério do usuário e, caso não sejam especificados, são preenchidos por valores padrão. Por ditar como o modelo de deep learning estará composto, esse arquivo também é referido como arquivo de definição de modelo. Nele, devem ser citados os tipos de cada dado que irá compor o modelo. No momento, o Ludwig suporta formatos de dados binários, numéricos, categóricos, imagem, texto, série temporal, dentre outros.
Esse arquivo pode ser preenchido em um editor de texto e declarado via terminal por meio do parâmetro “--model_definition_file model_definition.yaml”, no qual
“--model_definition_file” declara que será usado um arquivo contendo as instruções para o modelo e “model_definition.yaml” refere-se ao nome do arquivo com extensão .yaml, bem como à pasta em que o mesmo se encontra.
Além disso, é possível escrever toda a informação contida no arquivo em uma só linha via terminal. Nesse caso, o comando possui o seguinte formato: “--model_definition "{input_features: [{name: doc_text, type: text}], output_features: [{name: class, type: category}]}", em que “--model_definition” especifica que o modelo será descrito não por meio de um arquivo e sim no próprio terminal. Features e targets devem ser declarados por meio de informações como nome e tipo, contidas em “name” e “type”, respectivamente. O nome precisa ser idêntico ao do arquivo CSV, caso contrário será retornado um erro. As features podem ser codificadas de diferentes maneiras por meio da especificação do parâmetro “encoder”, onde cada codificador possui diferentes parâmetros. As features de saída (ou targets) possuem decodificadores declarados por meio do parâmetro “decoders” os quais, por sua vez, possuem o parâmetro “loss”. Esse parâmetro determina funções de perda relativas ao tipo da feature, como por exemplo “mean_squared_error” para o tipo numérico.
A definição de modelo oferece uma sessão só para treinamento na qual oferece diversos parâmetros desse processo. Todos eles possuem valores padrão caso não sejam especificados. Entretanto, são essenciais tanto para que usuários experientes tirem melhor proveito de seus modelos quanto para iniciantes colocarem em prática e entenderem diferentes métodos sem a dificuldade de implementá-los. Dentre os parâmetros, estão learning_rate, batch_size, early_stop, epochs, dentre outros.
Assim como no treinamento, existe uma sessão para pré-processamento de dados composta por importantes parâmetros relativos à maneira na qual os dados são particionados. Por meio de parâmetros como “split_probabilities”, é possível
especificar a proporção do dataset CSV que será treinado, validado e testado. Se não especificado, 0.7 do dataset é treinado, 0.1 validado e 0.2 testado. “force_split” por sua vez força o dataset a ser particionado randomicamente, enquanto “stratify” permite que uma feature seja selecionada para classificação de seus dados. A depender do tipo da feature, diferentes parâmetros de pré-processamento podem ser aplicados tais como estratégias para lidar com missing values, normalização, dentre outros.
3.4 Train
O Ludwig possui seis comandos principais que podem ser especificados via terminal: train, predict, test, experiment, visualize, collect_weights e collect_activations. Para treinamento, deve ser fornecido o comando “ludwig train”.
Para ser efetuado, o treinamento precisa apenas que sejam especificados o modelo de definição (via arquivo ou terminal) e o dataset. Esse último pode ser declarado através dos seguintes argumentos na Tabela 2:
Tabela 2. Argumentos para datasets
Fonte - Adaptado de (https://eng.uber.com/introducing-ludwig/)
Ao fim do treinamento, é gerado um arquivo HDF516 e outro JSON17. O primeiro contém os dados mapeados para ndarrays numpy enquanto o segundo contém os mapeamentos dos valores dos tensores até seus rótulos originais. Esses arquivos são gerados com o intuito de economizar tempo pois, caso o usuário deseje repetir o treinamento, o Ludwig tentará lê-los ao invés de computar mais uma vez todos os
16 https://www.hdfgroup.org/solutions/hdf5/ 17 https://www.json.org/json-pt.html
tensores. Se for feita uma predição após o treinamento, é preciso que os dados estejam identicamente mapeados, sendo necessário o arquivo JSON.
Além dos dois arquivos, é gerada uma pasta de nome padrão “results”. Nela, uma outra pasta de nome “[experiment_name]_[model_name]_0” é criada caso o nome do modelo e do experimento sejam especificados. Se não especificados, a pasta será intitulada “experiment_run_0” e irá conter:
a) description.json: arquivo que contém descrições do processo de treinamento, com informações para reproduzi-lo.
b) training_statistics.json: contém registros de todas as medidas e perdas para cada epoch.
c) model: diretório contendo pesos, checkpoints, hiperparâmetros e logs.
Se empregadas, as GPUs envolvidas no processo podem ser gerenciadas por meio dos argumentos --gpus e --gpu_fraction, os quais as especificam em uma lista de inteiros separados por vírgula e a fração de memória a ser utilizada, respectivamente. O treinamento é realizado atendendo a comandos como:
$ ludwig train --data_csv train.csv --model_definition_file modelo.yaml
3.5 Predict
Por meio do comando “predict”, o Ludwig fará uso do modelo previamente treinado para prever novos dados. Como precisa do modelo usado para o treinamento, é necessário usar o argumento “--model_path” seguido por sua localização e nome. Por meio do argumento “--output-directory” é possível determinar o local contendo os dados da predição. Caso não especificado, o diretório se chamará “result_0” e irá conter um arquivo CSV de predição e outro de probabilidade para cada feature de saída, assim como arquivos NPY. Se o argumento “--evaluate_performance” for utilizado, um arquivo “predict_statistics.json” contendo todas estatísticas das predições será emitido. Para acelerar a predição, o tamanho do batch pode ser especificado por meio do parâmetro “--batch_size”.
$ ludwig predict --data_csv data.csv --model_path results/experiment_run_0/model/
3.6 Test
O comando de teste opera de maneira muito similar ao de predição: usa um modelo previamente treinado para que possa prever novos dados e assim validá-los de acordo com o resultado verdadeiro. Os parâmetros são idênticos aos de predição, de maneira que a única diferença entre os comandos seja de que o teste, por comparar suas predições com resultados verdadeiros, exige que o dataset contenha colunas com o mesmo nome que as features de saída. Quando efetuado, os resultados dessa comparação são colocados no arquivo “test_statistics.json” gerado.
O teste é realizado atendendo a comandos como:
$ ludwig test --data_csv data.csv --model_path results/experiment_run_0/model/
3.7 Experiment
O comando experiment possui finalidade prática, visto que combina treinamento e teste em um só comando. Seus parâmetros correspondem aos dos outros dois, assim como as saídas geradas pelo comando.
O experiment é realizado por meio de comandos como:
$ ludwig experiment --data_csv data.csv --model_definition_file modelo.yaml
3.8 Visualize
O comando “visualize” permite ao usuário analisar visualmente os resultados estatísticos de treinamento e predição obtidos, além de possibilitar comparação entre diferentes modelos. Existem diversos tipos de visualização que podem ser obtidos, cada um por meio de parâmetros específicos. Dentre alguns, estão as matrizes de confusão, curvas ROC e curvas de aprendizado.
4 RESULTADOS
Nessa etapa do trabalho, foram explorados através do Ludwig três problemas distintos: Sobreviventes do Titanic, Classificação de Sentimentos e Avaliações de Filmes.
4.1 Titanic: Machine Learning from Disaster
Três datasets são disponibilizados pelo Kaggle: train.csv, test.csv e gender_submission.csv. O arquivo test.csv dispõe dessas mesmas features, com exceção do target “Survived”, sendo assim usado para prever os sobreviventes.
A estratégia adotada foi, primeiramente, definir os comandos que seriam usados para obtenção das predições. Considerando que o arquivo train.csv contém todas as features utilizadas no modelo, optou-se por submetê-lo à etapa de treinamento por meio do comando “train”. Após treinadas todas as features, seria feita a predição por meio de dados ainda não analisados do dataset test.csv, por meio do comando “predict”. Definidos os passos, precisou-se especificar o modelo utilizado através do arquivo YAML. Por intuição, as features “Name”, “Ticket” e “PassengerId” serão descartadas, visto que não fornecem dados relevantes para o modelo. Além delas, “Cabin” também é descartada do arquivo YAML por possuir muitos missing values (Figura 15).
Figura 15. Primeira tentativa realizada. Fonte - Elaborada pelo autor
O treinamento se deu pelo comando:
$ ludwig train --data_csv train.csv --model_definition_file modelo.yaml (Figura 16)
Figura 16. Resultado do treinamento do modelo n°1 do dataset Titanic. Fonte - Elaborada pelo autor
Foi utilizado um total de 100 epochs, número esse correspondente ao valor padrão definido. Para cada epoch, é exibida uma tabela contendo valores de erro e acurácia para as etapas de treinamento, validação e teste. O Ludwig informou ao fim do treinamento os melhores valores da função de perda na combinação dos conjuntos de validação e teste: 1.2086 e 1.2708 respectivamente. Todos os dados referentes ao modelo treinado foram guardados no diretório results/experiment_run_0, como especificado.
Terminado o treinamento, é necessário prever os dados os dados do dataset test.csv, os quais não são conhecidos pelo modelo. O diretório contendo o modelo usado no treinamento é referenciado por meio do argumento --model_path no seguinte comando:
$ ludwig predict --data_csv test.csv --model_path results/experiment_run_0/model/
Os arquivos contendo as previsões e probabilidades de sobreviventes são gerados e armazenados em um diretório específico. Esse modelo especificamente obteve um score de 0.64593. Um outro modelo foi testado por meio de um diferente arquivo YAML. Esse, por sua vez, se diferencia do primeiramente utilizado apenas pela especificação do seu combinador (Figura 17), gerando mudanças no treinamento (Figura 18).
Figura 17. Tentativa n°2 realizada no dataset do Titanic Fonte - Elaborada pelo autor
Figura 18. Resultado do treinamento do modelo n°2 do dataset Titanic. Fonte - Elaborada pelo autor
Esse modelo por si só reflete a praticidade e funcionalidade do Ludwig, tendo em vista a significativa mudança gerada por meio da adição de poucas linhas no arquivo YAML. Essa mudança pode ser verificada na tabela de scores obtida no Kaggle (Figura 19).
Figura 19. Tabela de scores fornecida pelo Kaggle. Fonte - (Kaggle.com)
A título de demonstração, foi obtida a visualização da curva de aprendizado do modelo, atendendo ao comando:
$ ludwig visualize --visualization learning_curves --training_statistics results/experiment_run_0/training_statistics.json
As curvas de aprendizado ilustram o comportamento observado em cada epoch no terminal: a diminuição do erro e o aumento da acurácia em função do aumento de epochs. Foram plotadas curvas de aprendizado relativas às etapas de treinamento e validação (Figuras 20 A e B).
Figura 20. Curvas de aprendizado. A) Curva de aprendizado da função de perda. B) Curva de aprendizado da acurácia
Fonte - Elaborada pelo autor
4.2 TMDB 5000 Movie Dataset
A segunda abordagem utilizada para testar o Ludwig se deu por meio do dataset obtido do The Movie Database (TMDB), disponível no Kaggle. Foi disponibilizado um único arquivo CSV, de nome tmdb_5000_movies.csv, o qual contém 4803 filmes e 20 colunas, como descrito na Tabela 3.
Tabela 3. Descrição das colunas do dataset TMDB. Fonte: elaborada pelo autor
Por conter apenas um arquivo CSV, não se faz necessário utilizar dois comandos distintos, como feito com o problema do Titanic. Nesse caso, apenas o treinamento é suficiente, visto que ao fim de cada epoch o modelo é usado para fazer predições nos conjuntos de validação e teste. Se utilizado, o comando experiment geraria um arquivo test_statistic.json que pode ser utilizado para obter algumas das visualizações disponíveis. Entretanto, nesse caso em especial o comando não teria muita utilidade, pois a feature de saída é do tipo numérico, o qual não possui visualizações. A predição realizada, diferente da obtida por meio do comando predict, possui um valor com o qual irá comparar a fim de medir seus acertos. Objetiva-se prever a nota de cada filme representada pela feature “vote_average”, que consiste na média das votações para o mesmo. Para que o modelo possuísse features que contribuíssem para o seu desempenho, foram selecionadas intuitivamente as seguintes features: “genres”, “popularity”, “tagline” e “production_companies” para o arquivo YAML (Figura 21).
Figura 21. Tentativa n°1 realizada no dataset TMDB. Fonte - Elaborada pelo autor
Realizado o treinamento:
$ ludwig train --data_csv tmdb_5000_movies.csv --model_definition_file model.yaml (Figura 22)
Figura 22.Resultado do treinamento do modelo n°1 do dataset TMDB. Fonte - Elaborada pelo autor
Na tentativa de melhorar os valores acima, foi feito um outro arquivo YAML (Figura 23).
Figura 23. Tentativa n°2 realizada no dataset de TMDB. Fonte: elaborada pelo autor
O modelo apresentou melhoras significativas em seu desempenho através do novo arquivo YAML (Figura 24).
Figura 24. Resultado do treinamento do modelo n°2 do dataset de TMDB. Fonte - Elaborada pelo autor
4.3 Sentiment Analysis
Para o último cenário de teste do Ludwig, foi considerado um dataset composto por análises feitas por clientes, retirado do Github do usuário Nathan Fritter18. Esse dataset, formado por apenas um arquivo CSV, não possuía nomes definidos para suas colunas, sendo assim nomeadas:
a) Review: Análise em questão;
b) Classification: Valores indicativos de sentimento da análise, classificados em Positive ou Negative.
Foi gerado o primeiro arquivo YAML para o modelo (Figura 25).
Figura 25. Tentativa n°1 realizada no dataset de análise de sentimentos. Fonte - Elaborada pelo autor
O comando ludwig experiment foi utilizado, de maneira a obter a seguinte saída (Figura 26) do terminal:
$ ludwig experiment --data_csv Amazon_reviews.csv --model_definition_file model.yaml
Figura 26. Resultado do treinamento do modelo n°1 do dataset de análise de sentimentos. Fonte - Elaborada pelo autor
O modelo não completou o número padrão de epochs devido ao fato de não serem registradas melhorias na acurácia da etapa de validação. Assim, passadas 5 epochs sem observar tais melhorias, o Ludwig completou apenas 15 epochs. O Ludwig informou ao fim do treinamento os melhores valores da função de perda na combinação dos conjuntos de validação e teste: 0.3451 e 0.4788 respectivamente. Todos os dados referentes ao modelo treinado foram guardados no diretório results/experimente_run_0, como especificado.
Foi testado um diferente modelo (Figura 27), o qual resultou em um novo treinamento (Figura 28).
Figura 27. Tentativa n°2 realizada no dataset de análise de sentimentos. Fonte - Elaborada pelo autor
Figura 28. Resultado do treinamento do modelo n°2 do dataset de análise de sentimentos. Fonte - Elaborada pelo autor
Percebeu-se que, com a alteração do codificador da feature Review de parallel_cnn para rnn, o modelo resultante piorou seu desempenho. Houve uma diminuição da acurácia bem como um aumento na função de perda em diferentes etapas do processo. Em se tratando de features de saída do tipo categóricas, o Ludwig permite visualizar diferentes modelos a fim de observar seus desempenhos. As seguintes visualizações foram obtidas por meio do comando:
$ ludwig visualize --visualization compare_performance --test_statistics result s/experiment_run_0/test_statistics.json results/experiment_run_4/test_statistics.json
(Figuras 29 e 30).
Figura 29. Comparação de performance em diferentes modelos de classificação. Fonte - Elaborada pelo autor
Figura 30. Comparação de acurácia em diferentes modelos de classificação. Fonte - Elaborada pelo autor
Dentre as opções de visualização permitidas, é possível plotar uma curva ROC (do inglês receiver operating characteristic curve) de um modelo que, por sua vez, deve ter feature de saída do tipo binária. Essa curva é utilizada para medir o desempenho do modelo quanto à sua capacidade de distinguir entre os dois valores binários. Além disso, é necessário que seja utilizado o arquivo test_statistics.json, gerado apenas em situações nas quais as predições possuem um valor verdadeiro para compararem. Por esse motivo, não foi possível utilizar o modelo Titanic e optou-se por transformar os valores da coluna Classification do dataoptou-set de análioptou-se de sentimentos em valores binários. Sendo assim, após feita a transformação, foi necessário modificar apenas o type dessa feature no arquivo YAML. Após repetir o procedimento ludwig experiment com o novo dataset e novo modelo, o arquivo test_statistics.json foi gerado e a seguinte plotagem (Figura 31) foi obtida pelo comando:
$ ludwig visualize --visualization roc_curves_from_test_statistics --test
Figura 31. Curva ROC. Fonte - Elaborada pelo autor
5 CONCLUSÃO
Com base nos exemplos em que foi testada, a ferramenta Ludwig cumpriu com eficácia o que propõe. Observou-se que foi possível não apenas criar modelos de deep learning como também customizá-los e melhorá-los. Sua estrutura fornece diversos parâmetros pelos quais usuários inexperientes podem testar diferentes estratégias e combinações, de forma que vários conceitos sejam fixados com o tempo.
Entretanto, é importante frisar que se trata de uma ferramenta ainda em desenvolvimento. Durante o decorrer deste trabalho, o Ludwig passou por atualizações e alguns comandos tornaram-se obsoletos, enquanto outros outrora executados passaram a apresentar erros quando utilizados. Sua página no Github foi essencial para que seu desenvolvedor esclarecesse dúvidas e realizasse eventuais ajustes e melhorias solicitadas por usuários. No entanto, a constância desses procedimentos pode vir a impedir que usuários sem experiência usufruam da ferramenta sem potenciais imprevistos.
No website do Ludwig, as diferentes formas de gerar visualizações não se encontram bem documentadas e explicadas. Além disso, são geradas de maneira genérica e pouco customizável. Alguns parâmetros também geram ambiguidade e confusão pela falta de exemplos de uso. Usuários sem qualquer experiência com
programação podem se deparar com alguns imprevistos, a exemplo de datasets que precisem ser organizados antes de iniciar os trabalhos com a ferramenta. Embora cumpra com seu propósito de não exigir habilidades de programação, o Ludwig ainda necessita de aprimoramentos para se tornar de fato atrativo a novos usuários.
6 REFERÊNCIAS
Aggarwal, C. C. (2018). Neural Networks and Deep Learning: A Textbook. 1-497. MA: Springer.
Fritter, N. Sentiment Analysis on Presidential Candidates for election year 2016. Disponível em<https://github.com/njfritter/sentimentAnalysis_presCandidates USA2016/tree/master/sentimentLabelledSentences>Acesso em 1 de junho de 2019.
Géron, A. (2017). Hands-On Machine Learning with Scikit-Learn and TensorFlow. 1-600. California: O’Reilly Media, Inc.
Grus, J. (2015). Data Science From Scratch. 1 ed. 1-330. California: O’Reilly Media, Inc.
Han, J.; Pei, J.; Kamber, M. (2011). Data Mining: Concepts and Techniques. 3 ed. 1-744. MA: Morgan Kaufmann Publishers.
Kaggle. Titanic: Machine Learning from Disaster. 2012. Disponível em <https://www.kaggle.com/c/titanic/data>. Acesso em 24 de março de 2019. Kriegeskorte, N. & Golan, T. (2019). Neural Network Models and Deep Learning – a
Primer for Biologists. Current Biology. 29, 231-236.
O’ Haykin, S. (2009). Neural Networks and Learning Machines. 3 ed. 1-936. McMaster University: Pearson.
O’neil, C. & Schutt, R. (2013). Doing Data Science Straight Talk from the Frontline. 1-375. California: O’Reilly Media, Inc.
Russom, P. (2007). BI Search and Text Analytics. TDWI Best Practices Report. TMDb - The Movie Database. TMDB 5000 Movie Dataset. 2017. Disponível em
<https://www.kaggle.com/tmdb/tmdb-movie-metadata>. Acesso em 25 de maio de 2019.
Trask, A. W. (2016). Grokking Deep Learning. 1-542. New York: Manning Publications.
Uber Technologies Inc., Ludwig. 2019. Disponível em <https://uber.github.io/ludwig/>. Acesso em 01 de março de 2019.
VanderPlass, J. (2016). Python Data Science Handbook. 1 ed. 1-548. California: O’Reilly Media, Inc.
Yoshiyama, K. & Sakurai, A. (2018). Semi-Supervised Learning with Uncertainty. Transactions of the Japanese Society for Artificial Intelligence. 33.
Zheng, A. & Casari, A. (2018). Feature Engineering for Machine Learning. 1 ed. 1-218. California: O’Reilly Media, Inc.