InovaTCU

  »Notícias

Aprendizado de máquina é divertido!


A introdução mais fácil do mundo a Machine Learning

Você já ouviu as pessoas falarem sobre aprendizado de máquina mas tem apenas uma vaga ideia do que isso significa?  Você está cansado de fingir estar entendendo as discussões de colegas de trabalho sobre o tema?  Vamos mudar isso!

Este guia é para qualquer um que esteja curioso sobre aprendizado de máquina mas não tenha ideia de onde começar.  Eu imagino que haja muitas pessoas que tentaram ler o artigo da Wikipedia, frustraram-se e desistiram desejando que alguém apenas desse a elas uma explicação de alto nível.  Pois aqui está essa explicação.

O objetivo é ser acessível a qualquer um – o que significa que existem muitas generalizações.  Mas quem se importa?  Se atingirmos um maior número de pessoas interessadas em ML, a missão está cumprida.

O que é aprendizado de máquina?

Aprendizado de máquina é a ideia de que existem algoritmos genéricos que podem lhe dizer algo interessante sobre um conjunto de dados sem que você tenha que escrever nenhum código específico ao problema.  Ao invés de escrever código, você alimenta o algoritmo genérico com os dados e ele constrói a sua própria logica com base nos dados.

Por exemplo, algoritmos de classificação.  Eles são capazes de colocar os dados em grupos diferentes.  O mesmo algoritmo de classificação usado para reconhecer números escritos à mão pode também ser usado para classificar e-mails em spam ou não spam sem modificar uma única linha de código.  É o mesmo algoritmo, sendo, porém, alimentado com dados de treinamento diferentes, o que leva a diferentes lógicas de classificação.

MLF-01.png

Este algoritmo de aprendizado de máquina é uma caixa-preta que pode ser reusada para muitos problemas diferentes de classificação

 

“Aprendizado de máquina” é um termo guarda-chuva que cobre muitos desses tipos de algoritmos genéricos.

Dois tipos de algoritmos de aprendizado de máquina

Você pode pensar em algoritmos de aprendizado de máquina de duas categorias principais: aprendizado supervisionado e aprendizado não supervisionado.  A diferença é simples, mas muito importante.

Aprendizado supervisionado

Vamos dizer que você seja um corretor de imóveis.  O seu negócio está crescendo, mas você contrata alguns trainees para ajudá-lo.  Mas aqui há um problema – você pode olhar para uma casa e ter uma boa ideia do seu valor, mas os seus trainees não têm a sua experiência, de modo que eles não sabem como avaliar casas.

Para ajudar seus trainees (e talvez se liberar para umas férias), você decide escrever um pequeno aplicativo que pode estimar o valor de uma casa na sua área com base em tamanho, vizinhança, etc, e por quanto casas similares foram vendidas.

Então você anota a cada vez que alguém vende uma casa na sua cidade por 3 meses.  Para cada casa, você anota um monte de detalhes – número de quartos, tamanho em metros quadrados, vizinhança, etc.  Mas mais importante, você anota o preço final de venda:

MLF-02.png

Estes são nossos “dados de treinamento”.

 

Usando esses dados de treinamento, você quer criar um programa que pode estimar quanto qualquer outra casa na sua área vale:

03.png

Nós queremos usar os dados de treinamento para prever os preços de outras casas.

 

Isso se chama aprendizado supervisionado.  Você sabia por quanto cada casa foi vendida, então, em outras palavras, você sabia a resposta para o problema e podia rastrea-la para obter a lógica utilizada.

Para construir o seu app, você alimenta o seu algoritmo de aprendizado da máquina com seus dados de treinamento sobre cada casa.  O algoritmo tenta descobrir que tipo de matemática precisa ser feita para fazer os números baterem.

É como ter o gabarito para um teste de matemática, mas com todos os símbolos aritméticos das operações apagados:

04.png

Oh não!  Um aluno malandro apagou os símbolos aritméticos do que seria o gabarito do professor!

 

A partir disso, você consegue adivinhar que tipo de problemas matemáticos estavam no teste?  Você sabe que tem que “fazer alguma coisa” com os números à esquerda para obter cada resposta à direita.

No aprendizado supervisionado, você deixa que o computador perceba esse relacionamento para você.  E uma vez que você sabe que operações matemáticas foram utilizadas para resolver esse conjunto específico de problemas, você pode responder a qualquer outro problema do mesmo tipo!

Aprendizado não supervisionado

