Baixe o app para aproveitar ainda mais
Prévia do material em texto
1 2 Sumário Unidade 1: Introdução – Inteligência Artificial ................................................................................ 5 1.1 Considerações Iniciais ....................................................................................................... 5 1.2 Introdução: O que é Inteligência Artificial? ...................................................................... 5 1.3 Ramos da Inteligência Artificial ......................................................................................... 6 1.4 Aprendizagem de Máquina (AM) ...................................................................................... 8 1.4.1 Aprendizagem Supervisionada .................................................................................. 9 1.4.2 Aprendizagem não Supervisionada ........................................................................ 10 1.4.3 Aprendizagem por Reforço ...................................................................................... 11 1.5 Roteiro ............................................................................................................................... 12 1.5.1 Pré-requisitos ............................................................................................................ 12 1.5.2 Assuntos abordados no módulo .............................................................................. 13 1.5.3 Recursos usados no módulo ................................................................................... 14 1.5.4 Ambiente de programação em Python: Spyder ..................................................... 14 1.6 Considerações Finais ...................................................................................................... 15 Unidade 2: Aprendizagem Supervisionada – Classificação e Regressão......................................... 16 2.1 Considerações Iniciais ..................................................................................................... 16 2.2 O que é classificação? .................................................................................................... 16 2.3 Avaliação da qualidade dos classificadores: Matriz de confusão ............................... 17 2.4 Classificação pelo método estatístico Naïve Bayes ..................................................... 19 2.5 O que é regressão? ......................................................................................................... 21 2.6 Regressão linear simples ................................................................................................ 21 2.7 Regressão múltipla .......................................................................................................... 23 2.8 Considerações Finais ...................................................................................................... 25 Unidade 3: Aprendizagem não supervisionada ........................................................................... 26 3.1 Considerações Iniciais ..................................................................................................... 26 3.2 Clusterização de dados com o algoritmo K-Means ...................................................... 26 3.3 Estimando o número de clusters com o algoritmo Mean Shift .................................... 29 3.4 Estimando a qualidade dos clusters com o conceito de silhouette scores ................ 31 3.5 Modelo de propagação por afinidade............................................................................. 33 3.6 Uso da clusterização para segmentar dados referentes a compra............................. 35 3.7 Considerações Finais ...................................................................................................... 36 Unidade 4: Redes Neurais ............................................................................................................. 37 4.1 Considerações Iniciais ..................................................................................................... 37 4.2 Conceitos básicos sobre redes neurais ......................................................................... 37 4.3 Construção de um classificador baseado em Perceptron ........................................... 38 4.4 Construção de uma rede neural de uma camada ........................................................ 40 4.5 Construção de uma rede neural multi-camadas ........................................................... 42 4.6 Redes Neurais Recorrentes ............................................................................................ 45 4.7 Considerações Finais ...................................................................................................... 48 Unidade 5: Algoritmos Genéticos e Programação Genética .......................................................... 49 5.1 Considerações Iniciais ..................................................................................................... 49 5.2 Algoritmos evolutivos e genéticos .................................................................................. 49 5.3 Conceitos fundamentais em algoritmos genéticos ....................................................... 50 5.4 Geração de um padrão de bits com parâmetros predefinidos..................................... 51 5.5 Visualizando a evolução .................................................................................................. 53 5.6 Construindo um controlador de robô inteligente ........................................................... 57 5.7 Considerações Finais ...................................................................................................... 61 3 Referências ................................................................................................................................... 62 4 Apresentação Prezado aluno, é uma grande satisfação contar com você para este módulo da especialização em que trataremos da introdução sobre os principais tópicos da área de Inteligência Artificial. Meu nome é Rogério Ferreira, sou professor da área de Ciência da Computação há dez anos. Sou Bacharel em Informática pela Universidade Estadual de Maringá (UEM), Mestre em Ciência da Computação (UEM) na área de Engenharia de Software, com ênfase na em Arquitetura de Linha de Produto para Sistemas Embarcados, mais precisamente Veículos Aéreos Não Tripulados (VANTs), e atualmente sou doutorando em Ciência da Computação e Matemática Computacional pela Universidade de São Paulo (USP), com tese na área de Learning Analytics, uma área que usa técnicas de inteligência artificial para analisar dados relacionados à educação. Aos longo dos próximos capítulos, vamos aprender o que é Inteligência Artificial e suas principais áreas, como a Aprendizagem de Máquina e o Reconhecimento de Padrões, a IA baseada em Lógica, as Técnicas de Pesquisa, a Representação do conhecimento, técnicas baseadas em Planejamento e Heurísticas. Ao longo do módulo, iremos priorizar as técnicas de Aprendizagem de Máquina, pois estas são as mais utilizadas atualmente por desenvolvedores para criar aplicações que podem aprender com base nos dados e experiência dos usuários. Você estudará exemplos práticos envolvendo técnicas de classificação supervisionadas, análise de regressão linear, algoritmos de clusterização, redes neurais artificiais e também algoritmos genéticos. Inteligência Artificial é um tema fascinante! Vai ser um prazer tê-lo conosco nos próximos capítulos, para aprender mais sobre este assunto. 5 Unidade 1: Introdução – Inteligência Artificial 1.1 Considerações Iniciais Neste primeiro capítulo, além de introduzir brevemente o que é e qual a importância da Inteligência Artificial, vamos iniciar os estudos sobre os conceitos fundamentais dessa área fascinante. A Inteligência Artificial tem desempenhado papelsignificativo na construção de sistemas que podem “aprender” com base nos dados e na experiência do usuário. Nas últimas décadas ela tem sido usada para construir aplicações que revolucionaram a forma como interagimos com o mundo, como os assistentes pessoais digitais (Amazon Alexa, Apple Siri e Microsoft Cortana). Este primeiro capítulo está estruturado da seguinte forma: na Seção 1.2 vamos introduzir o que é Inteligência Artificial (IA); na Seção 1.3 estudaremos os principais ramos da IA; na Seção 1.4 você conhecerá o conceito de Aprendizagem de Máquina, a sub-área da IA mais utilizada pelos desenvolvedores atualmente; na Seção 1.5 vamos apresentar o roteiro deste módulo, ou seja, quais assuntos serão estudados na sequência deste capítulo e nos capítulos seguintes; por fim, a Seção 1.6 faz as considerações finais do capítulo. 1.2 Introdução: O que é Inteligência Artificial? Nesta seção, discutiremos o conceito de inteligência artificial (IA) e como ela é aplicada no mundo real. Nós passamos uma parte significativa da nossa vida interagindo com sistemas inteligentes, seja ao pesquisar algo na internet, ao usar um sistema de reconhecimento facial biométrico ou converter palavras faladas em texto. A IA possui um papel central nessas atividades e está se tornando uma parte importante do nosso estilo de vida moderno. Todos esses sistemas são aplicações complexas do mundo real e a IA resolve esses problemas por meio de matemática e o uso de algoritmos. Ao longo deste capítulo, aprenderemos os princípios fundamentais que podem ser usados para criar essas aplicações. O objetivo é permitir que você aprenda a lidar com os problemas de IA que você pode encontrar no seu cotidiano. Primeiramente, precisamos definir os temos Inteligência e Artificial, o que não é uma tarefa fácil. Uma definição ampla e otimista do campo da IA poderia ser: "a área da ciência da computação que estuda como as máquinas podem executar tarefas que normalmente exigiriam um agente sensível" (ARTASANCHEZ & JOSHI, 2020). Com base nesta definição, pode-se argumentar que algo tão simples quanto um computador multiplicando dois números é "inteligência artificial". Isso ocorre porque projetamos uma máquina capaz de receber uma entrada e produzir independentemente uma saída lógica que normalmente exigiria o processamento de uma entidade viva. Uma definição mais cética seria: "a área da ciência da computação que estuda como as máquinas podem imitar de perto a inteligência humana". A partir dessa definição, os céticos podem argumentar que o que temos hoje não é inteligência artificial. Até agora, eles conseguiram apontar exemplos de tarefas que os computadores não podem executar e, portanto, afirmam que os computadores ainda não podem "pensar" ou exibir inteligência artificial se não puderem executar satisfatoriamente tais tarefas. Este capítulo oferece uma visão mais otimista da IA, portanto, nos inclinamos a observar as atividades complexas que um computador pode executar atualmente por meio das técnicas de IA. Na tarefa de multiplicação mencionada anteriormente, um computador certamente será mais rápido e preciso que um humano se os dois números forem suficientemente grandes. Existem outras áreas em que os humanos podem ter um desempenho muito melhor que os computadores. Por exemplo, um humano pode reconhecer, rotular e classificar objetos com 6 alguns exemplos, enquanto atualmente um computador pode exigir milhares de exemplos para executar essa tarefa com o mesmo nível de precisão. A pesquisa e a melhoria continuam incansavelmente, e continuaremos vendo os computadores resolvendo cada vez mais problemas que apenas alguns anos atrás eles não poderiam solucionar. Quando comparada a outras áreas da ciência, como a matemática ou a física, que existem há séculos, a IA é relativamente nova. Nas últimas duas décadas, ela produziu alguns resultados incríveis, como carros autônomos e robôs inteligentes que caminham por outros planetas. Com base na direção em que estamos seguindo, é óbvio que a a implementação de sistemas inteligentes terá um grande impacto em nossas vidas nos próximos anos. Não podemos deixar de imaginar como o cérebro humano consegue fazer inúmeras tarefas com relativa facilidade. Com nosso cérebro, podemos reconhecer objetos, entender diferentes idiomas, aprender coisas novas e executar muitas tarefas mais sofisticadas. Como o cérebro humano faz isso? Ainda não temos muitas respostas para essa pergunta. Se você tentar replicar tarefas que o cérebro executa usando uma máquina, perceberá o quanto ela fica para trás! Nosso cérebro é muito mais complexo que as máquinas, em muitos aspectos. Nesse contexto, a “vantagem” da IA é que já existe um modelo idealizado de inteligência: o cérebro humano. Assim, tudo o que precisamos fazer é imitar sua funcionalidade para criar um sistema inteligente que possa fazer algo semelhante, ou até mesmo melhor que o cérebro. Observe a Figura 1.1 que mostra como os dados brutos são convertidos em inteligência por meio de vários níveis de processamento: Figura 1.1 – Conversão de dados em inteligência (ARTASANCHEZ & JOSHI, 2020) Uma das principais razões para se estudar IA é a necessidade de automatizar muitas coisas. Embora o cérebro humano seja muito bom em analisar o mundo ao nosso redor, ele não consegue acompanhar o histórico das condições anteriores. Portanto, precisamos projetar e desenvolver máquinas inteligentes que possam fazer isso. Precisamos criar sistemas de IA que possam: • manipular grandes quantidades de dados de maneira eficiente, considerando que atualmente podemos armazenar grandes quantidades de dados com o advento da computação em nuvem; • processar dados de várias fontes simultaneamente, permitindo indexar e organizar dados de uma maneira que nos permita obter insights; • aprender com novos dados e atualizá-los constantemente usando os algoritmos de aprendizagem mais eficientes para cada contexto; • executar as tarefas anteriores constantemente, sem a necessidade de realizar pausas. As técnicas de IA estão sendo cada vez mais usadas para tornar as máquinas mais inteligentes, e permitir que elas possam executar tarefas com mais rapidez e eficiência. 1.3 Ramos da Inteligência Artificial É importante entender que IA é uma área bastante extensa, e é fundamental conhecer os seus vários campos de estudo para que possamos escolher a técnica mais adequada para resolver um determinado problema do mundo real. Existem várias maneiras de classificar os 7 diferentes ramos da IA. A classificação apresentada a seguir descreve os ramos da IA sugeridos por ARTASANCHEZ & JOSHI (2020). Aprendizagem de Máquina e Reconhecimento de Padrões: esta talvez seja a área mais popular da IA. Na aprendizagem de máquina projetamos e desenvolvemos sistemas que podem aprender com os dados fornecidos a eles, por meio de uma espécie de modelo estatístico. Com base nesses modelos, o sistema realiza previsões com dados desconhecidos. Uma das principais restrições dessa técnica é que esses sistemas são limitados ao poder dos dados fornecidos a eles. Se o conjunto de dados for pequeno, os modelos de aprendizagem também serão limitados. Observe na Figura 1.2 como é o esquema simplificado de um sistema típico baseado em aprendizagem de máquina. Figura 1.2 – Sistema baseado em aprendizagem de máquina (ARTASANCHEZ & JOSHI, 2020) Quando um sistema recebe um conjunto de dados desconhecido, ele usa os padrões dos dados analisados anteriormente para fazer inferências sobre esse novo conjunto de dados. Por exemplo, em um sistema de reconhecimento facial, o software tentará corresponder ao padrão de olhos, nariz, lábios, sobrancelhas, etc. para encontrar um rosto existente no banco de dados de usuários. IA baseada em Lógica: neste ramo, a lógica matemática é usada para criarprogramas de computador. Um sistema criado na IA baseada em lógica é um conjunto de instruções em forma lógica que expressa fatos e regras sobre um domínio de problema. Essa técnica é antiga e não tem sido usada extensivamente em sistemas que realizam reconhecimento de padrões, análise de idiomas, análise semântica e assim por diante. Técnicas de Pesquisa: são amplamente utilizadas em sistemas de IA que analisam muitas possibilidades e, em seguida, escolhem o caminho mais ideal. Por exemplo, essa técnica é muito usada em jogos de estratégia, como xadrez, redes, alocação de recursos, programação e assim por diante. Representação do conhecimento: os fatos sobre o mundo ao nosso redor precisam ser representados de alguma maneira para que um sistema possa compreendê-los. As linguagens da lógica matemática são frequentemente usadas nesse contexto. Se o conhecimento é representado de forma eficiente, os sistemas podem se beneficiar desta eficiência para executar tarefas mais inteligentes. A ontologia é conceito estreitamente relacionado com esta área, pois define as propriedades e os relacionamentos das entidades existentes em um determinado 8 domínio. Isso geralmente pode ser feito por meio de uma taxonomia ou outro tipo de estrutura hierárquica. Planejamento: essa área lida com o planejamento ideal que pode fornecer o máximo de recursos com custos mínimos. Esses sistemas se baseiam em dados sobre uma determinada situação e a definição de uma meta. A partir dessas informações, eles tentar gerar o plano mais adequado para atingir a meta. Heurísticas: uma heurística é uma técnica usada para resolver um determinado problema de forma prática e a curto prazo, sem necessariamente atingir a solução ótima. Pode ser considerado mais um palpite sobre qual abordagem devemos adotar para resolver um problema. Na IA, frequentemente encontramos situações em que não podemos verificar todas as possibilidades existentes para escolher a melhor opção. Portanto, precisamos usar heurísticas para atingir a meta. Elas são usadas extensivamente na IA em campos como robótica e mecanismos de pesquisa. 1.4 Aprendizagem de Máquina (AM) Uma das primeiras aplicações de AM que tornou-se verdadeiramente popular, que melhorou a vida de centenas de milhões de pessoas e conquistou o mundo nos anos 1990 foi o filtro de spam. Essa técnica foi seguida por centenas outros sistemas de AM que fornecem silenciosamente centenas de produtos e recursos que você usa regularmente, desde sistemas de recomendação até pesquisa por voz. Uma dúvida recorrente é onde a Aprendizagem de Máquina começa e onde termina? O que exatamente significa para uma máquina aprender alguma coisa? Se eu baixar uma cópia da Wikipedia, meu computador irá aprender alguma coisa? Nesta Seção, começaremos a esclarecer o que é AM e por que você pode querer usá-la. Aprendizagem de Máquina é a ciência (ou a arte) de criar sistemas que podem aprender com base em um conjunto de dados. Uma definição mais generalista descreve AM como “o campo de estudos que fornece aos computadores a habilidade de aprender sem serem explicitamente programados” (ARTASANCHEZ & JOSHI, 2020). O filtro de spam usado na caixa de entrada do seu e-mail é um programa de aprendizagem de máquina que, com base em inúmeros exemplos de e-mails de spam sinalizados por usuários, e exemplos de e-mails regulares (que não são spam), podem aprender a sinalizar um spam. Os exemplos que o sistema usa para aprender são chamados de conjunto de treinamento. Cada exemplo do conjunto de treinamento é chamado de instância (ou amostra) de treinamento, e a tarefa do filtro é sinalizar spam para novos e-mails com base na experiência anterior. Existem vários tipos diferentes de sistemas de AM, portanto, é útil classificá-los em categorias mais generalistas, com base em alguns critérios (GERON, 2019): • se eles são ou não treinados com supervisão humana (supervisionada, não supervisionada e semi-supervisionada ou aprendizado por reforço); • se eles podem ou não aprender dinamicamente de forma incremental (aprendizagem online versus aprendizagem em lote); • se eles funcionam simplesmente comparando novos conjuntos de dados com conjuntos de dados conhecidos, ou detectando padrões nos dados de treinamento e construindo um modelo preditivo (aprendizagem baseada em instância versus aprendizagem baseada em modelo) Esses critérios não são exclusivos; você pode combiná-los da maneira que quiser. Por exemplo, um filtro de spam de última geração pode aprender em tempo real usando um modelo de redes neurais treinado com um conjunto de dados contendo exemplos de spam; isso o torna 9 um sistema de aprendizagem online, baseado em um modelo supervisionado. As subseções a seguir descrevem alguns dos principais tipos de aprendizagem de máquina. 1.4.1 Aprendizagem Supervisionada Os sistemas de aprendizagem de máquina podem ser classificados de acordo com a quantidade e o tipo de supervisão que recebem durante o treinamento. Existem três categorias principais: aprendizagem supervisionada, aprendizagem não supervisionada, e aprendizagem semi-supervisionada ou por reforço. Na aprendizagem supervisionada, os dados de treinamento que você utiliza para o algoritmo incluem um atributo especial que classifica cada instância do conjunto de dados, chamado de classe ou rótulo. Uma atividade típica da aprendizagem supervisionada é a classificação. O filtro de spam é um bom exemplo disso: ele é treinado com muitos e-mails de exemplo, e cada um deles possui a sua classe (spam ou não-spam), e o sistema precisa aprender a classificar novos e-mails com base no conjunto de treinamento, como é mostrado na Figura 1.3. Figura 1.3 – Exemplo de aprendizagem supervisionada: conjunto de dados rotulados para classificação de spam (GERON, 2019) Outra tarefa típica da aprendizagem supervisionada é prever um valor numérico, como o preço de um carro, dado um conjunto de atributos (quilometragem, idade, marca, etc.) chamados preditores. Esse tipo de aprendizagem supervisionada é chamada de regressão. Para treinar o sistema, você precisa de um conjunto de dados com muitos exemplos de carros, incluindo os preditores e o seu rótulo, que neste caso será o preço do carro. Um exemplo genérico de regressão é mostrado na Figura 1.4. 10 Figura 1.4 – Problema de regressão: prever um valor, dado um atributo de entrada (podem existir também vários atributos de entrada) (GERON, 2019) 1.4.2 Aprendizagem não Supervisionada Na aprendizagem não supervisionada, os dados do conjunto de treinamento não possuem um rótulo ou classe, portanto, o sistema tenta aprender sem supervisão. Por exemplo, digamos que você tenha muitos dados sobre os usuários visitantes do seu blog. Você pode executar um algoritmo de clusterização (agrupamento) para tentar detectar grupos de visitantes semelhantes. Em nenhum momento você diz ao algoritmo a que grupo o visitante pertence: ele encontra essas conexões sem a sua ajuda. Por exemplo, pode notar que 40% dos seus visitantes são homens que gostam de histórias em quadrinhos e geralmente leem seu blog à noite, enquanto 20% são jovens amantes de ficção científica que visitam nos fins de semana. Se você usar um algoritmo de clusterização hierárquica, ele também poderá subdividir cada grupo em grupos menores. Isso pode ajudá-lo a direcionar suas postagens para cada grupo. Observe a Figura 1.5, à esquerda ela mostra o seu conjunto de dados (visitantes do blog), e à direita você pode visualizar os grupos (ou clusters) que foram identificados pelo algoritmo de clusterização. Figura 1.5 – Exemplo de aprendizagem não supervisionada (GERON, 2019) Outra tarefa importante de aprendizagem não supervisionada é a detecção de anomalias; por exemplo, a detecção de transações incomuns com cartão de crédito para evitar fraudes, detecção de defeitos de fabricaçãoou remoção automática de valores discrepantes de um conjunto de dados antes de usá-lo em outro algoritmo de aprendizagem. Essa técnica é usada para identificar instâncias “normais” durante o treinamento, portanto aprende a reconhecê-las; 11 então, quando analisa uma nova instância, pode dizer se ela é parecida com uma instância normal ou se provavelmente é uma anomalia, como você pode observar na Figura 1.6. Uma tarefa muito semelhante é a detecção de novidades: ela visa detectar novas instâncias que parecem diferentes de todas as outras no conjunto de treinamento. Isso requer um conjunto de treinamento desprovido de qualquer instância que você queira que o algoritmo detecte. Por exemplo, se você tem milhares de fotos de cães e 1% delas representa Chihuahuas, um algoritmo de detecção de novidade não deve tratar novas fotos de Chihuahuas como novidades. Por outro lado, algoritmos de detecção de anomalias podem considerar esses cães tão raros e tão diferente de outros cães que provavelmente os classificariam como anomalias (sem querer ofender aos Chihuahuas). 1.4.3 Aprendizagem por Reforço A aprendizagem por reforço é um método bastante diferente. Nesse sistema de aprendizagem, um agente “inteligente” pode observar o ambiente, selecionar e executar ações e receber recompensas em troca, ou penalidades na forma de recompensas negativas, como mostra a Figura 1.7. Em seguida, ele deve aprender por si próprio qual é a melhor estratégia, chamada de política, para obter a maior recompensa ao longo do tempo. Uma política define qual ação o agente deve escolher quando estiver em uma determinada situação. Por exemplo, muitos robôs são criados com base em algoritmos de aprendizagem por reforço para aprender a andar. O programa AlphaGo da DeepMind também é um bom exemplo de aprendizagem por reforço: ele chegou às manchetes em maio de 2017 quando venceu o campeão mundial Ke Jie no jogo Go. Ele aprendeu sua política vitoriosa analisando milhões de jogos e depois jogando muitas vezes contra si mesmo, sendo que a aprendizagem foi desativada durante os jogos contra o campeão, assim, o AlphaGo estava apenas aplicando a política que havia aprendido anteriormente (GERON, 2019). Figura 1.6 – Exemplo genérico de detecção de anomalias (GERON, 2019) 12 Figura 1.7 – Aprendizagem por reforço (GERON, 2019) 1.5 Roteiro Nesta seção iremos apresentar o conteúdo que estudaremos em cada capítulo do módulo. 1.5.1 Pré-requisitos Os únicos conhecimentos necessários que você precisará ter para compreender o conteúdo estudado neste módulo são os conceitos básicos da linguagem de programação Python1. Os trechos de código-fonte discutidos nos próximos capítulos foram implementados e utilizam pacotes em Python 3, portanto, vamos considerar que você possui algum tipo de familiaridade com esta linguagem de programação Também utilizaremos alguns pacotes específicos em Python para executar os exemplos discutidos nos próximos capítulos. São eles: NumPy2, SciPy3, scikit-learn4 e matplotlib5. Em cada capítulo serão utilizados alguns pacotes mais específicos sobre algumas técnicas de Inteligência Artificial, neste caso, as instruções serão fornecidas no próprio capítulo. 1https://www.python.org/downloads 2http://docs.scipy.org/doc/numpy-1.10.1/user/install.html 3http://www.scipy.org/install.html 4http://scikit-learn.org/stable/install.html 5http://matplotlib.org/1.4.2/users/installing.html https://www.python.org/downloads/ http://docs.scipy.org/doc/numpy-1.10.1/user/install.html http://www.scipy.org/install.html http://scikit-learn.org/stable/install.html http://matplotlib.org/1.4.2/users/installing.html 13 1.5.2 Assuntos abordados no módulo Este primeiro Capítulo é uma introdução ao conceito de Inteligência Artificial (IA). Já discutimos rapidamente o que é IA e como ela ganhou relevância na construção de sistemas inteligentes, principalmente nas últimas décadas. IA é uma área bastante extensa e possui diversos ramos, como a Aprendizagem de Máquina e Reconhecimento de Padrões, a IA baseada em Lógica, as Técnicas de Pesquisa, a Representação do conhecimento, técnicas baseadas em Planejamento e Heurísticas. Contudo, algumas dessas sub-áreas são bastante antigas e hoje são consideradas obsoletas, como a Representação do conhecimento. São consideradas técnicas de IA modernas principalmente aquelas baseadas em Aprendizagem de Máquina e Reconhecimento de Padrões, e é justamente para esse ramos da IA que dedicaremos os próximos quatro capítulos do módulo. Ainda no Capítulo 1 fizemos uma introdução ao conceitos de Aprendizagem de Máquina. Você estou que essa sub-área da IA basicamente se divide em aprendizagem supervisionada, aprendizagem não supervisionada e aprendizagem por reforço. Esta última técnica é usada principalmente na implementação de agentes inteligentes, como robôs. Portanto, iremos focar os próximos capítulos em técnicas de aprendizagem supervisionadas e não supervisionadas. No Capítulo 2 discutiremos as duas principais técnicas de aprendizagem supervisionada: classificação e regressão. O capítulo se inicia com a discussão de conceitos relacionados à avaliação da qualidade dos classificadores, como matriz de confusão, precision, recall e F1-score. Em seguida, discutiremos a classificação pelo método estatístico Naïve Bayes, uma técnica usada para construir classificadores usando o teorema de Bayes, que descreve a probabilidade de ocorrência de um evento com base em diferentes condições relacionadas a esse evento. Por fim, discutiremos as técnicas de regressão linear simples e regressão linear múltipla. No Capítulo 3 apresentaremos técnicas de aprendizagem não supervisionadas, ela é o método oposto da aprendizagem supervisionada, uma vez que não existe disponível um atributo que exerça o papel da classe no conjunto de dados. Você estudará algoritmos de clusterização como o K-Means e o Mean Shift, além de conhecer métodos para estimar a qualidade dos clusters identificados pelos algoritmos, por meio da técnica de silhouette scores. No Capítulo 4 estudaremos uma das principais técnicas de aprendizagem supervisionadas existentes atualmente, as redes neurais artificiais. Uma das premissas fundamentais da Inteligência Artificial é criar sistemas que possam executar tarefas que normalmente exigiriam inteligência humana. O cérebro humano é incrível quando o tema é aprender novos conceitos. Sendo assim, por que não usar o modelo do cérebro humano para construir um sistema? Uma rede neural artificial é um modelo projetado para simular livremente o processo de aprendizagem do cérebro humano. As redes neurais são projetadas para identificar os padrões subjacentes nos dados e aprender com eles. Neste capítulo você conhecerá o Perceptron, que é a estrutura básica para implementação de sistemas baseados em redes neurais, estudará como implementar redes neurais de uma e de várias camadas, e ainda aprenderá o conceito de redes neurais recorrentes. No Capítulo 5 conheceremos os Algoritmos Genéticos, um método que, assim como as redes neurais, faz parte da chamada área evolucionista da IA, pois utiliza uma série de técnicas bioinspiradas para criar sistemas baseados em aprendizagem de máquina. Primeiro, iremos descrever o que é um algoritmo genético, discutiremos os conceitos de algoritmos evolutivos e programação genética, e também veremos como eles se relacionam com algoritmos genéticos. Aprenderemos sobre os elementos fundamentais dos algoritmos genéticos, incluindo funções de cruzamento, mutação e aptidão. Em seguida, usaremos esses conceitos para construir alguns exemplos que vão ajudá-lo a aprofundar seus conhecimentos no assunto. 14 Em todos os próximos quatro capítulos, você irá aprender os conceitos apresentados por meio de uma série de exemplos práticos implementadosna linguagem de programação Python. Sempre iniciaremos o estudo por meio da análise de exemplos mais simples, e aos poucos iremos adicionar mais conceitos para que você possa entender os exemplos mais complexos. O objetivo é fornecer uma base com os conceitos fundamentais da Inteligência Artificial e da Aprendizagem de Máquina, para que futuramente você possa se aprofundar nos temas de seu maior interesse, no ritmo e intensidade que você julgar necessários. 1.5.3 Recursos usados no módulo Outro tema importante são os recursos que você irá utilizar ao longo do módulo. Em várias aulas, solicitaremos que você importe algum arquivo ou execute algum script já pronto para agilizar o andamento dos estudos. Todos esses recursos estão compactados em uma pasta que você pode baixar no seguinte link: https://bityli.com/zzdDJ. Recomendamos que logo no início, você salve esse arquivo e descompacte-o em alguma pasta no seu computador. Durante o módulo, sempre que solicitarmos que você utilize algum arquivo, você pode buscá-lo nessa pasta. 1.5.4 Ambiente de programação em Python: Spyder Os exemplos fornecidos ou implementados em Python podem ser executados na ferramenta de edição de código-fonte da sua preferência. Nós recomendamos e usaremos ao longo de todo o módulo o ambiente Spyder6. Spyder é um poderoso ambiente científico open source escrito em Python, para a linguagem de programação Python, projetado por e para cientistas, engenheiros e analistas de dados. Ele oferece uma combinação exclusiva das funcionalidades avançadas de edição, análise e depuração, por meio de uma ferramenta abrangente de desenvolvimento com exploração de dados, execução interativa, inspeção profunda e recursos de visualização interessantes para um pacote científico. Além de seus inúmeros recursos internos, suas habilidades podem ser estendidas ainda mais através do sistema de plugins e da API da ferramenta. Além disso, o Spyder também pode ser usado como uma biblioteca de extensão PyQt7, permitindo que os desenvolvedores aproveitem sua funcionalidade e incorporem seus componentes, como o console interativo, em seu próprio software PyQt. A Figura 1.8 mostra a interface principal do ambiente Spyder. 6https://www.spyder-ide.org 7https://pypi.org/project/PyQt5 https://bityli.com/zzdDJ https://www.spyder-ide.org/ https://pypi.org/project/PyQt5/ 15 Figura 1.8 – Interface principal do ambiente de Programação Spyder 1.6 Considerações Finais Neste primeiro capítulo do módulo, introduzimos os principais conceitos relacionados a Inteligência Artificial (IA). Você conheceu a definição de IA e estudou quais são os seus principais ramos, como a Aprendizagem de Máquina e Reconhecimento de Padrões, a IA baseada em Lógica, as Técnicas de Pesquisa, a Representação do conhecimento, técnicas baseadas em Planejamento e Heurísticas. Dentre essas sub-áreas, discutimos que atualmente as principais técnicas para a construção de sistemas inteligentes são baseadas em métodos de aprendizagem de máquina, sejam elas supervisionadas ou não supervisionadas. Você conheceu o roteiro que estudaremos nos próximos capítulos, que incluem técnicas de classificação, regressão, redes neurais e algoritmos genéticos. No próximo capítulo daremos início ao estudos sobre aprendizagem de máquina, conhecendo a técnica de classificação baseado no algoritmo Naïve Bayes e os métodos de análise de regressão linear. 16 Unidade 2: Aprendizagem Supervisionada – Classificação e Regressão 2.1 Considerações Iniciais A Aprendizagem supervisionada refere-se ao processo de construção de modelos de aprendizagem de máquina baseados em um conjunto de dados devidamente classificado. Neste tipo de aprendizagem, também chamada de classificação, cada exemplo ou observação do conjunto de dados consiste de diversas variáveis de entrada e uma variável de saída, conhecida como classe. O objetivo dos algoritmos de aprendizagem supervisionada é justamente prever a classe de um conjunto de dados, levando em consideração as variáveis de entrada. Justamente por isso, essa técnica também é conhecida como classificação. Por exemplo: um conjunto de dados bastante comum usado nesse contexto é o do Titanic, que contém as características (features) dos passageiros do famoso navio, como nome do passageiro, sexo, classe da cabine, idade e local de embarque. Neste exemplo, a variável classe seria do tipo boolean, pois ela indica se o passageiro sobreviveu ou não. Na Seção 2.2 você conhecerá mais detalhes do conceito de classificação. Na Seção 2.3 trataremos de conceitos relacionados à avaliação da qualidade dos classificadores. Na Seção 2.4 vamos aprender a classificação pelo método estatístico Naïve Bayes. Na Seção 2.5 aprenderemos o que é regressão. Na seção 2.6 trataremos de regressão linear simples, e na Seção 2.7 de regressão linear múltipla. Por fim, a Seção 2.8 faz as considerações finais do capítulo. 2.2 O que é classificação? Nesta seção, discutiremos sobre técnicas de classificação supervisionadas. No processo de classificação nós categorizamos os dados em um determinado número de classes. Durante o processo, organizamos os dados em um número fixo de categorias para que a classificação possa funcionar mais eficientemente. Neste sentido, o processo de classificação soluciona o problema de identificar a categoria à qual pertence um novo elemento no conjunto de dados. O modelo de classificação é construído com base no conjunto de dados de treinamento e suas categorias correspondentes. Por exemplo, digamos que você queira verificar se uma determinada imagem contém o rosto de uma pessoa ou não. O conjunto de dados de treinamento deveria conter classes correspondentes a essas duas categorias: “com rosto” e “sem rosto”. Em seguida o modelo é treinado com base nas amostras de dados disponíveis, e em seguida ele é usado para inferência. Um bom sistema de classificação facilita a localização e a recuperação de dados. Essas operações são usadas extensivamente em atividades como no reconhecimento facial, identificação de spam, sistemas de recomendação e assim por diante. Os algoritmos para classificação de dados irão apresentar os critérios corretos para separar os dados em um determinado número de classes. Você precisa fornecer um número suficientemente grande de amostras de treinamento para que o algoritmo de classificação consiga generalizar os seus critérios. Caso haja um número insuficiente de amostras, o algoritmo irá se ajustar aos dados do treinamento. Isso significa que ele não irá funcionar bem em dados desconhecidos, porque ele se ajustou muito ao modelo para se afinar aos padrões observados nos dados de treinamento. Este problema é conhecido como overfitting, sendo muito recorrente no mundo da inteligência artificial, e é preciso considerar esse fator ao criar os modelos de classificação. Também existe um problema antagônico conhecido como underfitting, e ocorre quando o modelo não se adapta bem sequer aos dados com os quais foi treinado. 17 2.3 Avaliação da qualidade dos classificadores: Matriz de confusão Uma matriz de confusão é uma tabela que é usada para descrever o desempenho de um classificador. Cada linha na matriz representa as instâncias da classe prevista, e cada coluna representa as instâncias da classe real. Esse nome é usado porque a matriz facilita a visualização se o modelo confundir ou rotular incorretamente suas classes. Nós comparamos cada classe com todas as outras e vemos quantas amostras são classificadas corretamente e incorretamente. Durante a construção da matriz, encontramos alguns conceitos importantes descritos a seguir. Considere um caso de classificação binária em que as saídas possíveis sejam 0 ou 1: • Verdadeiro positivo (VP): são amostras para as quais foi previsto1 e valor real é 1. • Verdadeiro negativo (VN): são amostras para as quais foi previsto 0 e valor real é 0. • Falso positivo (FP): são amostras para as quais foi previsto 1 e valor real é 0. • Falso negativo (FN): são amostras para as quais foi previsto 0 e valor real é 1. Dependendo do problema em questão, talvez seja necessário otimizar o algoritmo para reduzir a taxa de falsos positivos ou de falsos negativos. Por exemplo, em um sistema de identificação biométrica, é muito importante evitar falsos positivos, porque as pessoas erradas podem ter acesso a informações confidenciais. Em termos de métricas de avaliação, existem basicamente quatro conceitos: acurácia, precision, recall e F1-score. A acurácia é a métrica de desempenho mais comum, ela simplesmente indica a proporção de previsões corretas, por meio da fórmula: Precision é a proporção de cada verdadeiro positivo com o total de positivos. Podemos pensar nessa métrica como um ruído de medição das previsões, isto é, quando o classificador prevê algo como positivo, qual a probabilidade de realmente ser positivo. Um classificador com valor alto de precision é considerado pessimista, pois ele apenas irá classificar uma observação como positiva quando tiver certeza disto. Formalmente, a fórmula para o cálculo de precision é: Recall é a proporção de cada observação positiva que é verdadeiramente positiva. Podemos pensar nessa métrica como a habilidade do classificador em identificar observações da classe positiva. Classificadores com alto valor de recall são considerados otimistas, pois eles tendem a prever as observações como positivas. A fórmula para o cálculo de recall é: Por sua vez, F1-score é uma métrica que busca equilibrar precision e recall, por meio de uma média harmônica (tipo de média utilizada para proporções): A seguir é mostrado um exemplo de como criar uma matriz de confusão e um relatório com as métricas de avaliação do classificador. #importar os pacotes necessários import numpy as np import matplotlib.pyplot as plt from sklearn.metrics import confusion_matrix 18 from sklearn.metrics import classification_report # Definir os rótulos verdadeiros e falsos true_labels = [2, 0, 0, 2, 4, 4, 1, 0, 3, 3, 3] pred_labels = [2, 1, 0, 2, 4, 3, 1, 0, 1, 3, 3] # Criar a matriz de confusão confusion_mat = confusion_matrix(true_labels, pred_labels) # Visualizar a matriz de confusão plt.imshow(confusion_mat, interpolation='nearest', cmap=plt.cm.gray) plt.title('Matriz de Confusão') plt.colorbar() ticks = np.arange(5) #refere-se ao número de classes distintas plt.xticks(ticks, ticks) plt.yticks(ticks, ticks) plt.ylabel('Classes verdadeiras') plt.xlabel('Classes previstas') plt.show() # Relatório de classificação targets = ['Class-0', 'Class-1', 'Class-2', 'Class-3', 'Class-4'] print('\n', classification_report(true_labels, pred_labels, target_names=targets)) Ao executar o código, será visualizada a imagem mostrada na Figura 2.1. A cor branca representa os valores mais altos, enquanto a cor preta representa valores mais baixos. Em um cenário ideal, a diagonal principal da matriz deveria ser da cor branca, o que indica 100% de precisão. Além da matriz de confusão, o código mostra o relatório de classificação com o desempenho do classificador para cada classe. O relatório de classificação mostra o valor de precision de 85%, recall 73% e F1-score 75%. Dependendo do domínio com o qual estamos trabalhando, esses valores podem ser muito bons ou muito ruins. Se o domínio em questão tentasse determinar se um paciente tem câncer e tivéssemos um valor de precision de 85%, isso significa que 15% da população seria classificada incorretamente, o que é um resultado bastante ruim. Contudo, se o domínio estiver relacionado a compra de um produto e valor de precision for o mesmo (85%), esse resultado pode ser considerado ótimo, o que inclusive poderia reduzir as despesas do departamento de marketing. 19 Figura 2.1: Desempenho de cada classe do classificador (Fonte: ARTASANCHEZ & JOSHI (2020)) 2.4 Classificação pelo método estatístico Naïve Bayes Naïve Bayes é uma técnica usada para construir classificadores usando o teorema de Bayes, que descreve a probabilidade de ocorrência de um evento com base em diferentes condições relacionadas a esse evento. É possível construir um classificador Naïve Bayes atribuindo rótulos de classe a diferentes instâncias de um conjunto de dados. Essas instâncias são representadas como vetores de atributos, sendo que deve existir a premissa de que o valor de cada um dos atributos deve ser independente dos demais, o que é chamado de premissa da independência, e é parte fundamental de um classificador Naïve Bayes. Para um certo conjunto de dados, considerada uma determinada classe, nós apenas podemos avaliar como um determinado atributo a afeta independentemente dos seus efeitos sobre os outros atributos. Por exemplo, um animal apenas pode ser considerado um guepardo se ele possui manchas na pele, tem quatro patas, tem uma cauda e corre a 70 milhas por hora. Um classificador Naïve Bayes considera que cada um destes atributos contribui independentemente para o resultado. O resultado refere-se a probabilidade do animal ser um guepardo. Não precisamos nos preocupar com as correlações que podem existir entre manchas na pele, número de patas, existência de uma cauda e a velocidade do animal. O código a seguir mostra como criar um classificador Naïve Bayes. import numpy as np from sklearn.naive_bayes import GaussianNB from sklearn.model_selection import train_test_split from sklearn.model_selection import cross_val_score from utilities import visualize_classifier # Arquivo contendo os dados de entrada input_file = 'data_multivar_nb.txt' # Carregar os dados do arquivo data = np.loadtxt(input_file, delimiter=',') X, y = data[:, :-1], data[:, -1] # Criar o classificador Naive Bayes classifier = GaussianNB() # Treinar o classificador classifier.fit(X, y) # Prever os valores para os dados de treinamento y_pred = classifier.predict(X) # Calcular a acurácia accuracy = 100.0 * (y == y_pred).sum() / X.shape[0] print("Accuracy of Naive Bayes classifier =", round(accuracy, 2), "%") # Visualizar o desempenho do classificador visualize_classifier(classifier, X, y) ################### # Validação cruzada # Dividir os dados em conjuntos de teste e treinamento 20 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=3) classifier_new = GaussianNB() classifier_new.fit(X_train, y_train) y_test_pred = classifier_new.predict(X_test) # Calcular a acurácia do classificador accuracy = 100.0 * (y_test == y_test_pred).sum() / X_test.shape[0] print("Accuracy of the new classifier =", round(accuracy, 2), "%") # Visualizar o desempenho do classificador visualize_classifier(classifier_new, X_test, y_test) ######################## # Métricas de desempenho num_folds = 3 accuracy_values = cross_val_score(classifier, X, y, scoring='accuracy', cv=num_folds) print("Accuracy: " + str(round(100*accuracy_values.mean(), 2)) + "%") precision_values = cross_val_score(classifier, X, y, scoring='precision_weighted', cv=num_folds) print("Precision: " + str(round(100*precision_values.mean(), 2)) + "%") recall_values = cross_val_score(classifier, X, y, scoring='recall_weighted', cv=num_folds) print("Recall: " + str(round(100*recall_values.mean(), 2)) + "%") f1_values = cross_val_score(classifier, X, y, scoring='f1_weighted', cv=num_folds) print("F1: " + str(round(100*f1_values.mean(), 2)) + "%") Ao executar o código, além das métricas de desempenho são mostrados os gráficos da Figura 2.2. Eles mostram os dados de entradaseparados em quatro regiões, de acordo com os valores de entrada. Atenção! Neste exemplo de classificação com o algoritmo Naïve Bayes foram utilizadas apenas atributos numéricos. Contudo, essa não é uma característica obrigatória, pois o algoritmo pode executar também com atributos categóricos (string) ou de outros tipos. (a) (b) Figura 2.2: (a) Dados e seus limites após o primeiro treinamento. (b) Dados e seus limites após o segundo treinamento, com conjuntos de teste e treinamento (Fonte: ARTASANCHEZ & JOSHI (2020)) 21 2.5 O que é regressão? O termo “Análise de Regressão” define um vasto conjunto de técnicas usadas para modelar relações entre variáveis e predizer o valor de uma ou mais variáveis dependentes (de resposta ou saída) a partir de um conjunto de variáveis independentes (preditoras ou de entrada). Um objetivo comum para se desenvolver um modelo de regressão é prever qual deve ser o valor de saída de um sistema para um novo conjunto de valores de entrada, uma vez que você possui uma coleta de dados sobre sistemas semelhantes. Por exemplo, à medida que você ganha experiência ao dirigir um carro, você começou a desenvolver uma noção intuitiva de quanto tempo levaria para dirigir em algum lugar se soubesse o tipo de carro, o clima, uma estimativa do tráfego, a distância e assim por diante. O que você realmente fez para criar essa estimativa do tempo de condução foi construir um modelo de regressão de múltiplos fatores em sua mente. As entradas para o seu modelo são o tipo de carro, o clima, etc. A saída é quanto tempo você levará para ir de um ponto a outro. Quando você altera qualquer uma das entradas, como um aumento repentino no tráfego, você reestima automaticamente quanto tempo levará para chegar ao destino. Regressão é o processo de estimar o relacionamento entre variáveis de entrada e variáveis de saída. Uma observação importante é que as variáveis tanto entrada como de saída devem ser numéricas. Portanto, há um número infinito de possibilidades. Isso diferencia regressão de classificação, em que o número de classes do conjunto de dados é fixo, ou seja, existe um conjunto finito de possibilidades. Além disso, podem existir atributos não numéricos (categóricos). Na regressão, assume-se que as variáveis de saída dependem das variáveis de entrada, portanto, queremos ver como elas estão relacionadas. Consequentemente, as variáveis de entrada são chamadas de variáveis independentes, também conhecidas como preditores, e as variáveis de saída são chamadas de variáveis dependentes, também conhecidas como variáveis de critério. Não é necessário que as variáveis de entrada sejam independentes umas das outras, sendo que existem muitas situações em que ocorrem correlações entre variáveis de entrada. A análise de regressão nos ajuda a entender como o valor da variável de saída muda quando mudamos o valor de algumas variáveis de entrada, mantendo outras variáveis com o valor fixo. Na regressão linear, assumimos que a relação entre entrada e saída é linear. Isso restringe o procedimento de modelagem, mas é rápido e eficiente. Às vezes, a regressão linear não é suficiente para explicar a relação entre variáveis de entrada e saída. Nesses casos, usamos a regressão polinomial, em que um polinômio é criado para explicar a relação entre variáveis de entrada e saída. Isso é computacionalmente mais complexo, mas oferece maior precisão. Dependendo do problema em questão, usamos diferentes formas de regressão para extrair o relacionamento. A análise de regressão é frequentemente usada para a previsão de preços, na economia, variações do mercado financeiro e assim por diante. 2.6 Regressão linear simples O método de classificação por regressão linear simples é utilizado em conjuntos de dados em que uma única variável de entrada é utilizada para prever o valor de saída. O código a seguir cria um classificador baseado em regressão simples. import pickle import numpy as np from sklearn import linear_model import sklearn.metrics as sm import matplotlib.pyplot as plt # Arquivo de entrada que contem os dados 22 input_file = 'data_singlevar_regr.txt' # Leitura dos dados data = np.loadtxt(input_file, delimiter=',') X, y = data[:, :-1], data[:, -1] # Conjuntos de teste e treinamento num_training = int(0.8 * len(X)) num_test = len(X) - num_training # Treinando os dados X_train, y_train = X[:num_training], y[:num_training] # Dados de teste X_test, y_test = X[num_training:], y[num_training:] # Criando o objeto responsável pelo linha de regressão regressor = linear_model.LinearRegression() # Treinando o modelo com os dados do conjunto de treinamento regressor.fit(X_train, y_train) # Prevendo a saída y_test_pred = regressor.predict(X_test) # Colocando os resultados no gráfico plt.scatter(X_test, y_test, color='green') plt.plot(X_test, y_test_pred, color='black', linewidth=3) plt.xticks(()) plt.yticks(()) plt.show() # Calculando as métricas de desempenho print("Desempenho da classificação por regressão linear simples:") print("Erro absoluto médio = ", round(sm.mean_absolute_error(y_test, y_test_pred), 2)) print("Erro quadrático médio = ", round(sm.mean_squared_error(y_test, y_test_pred), 2)) print("R2 score = ", round(sm.r2_score(y_test, y_test_pred), 2)) # Modelo de persistência output_model_file = 'model.pkl' # Armazenando o modelo with open(output_model_file, 'wb') as f: pickle.dump(regressor, f) # Carregando o modelo with open(output_model_file, 'rb') as f: regressor_model = pickle.load(f) # Executando previsão com os dados de teste y_test_pred_new = regressor_model.predict(X_test) print("\nNew mean absolute error =", round(sm.mean_absolute_error(y_test, y_test_pred_new), 2)) Após executar o código, é exibido o gráfico da Figura 2.3, que mostra o modelo linear que representa o classificador construído. Além disso são mostradas as seguintes informações: Desempenho da classificação por regressão linear simples: Erro absoluto médio = 0.59 23 Erro quadrático médio = 0.49 R2 score = 0.86 Novo erro absoluto médio = 0.59 Figura 2.3: Modelo de regressão linear (Fonte: ARTASANCHEZ & JOSHI (2020)) O erro absoluto médio (MAE – Mean Absolute Error) é a média dos erros absolutos, obtido por meio da seguinte fórmula: Em que é a previsão e é o valor atual. O erro quadrático médio (MSE - Mean Squared Error), como o próprio nome indica, é a média dos quadrados dos erros, ou seja, o quadrado médio da diferença entre os valores previstos e os valores atuais. MSE é quase sempre estritamente positivo (e não zero) devido a aleatoriedade. Normalmente, MSE é usado como métrica para avaliar a qualidade do classificador de regressão linear; ele é sempre um valor não negativo, e os melhores valores são os mais próximos de zero. O R2 score ou coeficiente de determinação é utilizado para analisar como as diferenças para uma variável pode ser explicada pela diferença em uma segunda variável (correlação). É um valor entre 0 e 1 que descreve quão bem o modelo de regressão linear representa os dados mensurados. Esse valor pode ser calculado dividindo a variação total de como o modelo explica os dados e a variação total. Ao multiplicar este valor por 100, podemos interpretá-lo como uma porcentagem entre 0 e 100. O valor de 0.86 reportado significa que o modelo pode explicar 86% da variação dos dados. 2.7 Regressão múltipla Na seção anterior discutimos como construir um classificador de regressão simples. Nesta seção, iremos introduzir o conceito de regressão múltipla, que utiliza dados multidimensionais. O código a seguir cria um classificador baseado em regressão múltipla. import numpy asnp from sklearn import linear_model 24 import sklearn.metrics as sm from sklearn.preprocessing import PolynomialFeatures # Arquivo de entrada que contém os dados input_file = 'data_multivar_regr.txt' # Carrega os dados do arquivo de entrada data = np.loadtxt(input_file, delimiter=',') X, y = data[:, :-1], data[:, -1] # Divide os dados em conjuntos de treinamento e teste num_training = int(0.8 * len(X)) num_test = len(X) - num_training # Dados de treinamento X_train, y_train = X[:num_training], y[:num_training] # Dados de teste X_test, y_test = X[num_training:], y[num_training:] # Cria o modelo de regressão linear linear_regressor = linear_model.LinearRegression() # Treina o modelo utilizando os dados de treinamento linear_regressor.fit(X_train, y_train) # Predição da saída y_test_pred = linear_regressor.predict(X_test) # Métricas de desempenho print("Desempenho da classificação por regressão linear múltipla:") print("Erro absoluto médio = ", round(sm.mean_absolute_error(y_test, y_test_pred), 2)) print("Erro quadrático médio = ", round(sm.mean_squared_error(y_test, y_test_pred), 2)) print("Mediana absoluta média = ", round(sm.median_absolute_error(y_test, y_test_pred), 2)) print("Explicação da variância = ", round(sm.explained_variance_score(y_test, y_test_pred), 2)) print("R2 score = ", round(sm.r2_score(y_test, y_test_pred), 2)) # Regressão polinomial polynomial = PolynomialFeatures(degree=10) X_train_transformed = polynomial.fit_transform(X_train) datapoint = [[7.75, 6.35, 5.56]] poly_datapoint = polynomial.fit_transform(datapoint) poly_linear_model = linear_model.LinearRegression() poly_linear_model.fit(X_train_transformed, y_train) print("\nRegressão linear:\n", linear_regressor.predict(datapoint)) print("\nRegressão polinomial:\n", poly_linear_model.predict(poly_datapoint)) O trecho de código referente à regressão polinomial cria um classificador baseado em um polinômio de grau 10. Depois de treinar o classificador, o trecho de código acima utiliza uma observação do conjunto de dados e realiza a previsão. A observação escolhida está na linha 11 do arquivo de dados: [7.66, 6.29, 5.66], e o seu resultado é igual a 41.35. Além das métricas de desempenho, a execução do código mostra o seguinte resultado: Linear regression: [ 36.05286276] Polynomial regression: [ 41.46961676] 25 Como você pode observar, o classificador baseado em regressão polinomial prevê um valor mais próximo ao da realidade. 2.8 Considerações Finais Este capítulo apresentou com mais detalhes o conceito de aprendizagem supervisionada, conhecida como classificação, e dois algoritmos pertencentes a esta área da inteligência supervisionada. Você conheceu técnicas simples para avaliar a qualidade de modelos de classificação, como a matriz de confusão e suas métricas relacionadas, como acurácia, precision e recall. Você também conheceu o algoritmo de classificação Naïve Bayes, que utiliza métodos estatísticos para prever a classe de um conjunto de dados. Você conheceu ainda as técnicas de classificação por regressão, simples e múltipla, que trata exclusivamente da classificação de dados numéricos relacionados ou não entre si. No próximo capítulo, você conhecerá a técnica de aprendizagem não supervisionada, que não necessita da variável conhecida como classe em seu conjunto de dados. 26 Unidade 3: Aprendizagem não supervisionada 3.1 Considerações Iniciais A Aprendizagem não Supervisionada refere-se ao processo de construção de modelos de aprendizagem de máquina sem a utilização de um conjunto de dados devidamente classificado, ou seja, sem o processo de treinamento. Nesse sentido, esse método é o oposto da aprendizagem supervisionada. Uma vez que não existe disponível um atributo que exerça o papel da classe no conjunto de dados, é necessário extrair alguns insights com base nos dados disponíveis. Na aprendizagem não supervisionada, nós estamos treinando um sistema em que os dados serão separados, com base em suas características, para formar vários grupos, conhecidos como clusters. Um ponto chave que deve ser ressaltado é que nós não sabemos exatamente qual seria esse critério de separação. Nesse sentido, um algoritmo de aprendizagem não supervisionada precisa separar os dados da melhor forma possível. Na Seção 3.2 trataremos da clusterização de dados com o algoritmo K-Means. Na Seção 3.3 vamos aprender a estimar o número ideal de clusters com o algoritmo Mean Shift. Na Seção 3.4 iremos estimar a qualidade dos clusters por meio do conceito de silhouette scores. Na seção 3.5 vamos conhecer o modelo de propagação por afinidade. Na Seção 3.6 vamos usar a clusterização para segmentar dados referentes a compras feitas por clientes. Por fim, a Seção 3.7 faz as considerações finais do capítulo. 3.2 Clusterização de dados com o algoritmo K-Means A clusterização, ou agrupamento, é uma das técnicas mais populares de aprendizagem não supervisionada. Essa técnica é usada para analisar dados e encontrar clusters dentro desses dados. Para encontrar tais clusters, usamos uma métrica de similaridade, como a distância euclidiana, para encontrar subgrupos. Essa métrica de similaridade pode estimar a proximidade que os dados irão manter dentro de um cluster. Assim, clusterização é o processo de organização de dados em subgrupos cujos elementos são semelhantes entre si. O objetivo do algoritmo é identificar as propriedades intrínsecas dos pontos de dados que os fazem pertencer ao mesmo subgrupo. Não há uma métrica de similaridade universal que funcione em todos os casos. Por exemplo, podemos estar interessados em encontrar uma proximidade que seja representativa para cada subgrupo, ou então encontrar valores discrepantes nos dados. Dependendo da situação, métricas diferentes podem ser mais apropriadas que outras. K-Means é um algoritmo bem conhecido e utilizado para agrupar dados. Para utilizá-lo, é preciso determinar o número de clusters previamente. Os dados são segmentados em k subgrupos usando vários atributos do conjunto de dados. O número de clusters é fixo e os dados são classificados com base nesse número. A ideia principal é que precisamos atualizar os locais dos centroides a cada iteração. Um centroide é o local que representa o centro do cluster. Esse processo é feito em várias iterações, até que os centroides sejam posicionados em locais considerados ideais. O posicionamento inicial dos centroides desempenha um papel importante no algoritmo. Esses centroides devem ser colocados de maneira inteligente, porque isso afeta diretamente os resultados. Uma boa estratégia é colocá-los o mais longe possível um do outro. 27 O algoritmo K-Means básico distribui esses centroides aleatoriamente, enquanto uma versão alternativa conhecida como K-Means++ escolhe esses pontos na lista de entrada do conjunto de dados. Ele tenta distribuir os centroides iniciais distantes um do outro para que a convergência possa acontecer rapidamente. Em seguida, percorremos o conjunto de dados de treinamento e atribuimos cada ponto de dados ao centroide mais próximo. Depois de percorrermos todo o conjunto de dados, a primeira iteração termina. Os pontos foram agrupados com base nos centroides inicializados. A localização dos centroides é recalculada com base nos novos clusters que foram obtidos no final da primeira iteração. Depois que um novo conjunto de K centroides é obtido, o processo é repetido. Repetimos a análise do conjunto de dados e atribuímos cada ponto ao centroide mais próximo. À medida que os passos se repetem, os centroides continuam se movendo para uma posição de equilíbrio. Depois de um certo número de iterações, os centroides não mudam mais de posição, pois eles convergem paraum local final. Esses k centroides são os valores que serão usados para inferência. Vamos aplicar o algoritmo K-Means em um conjunto de dados bidimensionais (arquivo data_clustering.txt) para entender como ele funciona, por meio do código-fonte em Python mostrado a seguir. import numpy as np import matplotlib.pyplot as plt from sklearn.cluster import KMeans # Carregar os dados X = np.loadtxt('data_clustering.txt', delimiter=',') # Definir o número de clusters num_clusters = 5 # Plotar os dados de entrada plt.figure() plt.scatter(X[:,0], X[:,1], marker='o', facecolors='none', edgecolors='black', s=80) x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1 y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1 plt.title('Dados de entrada') plt.xlim(x_min, x_max) plt.ylim(y_min, y_max) plt.xticks(()) plt.yticks(()) # Criar o objeto que representa o algoritmo kmeans = KMeans(init='k-means++', n_clusters=num_clusters, n_init=10) # Treinar o modelo de clusterização kmeans.fit(X) # Granularidade para a divisão dos grupos step_size = 0.01 # Definir os pontos do grid para facilitar a visualização dos clusters x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1 y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1 x_vals, y_vals = np.meshgrid(np.arange(x_min, x_max, step_size), np.arange(y_min, y_max, step_size)) 28 # Prever os rótulos de saída para todos os pontos do grid output = kmeans.predict(np.c_[x_vals.ravel(), y_vals.ravel()]) # Definir cores diferentes para os clusters output = output.reshape(x_vals.shape) plt.figure() plt.clf() plt.imshow(output, interpolation='nearest', extent=(x_vals.min(), x_vals.max(), y_vals.min(), y_vals.max()), cmap=plt.cm.Paired, aspect='auto', origin='lower') # sobreposição dos pontos de entrada plt.scatter(X[:,0], X[:,1], marker='o', facecolors='none', edgecolors='black', s=80) # Plotar as regiões centrais dos clusters cluster_centers = kmeans.cluster_centers_ plt.scatter(cluster_centers[:,0], cluster_centers[:,1], marker='o', s=210, linewidths=4, color='black', zorder=12, facecolors='black') x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1 y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1 plt.title('Limites de cada cluster') plt.xlim(x_min, x_max) plt.ylim(y_min, y_max) plt.xticks(()) plt.yticks(()) plt.show() Ao executar o código fonte, são mostrados os dois gráficos representados na Figura 3.1. A Figura 3.1(a) mostra os dados de entrada em um gráfico bidimensional; a Figura 3.1(b) mostra como ficou a divisão dos dados em cinco clusters após a execução do algoritmo K-Means. Os círculos pretos mostrados representam os centroides de cada cluster. 29 (a) (b) Figura 3.1: (a) Visualização dos dados de entrada. (b) Divisão dos dados em cinco clusters após execução do algoritmo K-Means (Fonte: ARTASANCHEZ & JOSHI (2020)) 3.3 Estimando o número de clusters com o algoritmo Mean Shift Mean Shift é um algoritmo poderoso usado em aprendizagem não supervisionada. É um algoritmo não paramétrico usado com frequência para clusterização. Ele é não paramétrico, porque não faz suposições sobre as distribuições subjacentes. Isso contrasta com as técnicas paramétricas, nas quais se assume que os dados subjacentes seguem uma distribuição de probabilidade padrão. O Mean Shift possui muitas aplicações, principalmente em áreas como rastreamento de objetos e análise de dados em tempo real. No algoritmo Mean Shift, todo o espaço de features (atributos dos dados) é considerado uma função de densidade de probabilidade. Ele começa com o conjunto de dados de treinamento e assume que ele foi criado com base em uma função de densidade de probabilidade. Na estratégia adotada pelo algoritmo, os clusters correspondem aos máximos locais da distribuição subjacente. Se houver k clusters, haverá k pontos máximos (picos) na distribuição de dados subjacentes e o Mean Shift identificará esses picos. O objetivo do algoritmo Mean Shift é identificar a localização dos centroides. Para cada observação no conjunto de dados de treinamento, ele define uma janela ao seu redor. Em seguida, calcula o centroide para esta janela e atualiza o valor local para esse novo centroide. Em seguida, repete o processo para esse novo local, definindo uma janela ao seu redor. Enquanto realiza esse processo iterativamente, se aproxima cada vez mais do ponto máximo do cluster. Cada observação dos dados se moverá em direção ao cluster ao qual pertence. O movimento é em direção a uma região de maior densidade. Os centroides (também chamados de meios, tradução para means) continuam sendo deslocados para os picos de cada cluster. O algoritmo recebe esse nome pelo fato dos centroides continuarem sendo alterados. Essa mudança continua ocorrendo até que o algoritmo atinja o ponto de convergência, momento em que os centroides não se movem mais. Veja no código-fonte abaixo como usar o algoritmo Mean Shift para estimar o número de clusters mais adequado para um determinado conjunto de dados. Os dados são os mesmos utilizados na seção anterior com o algoritmo K-Means. import numpy as np import matplotlib.pyplot as plt from sklearn.cluster import MeanShift, estimate_bandwidth # Carregar os dados de entrada X = np.loadtxt('data_clustering.txt', delimiter=',') 30 # Definindo o bandwidth, parâmetro que afeta a convergência do algoritmo bandwidth_X = estimate_bandwidth(X, quantile=0.1, n_samples=len(X)) # Clusterização meanshift_model = MeanShift(bandwidth=bandwidth_X, bin_seeding=True) meanshift_model.fit(X) # Mostrar os valores dos centroides de cada cluster cluster_centers = meanshift_model.cluster_centers_ print('\nCentroides dos clusters:\n', cluster_centers) # Estimar o número de clusters labels = meanshift_model.labels_ num_clusters = len(np.unique(labels)) print("\nNúmero de clusters no conjunto de dados =", num_clusters) # Mostrar os dados e seus respectivos centroides plt.figure() markers = 'o*xvs' for i, marker in zip(range(num_clusters), markers): # Plotar os pontos do conjunto de dados plt.scatter(X[labels==i, 0], X[labels==i, 1], marker=marker, color='black') # Plotar os centroides cluster_center = cluster_centers[i] plt.plot(cluster_center[0], cluster_center[1], marker='o', markerfacecolor='red', markeredgecolor='red', markersize=15) plt.title('Clusters') plt.show() Ao executar o código-fonte, você pode visualizar o gráfico mostrado na Figura 3.2, que representa os cinco clusters e seus respectivos centroides, destacados na cor vermelha. Figura 3.2: Clusters criados com o algoritmo Mean Shift (Fonte: ARTASANCHEZ & JOSHI (2020)) 31 Além do gráfico, o código-fonte também mostra as seguintes informações, com as coordenadas dos centroides de cada cluster. Centroides dos clusters: [[2.95568966 1.95775862] [7.20690909 2.20836364] [2.17603774 8.03283019] [5.97960784 8.39078431] [4.99466667 4.65844444]] Número de clusters no conjunto de dados = 5 3.4 Estimando a qualidade dos clusters com o conceito de silhouette scores Se os dados estão naturalmente organizados em vários grupos distintos, é fácil examiná- los visualmente e fazer algumas inferências. Infelizmente, essa é uma situação rara no mundo real. Os dados no mundo real são muito grandes e confusos. Portanto, precisamos de uma maneira de quantificar a qualidade dos clusters criados pelos algoritmos de aprendizagem não supervisionada. Silhouette score refere-se a um método usado paraverificar a consistência dos clusters nos dados. Ele fornece uma estimativa de quão bem cada observação dos dados se ajusta ao seu cluster. A pontuação nesse método é uma métrica que analisa a semelhança de um ponto no conjunto de dados com seu próprio cluster, em comparação com os outros clusters. Essa pontuação funciona com qualquer métrica de similaridade. Para cada observação no conjunto de dados, o silhouette score é calculado por meio da seguinte fórmula: sendo que p é a distância média para os pontos no cluster mais próximo do qual os dados da observação não faz parte, e q é a distância média intra-cluster para todas as observações em seu próprio cluster. O valor do silhouette score é um número no intervalo [-1, 1]. Um valor mais próximo de 1 indica que as observações são muito semelhantes umas às outras dentro no cluster, enquanto um valor mais próxima de -1 indica que as observações não são semelhantes umas às outras dentro do cluster. Uma forma de interpretar esses valores é que, se houver muitas observações com valores negativos, o número k que representa o número de clusters pode ter sido muito grande ou muito pequeno. Neste caso, é preciso executar o algoritmo de clusterização novamente para encontrar o número ideal de clusters. Idealmente, é desejável ter um alto valor positivo. Dependendo do conjunto de dados, não é preciso otimizar e ter o maior valor possível (próximo de 1), mas, em geral, se tivermos um silhouette score próximo a 1, isso indica que os dados foram bem agrupados. Se o score estiver próximo de -1, isso indica que a variável utilizada para agrupar os dados contém um alto nível de ruído e deve ser reanalisada. O código fonte a seguir mostra como avaliar o desempenho do algoritmo de clusterização K-Means por meio do conceito de silhouette score. O conjunto de dados utilizado está contido no arquivo data_quality.txt. Ao executar o código fonte, você irá visualizar os gráficos mostrados na Figura 3.3. A Figura 3.3(a) mostra os dados de entrada em gráfico bidimensional; a Figura 3.3(b) mostra os valores de silhouette score, sendo que é possível observar que o score mais alto é com k = 6, o que é bastante condizente com os dados mostrados no gráfico. 32 (a) (b) Figura 3.3: (a) Visualização dos dados de entrada. (b) Silhouette score para cada número de cluster usado na execução do algoritmo (Fonte: ARTASANCHEZ & JOSHI (2020)) Além dos gráficos, a execução do código-fonte mostra as seguintes informações como saída, em que é possível observar que o melhor valor de silhouette score é para o número de clusters igual a 6. Número de clusters = 2 Silhouette score = 0.47762624870454473 Número de clusters = 3 Silhouette score = 0.5471742411734871 Número de clusters = 4 Silhouette score = 0.579480188968759 Número de clusters = 5 Silhouette score = 0.5890032635647954 Número de clusters = 6 Silhouette score = 0.6096904118954453 Número de clusters = 7 Silhouette score = 0.5538191872249804 33 Número de clusters = 8 Silhouette score = 0.49386778685308397 Número de clusters = 9 Silhouette score = 0.44659247187658097 Número ótimo de clusters = 6 3.5 Modelo de propagação por afinidade O modelo de propagação de afinidade é um algoritmo de agrupamento que não exige que um número de clusters seja especificado antecipadamente. Devido à sua natureza genérica e sua simplicidade de implementação, ele encontrou muitas aplicações em diversas áreas. Ele encontra clusters representativos, chamados de exemplos, usando uma técnica chamada passagem de mensagem. Tudo começa especificando as medidas de similaridade que precisam ser consideradas. Simultaneamente, considera-se todas as observações no conjunto de treinamento como possíveis exemplos. Em seguida, o algoritmo passa as mensagens entre as observações até encontrar um conjunto significativo de exemplos. A passagem da mensagem ocorre em duas etapas alternativas, denominadas responsabilidade e disponibilidade. Responsabilidade refere-se à mensagem enviada dos membros do cluster para os exemplos candidatos, indicando o quão adequada a observação seria como membro do cluster deste exemplo. Disponibilidade refere-se à mensagem enviada de exemplos candidatos a membros em potencial do cluster, indicando o quão adequado ele seria como exemplo. O algoritmo continua essa estratégia até convergir para um conjunto ideal de exemplos. Há também um parâmetro chamado preferência, que controla o número de exemplos que serão encontrados. Se um valor alto for escolhido, ele fará com que o algoritmo encontre muitos clusters. Se um valor baixo for escolhido, isso levará a um pequeno número de clusters. Um valor ótimo seria a mediana entre esses dois pontos. Vamos usar o modelo de propagação por afinidade para encontrar subgrupos em um conjunto de dados do mercado de ações. Usaremos a variação da cotação das ações entre abertura e fechamento como o recurso de controle. Os dados do mercado de ações disponíveis na biblioteca matplotlib serão usados como dados de entrada. Os símbolos da empresa são mapeados para seus nomes completos no contidos no arquivo company_symbol_mapping.json. Atenção! Para executar o código-fonte a seguir, você precisará instalar o pacote yfinance, disponível em: https://pypi.org/project/yfinance. import datetime import json import numpy as np from sklearn import covariance, cluster import yfinance as yf # Arquivo de entrada contendo os símbolos input_file = 'company_symbol_mapping.json' https://pypi.org/project/yfinance 34 # Carregar os símbolos em um mapa with open(input_file, 'r') as f: company_symbols_map = json.loads(f.read()) symbols, names = np.array(list(company_symbols_map.items())).T # Carregar os dados históricos das ações start_date = datetime.datetime(2019, 1, 1) end_date = datetime.datetime(2019, 1, 31) quotes = [yf.Ticker(symbol).history(start=start_date, end=end_date) for symbol in symbols] # extrair dados da abertura e encerramento das cotações opening_quotes = np.array([quote.Open for quote in quotes]).astype(np.float) closing_quotes = np.array([quote.Close for quote in quotes]).astype(np.float) # calcular as diferenças entre abertura e encerramento quotes_diff = closing_quotes - opening_quotes # Normalizar os dados X = quotes_diff.copy().T X /= X.std(axis=0) # Criar um modelo gŕafico edge_model = covariance.GraphicalLassoCV() # Treinar o modelo with np.errstate(invalid='ignore'): edge_model.fit(X) # Construir o modelo de clusterização baseado em propagação por afinidade _, labels = cluster.affinity_propagation(edge_model.covariance_, random_state=None) num_labels = labels.max() # Imprimir os resultados print('\nClusterização das ações com base na diferença entre as cotações na abertura e no encerramento:\n') for i in range(num_labels + 1): print("Cluster", i+1, "==>", ', '.join(names[labels == i])) Resultado da execução do código-fonte: Cluster 1 ==> Microsoft, Amazon, Apple Cluster 2 ==> Ford Cluster 3 ==> IBM, Navistar, Northrop Grumman, Boeing, 3M Cluster 4 ==> Mc Donalds Cluster 5 ==> Coca Cola, Pepsi, Procter Gamble Cluster 6 ==> Kellogg Este resultado representa os vários subgrupos no mercado de ações durante o período especificado, entre 01 e 31 de janeiro de 2019. Observe que os clusters podem aparecer em uma ordem diferente quando você executar o código. 35 3.6 Uso da clusterização para segmentar dados referentes a compra Nesta subseção vamos usar técnicas de aprendizagem não supervisionadas para segmentar dados de mercado usando hábitos de compra dos clientes.
Compartilhar