Vamos voltar para nosso exemplo original com o corretor de imóveis.  E se você não soubesse o preço de venda de cada casa?  Mesmo que tudo o que você saiba seja o tamanho, localização, etc de cada casa, ainda assim você pode fazer algo interessante.  Isso se chama aprendizado não supervisionado.

05.png

Mesmo que você não esteja tentando prever um número desconhecido (como preço), você ainda pode fazer coisas interessantes com aprendizado de máquina.

 

É como se alguém lhe desse uma lista de números em um papel e dissesse “Eu não sei o que esses números significam, mas talvez você possa perceber se há um padrão ou agrupamento ou alguma outra coisa – boa sorte! ”

Então o que você poderia fazer com os dados?  Para iniciantes, você poderia ter um algoritmo que automaticamente identificasse diferentes segmentos de mercado nos seus dados.  Talvez você descobrisse que compradores na vizinhança próxima à universidade local realmente gosta de casas pequenas com muitos quartos, mas compradores nos subúrbios preferem casas de 3 quartos com área grande.  Saber sobre esses diferentes tipos e clientes pode ajudar a direcionar seus esforços de marketing.

Uma outra coisa legal que você pode fazer é identificar automaticamente quaisquer casas fora do padrão, diferentes de todo o resto.  Talvez essas casas fora do padrão sejam mansões gigantes e você pode focar suas melhores vendas nessas áreas porque eles rendem comissões maiores.

Aprendizado supervisionado é onde vamos focar no restante deste post, mas não porque aprendizado não supervisionado seja menos útil ou interessante.  De fato, aprendizado não supervisionado está se tornando cada vez mais importante à medida que os algoritmos se tornam melhores, porque ele pode ser usado sem ter que rotular os dados com a resposta correta.

Nota: existem muitos outros tipos de algoritmos de aprendizado de máquina.  Mas aqui é um ponto bom o suficiente para começar.

 

Legal, mas ser capaz de estimar o preço de uma casa realmente conta como “aprendizado”?

Enquanto ser humano, seu cérebro pode abordar quase qualquer situação e aprender como lidar com ela sem instruções explícitas. Se você vende casas por um longo tempo, você instintivamente possui um “sentimento” de qual o preço correto de uma casa, qual a melhor maneira de vendê-la, o tipo de cliente que se interessaria por ela etc. O alvo da pesquisa em Inteligência Artificial Forte é ser capaz de replicar essa habilidade com computadores.

No entanto, os algoritmos atuais de aprendizado de máquina ainda não são tão bons assim – eles só funcionam quando focam um problema muito específico e limitado. Talvez uma definição melhor do que “aprendizado” nesse caso seja “descobrindo uma equação para resolver um problema específico baseado em alguns dados de exemplo.”

Infelizmente, “Máquina descobrindo uma equação para resolver um problema específico baseado em alguns dados de exemplo” não é realmente um bom nome. Então, em vez disso, acabamos ficando com “Aprendizado de Máquina” (Machine Learning).

É claro que se você está lendo isto 50 anos no futuro e nós tivermos descoberto o algoritmo para Inteligência Artificial Forte, então todo este artigo vai lhe parecer um pouco ultrapassado. Talvez seja melhor parar de ler e ir dizer ao seu robô-empregado para lhe preparar um sanduíche, humano do futuro.

Vamos escrever aquele programa!

Então, como você escreveria o programa para estimar o valor de uma casa como no nosso exemplo acima? Pense nisso por um segundo antes de ler mais adiante. Se você não sabia nada sobre aprendizado de máquina, você provavelmente tentaria escrever algumas regras básicas para estimar o preço de uma casa como a seguir:

def estima_preco_venda_casa (num_de_quartos, area, vizinhanca):
   preco = 0
   # Por onde moro, o preço médio de uma casa é de
   # R$ 200 por metro quadrado (área)
   preco_por_area = 200
   if vizinhanca == "hipsterton":
      # mas algumas vizinhanças custam mais
      preco_por_area = 400
   elif vizinhanca == "skid row":
      # e algumas vizinhanças custam menos
      preco_por_area = 100
   # comece com um preço básico estimado em função do tamanho da casa
   preco = preco_por_area * área
   # agora ajuste sua estimativa em função do número de quartos
   if num_de_quartos == 0:
      # Quitinetes são baratas
      preco = preco — 20000
   else:
      # casas com mais quartos são geralmente mais caras
      preco = preco + (num_de_quartos * 1000)
return preco

 

Se você ficar ajustando esse programa por horas e horas, poderá chegar em alguma coisa que meio que funciona. Mas o seu programa nunca será perfeito e será difícil de manter à medida que os preços mudam.

Não seria melhor se o computador pudesse apenas descobrir como implementar essa função para você? Quem se importa com o que exatamente a função faz desde que ela retorne o número correto?

def estima_preco_venda_casa (num_de_quartos, area, vizinhanca):
   preco = <computador, por favor produza alguma matemática para mim>
return preco

 

Uma maneira de pensar sobre esse problema é que o preço é um delicioso ensopado e os ingredientes são o número de quartos, a metragem, e a vizinhança. Se você puder apenas descobrir o quanto cada ingrediente impacta o preço final, talvez haja uma proporção exata de ingredientes para misturar e fazer o preço final.

Isso reduziria sua função original (com todos aqueles if’s e else’s malucos) para alguma coisa simples como essa:

def estima_preco_venda_casa (num_de_quartos, area, vizinhanca):
   preco = 0
   # uma pinçada disso
   preco += num_de_quartos * 0.841231951398213
   # e um bocado daquilo
   preco += area * 1231.1231231
   # talvez um pouco disso
   preco += vizinhanca * 2.3242341421
   # e finalmente, uma pitada extra de sal para terminar
   preco += 201.23432095
return preco

 

Note os números mágicos em negrito -- 0.841231951398213, 1231.1231231, 2.3242341421, e 201.23432095. Esses são nossos pesos. Se nós apenas pudéssemos descobrir os pesos perfeitos que funcionassem para todas as casas, nossa função poderia prever preços de casas!

Um jeito burro de descobrir os melhores pesos seria algo assim:

Passo 1:

Comece com cada peso valendo 1.0:

def estima_preco_venda_casa (num_de_quartos, area, vizinhanca):
   preco = 0
   # uma pinçada disso
   preco += num_de_quartos * 1.0
   # e um bocado daquilo
   preco += area * 1.0
   # talvez um pouco disso
   preco += vizinhanca * 1.0
   # e finalmente, uma pitada extra de sal para terminar
   preco += 1.0
return preco

Passo 2:

Passe todas as casas que você conhece para sua função e veja o quão longe a função está de adivinhar o preço correto para cada casa:

06.png

Use sua função para prever o preço para cada casa.

 

Por exemplo, se a primeira casa foi realmente vendida por $ 250.000, mas sua função disse que ela seria vendida por $ 178.000, você está fora por $ 72.000 para aquela casa.

Agora some o quadrado das quantias que você está fora para cada casa no seu conjunto de dados. Vamos dizer que você tinha 500 vendas no seu conjunto de dados e o quadrado do quanto sua função estava fora para cada casa foi um valor total de $ 86.123.373. Isso é o quanto sua função está “errada” atualmente.

Agora, pegue aquela soma total e divida por 500 para obter uma média de quanto você está fora para cada casa. Chame esse erro médio de custo da sua função.

Se você puder zerar esse custo jogando com os pesos, sua função seria perfeita. Significaria que em todos os casos, sua função adivinharia perfeitamente o valor da casa baseando-se nos dados de entrada. Esse é nosso alvo – conseguir que esse custo seja o mais baixo possível por meio de experimentar diferentes pesos.

Passo 3:

Repita o passo 2 várias e várias vezes para todas as possíveis combinações de pesos. Seja qual for a combinação de pesos que torne o custo o mais próximo de zero é essa que você usará. Quando encontrar os pesos que funcionam, você terá resolvido o problema!

Momento pra pirar (Mind blowage Time)

Muito simples, não? Pense bem no que você acabou de fazer. Você pegou alguns dados, os fez passar por três passos genéricos bem simples, e terminou com uma função que consegue adivinhar o preço de qualquer casa em sua região. Fique esperto, WImóveis!

Mas aqui estão mais alguns fatos que vão impressionar você:

  1. Pesquisas dos últimos 40 anos em muitos campos (como linguística/tradução) demonstram que esses algoritmos genéricos de aprendizagem que “misturam o ensopado de números” (uma frase que eu acabei de inventar) superam abordagens onde pessoas reais tentam solucionar com regras explícitas próprias. No final, a abordagem “burra” do aprendizado de máquina supera especialistas humanos.
  2. A função que você obtém no final é totalmente burra. Ela sequer sabe o que é “metro quadrado” ou “quartos”. Tudo o que ela sabe é que precisa misturar numa certa quantidade aqueles números para obter a resposta certa.
  3. É muito provável que você não tenha ideia do porquê um grupo particular de pesos funcionará. Ou seja, você acabou de escrever uma função que você realmente não compreende, mas que pode provar que irá funcionar.
  4. Imagine que em vez de obter parâmetros como “metros quadrados” e “número de quartos”, sua função de predição receba uma lista de números. Digamos que cada número represente o brilho de um pixel numa imagem capturada por uma câmera montada no topo do seu carro. Agora, digamos que em vez de retornar uma previsão chamada “preço”, a função retornasse uma previsão chamada “graus para virar o volante”. Você acabou de criar uma função que pode dirigir seu carro por si mesma!

Muito louco não?

 

E quanto àquele "teste cada número" no Passo 3?

Ok, é claro que você não pode simplesmente testar todas as combinações de todos os possíveis pesos para encontrar a combinação que funciona melhor. Isso literalmente demoraria uma eternidade visto que você nunca esgotaria os números para testar.

Para evitar isso, os matemáticos descobriram muitas maneiras espertas para encontrar rapidamente bons valores para esses pesos sem ter que experimentar muitos. Eis uma maneira:

Primeiro, escreva uma simples equação que representa o Passo 2, acima:

07.png

Esta é a sua função de custo.

 

Agora vamos reescrever exatamente a mesma equação, mas usando um monte de jargão matemático do aprendizado de máquina (que você pode ignorar por hora):

08.png

θ é o que representa os seus pesos atuais. J(θ) significa o "custo para os seus pesos atuais'.

 

Esta equação representa o quão errada a nossa função de estimativa de preço encontra-se para os pesos que utilizamos nesse momento.

Se desenharmos o gráfico dessa equação de custo para todos os possíveis valores de nossos pesos para o num_de_quartos e area, teríamos um gráfico que poderia se parecer com o seguinte:

09.png

O gráfico da nossa função de custo parece uma tigela. O eixo vertical representa o custo.

 

Neste gráfico, o ponto mais baixo em azul é onde o nosso custo é o menor - portanto, a nossa função está menos errada. Os pontos mais altos são onde estamos mais errados. Então, se pudermos encontrar os pesos que nos levam ao ponto mais baixo deste gráfico, teremos a nossa resposta!

10.png

Então, só precisamos ajustar nossos pesos para que estejamos "caminhando numa descida de encosta" neste gráfico para o ponto mais baixo. Se continuarmos a fazer pequenos ajustes para os nossos pesos que estão sempre se movendo em direção ao ponto mais baixo, acabaremos chegando lá sem ter que testar muitos pesos diferentes.

Se você consegue se lembrar de algo de Cálculo, você talvez lembre que se você tomar a derivada de uma função, ela informa a inclinação da tangente da função para qualquer ponto. Em outras palavras, ela nos diz qual é o caminho para descer a partir de qualquer ponto em nosso gráfico. Nós podemos usar esse conhecimento para descer a encosta.

Então, se nós calcularmos uma derivada parcial da nossa função de custo em relação a cada um dos nossos pesos, então poderemos subtrair esse valor de cada peso. Isso nos fará andar um passo mais perto do fundo do vale. Continue fazendo isso e, eventualmente, chegaremos ao fundo do vale e assim teremos os melhores valores possíveis para os nossos pesos. (Se isso não fizer sentido, não se preocupe e continue lendo).

Isso é o esboço de um resumo de uma maneira de encontrar os melhores pesos para a sua função chamada descida de gradiente por lote. Não tenha medo de aprofundar caso tenha interesse em aprender os detalhes.

Quando você usa uma biblioteca de aprendizado de máquina para resolver um problema real, tudo isso será feito para você. Mas ainda é útil ter uma boa ideia do que está acontecendo.

 

O que mais você achou conveniente pular?

O algoritmo em três etapas que eu descrevi é chamado de regressão linear múltipla. Você está estimando a equação de uma linha que passa através de todos os seus pontos com os dados de casas. Então você está usando essa equação para adivinhar o preço de venda de casas que você nunca viu antes com base na posição em que aquela casa apareceria em sua linha. É uma ideia realmente poderosa e com a qual você pode resolver problemas "reais".

Mas, ainda que a abordagem que mostrei possa funcionar em casos simples, não irá funcionar em todos os casos. Uma das razões é porque os preços das casas nem sempre são simples o suficiente para seguir uma linha contínua.

Mas, felizmente, há muitas maneiras de lidar com isso. Há uma abundância de outros algoritmos de aprendizado de máquina que podem lidar com dados não-lineares (como redes neurais ou Máquina de Vetores de Suporte (SVMs) com kernels). Há também formas de usar regressão linear de forma mais esperta que permite criar linhas mais complexas para serem ajustadas. Em todos os casos, a mesma ideia de base da necessidade de encontrar os melhores pesos ainda se aplica.

Além disso, eu deixei de lado a ideia de sobreajustamento (overfitting). É fácil chegar a um conjunto de pesos que sempre funciona perfeitamente para prever os preços das casas em seu conjunto de dados original, mas que nunca realmente funciona para quaisquer novas casas que não estejam em seu conjunto de dados original. Mas existem maneiras de lidar com isso (como regularização e usando um conjunto de dados para validação cruzada). Aprender a lidar com esta questão é uma parte fundamental em aprender a aplicar o aprendizado de máquina com sucesso.

Em outras palavras, enquanto o conceito básico é muito simples, é preciso alguma habilidade e experiência para aplicar o aprendizado de máquina e obter resultados úteis. Mas é uma habilidade que qualquer desenvolvedor pode aprender!

 

O aprendizado de máquina é magia?

Uma vez que você começar a ver o quão facilmente as técnicas de aprendizado de máquina podem ser aplicadas a problemas que parecem muito difíceis (como o reconhecimento de escrita), você começa a ter a sensação de que você poderia usar o aprendizado de máquina para resolver qualquer problema e obter uma resposta, desde que você tenha dados suficientes. Basta alimentar os dados e ver o computador magicamente descobrir a equação que se ajusta aos dados!

Mas é importante lembrar que o aprendizado de máquina só funciona se o problema é realmente solucionável com os dados que você tem.

Por exemplo, se você construir um modelo que prevê preços de casas com base no tipo de vasos de plantas em cada casa, ele nunca vai funcionar. Simplesmente não há qualquer tipo de relação entre os vasos de plantas em cada casa e preço de venda da casa. Portanto, não importa o quão arduamente tente, o computador nunca poderá deduzir uma relação entre os dois.

11.png

Você só pode modelar relacionamentos que realmente existam.

 

Assim lembre-se, se um perito humano não puder utilizar os dados para resolver o problema manualmente, um computador, provavelmente, não será capaz tampouco. Em vez disso, concentre-se em problemas nos quais um ser humano poderia resolver o problema, mas em que seria ótimo se um computador pudesse resolvê-lo muito mais rapidamente.

Como aprender mais sobre Aprendizado de Máquina

Na minha opinião, o maior problema com aprendizado de máquina no momento é que ela se encontra, majoritariamente, no mundo da academia e em grupos de pesquisa corporativos. Não há muito material fácil de entender por aí, para as pessoas que gostariam de obter um amplo entendimento sem realmente tornarem-se especialistas. Mas está ficando um pouco melhor a cada dia.

O curso gratuito de Andrew Ng, Aprendizado de Máquina no Coursera, é bastante incrível. Eu altamente recomendo começar por lá. O curso poder ser acessível a qualquer um que tenha uma gradução em ciências da computação e que se lembra de uma quantidade mínima de matemática.

Além disso, você pode brincar com toneladas de algoritmos de aprendizado de máquina, baixando e instalando SciKit-Learn. É uma biblioteca de funções em python que tem versões "caixa preta" de todos os algoritmos mais comuns.

________________________________________

Se você gostou deste artigo, por favor, considere inscrever-se para a minha lista de email "Machine Learning is Fun!". Eu só vou enviar e-mail para você quando tiver algo novo e impressionante para compartilhar. É a melhor forma para ficar sabendo quando eu escrever mais artigos como este.

Você também pode me seguir no Twitter em @ageitgey, enviar-me correio eletrônico diretamente ou encontrar-me no LinkedIn. Eu adoraria ouvir de você se eu puder ajudá-lo ou a sua equipe com aprendizado de máquina.

Agora continue com "Aprendizado de Máquina é divertido" Parte 2, Parte 3, Parte 4 e Parte 5!

Adam Geitgey

[traduzido por Monique Monteiro, Jocelino Mendes e Erick Muzart, a partir do original]

12/09/2016



Voltar