Tutorial de Machine Learning com Python - Iniciantes - Parte 1



Este tutorial tem como objetivo explicar apenas o necessário para que qualquer pessoa, possa iniciar sua caminhada em Ciência de Dados. 
Abordaremos as principais ferramentas que um Cientista de Dados na linguagem Python, não pode deixar de utilizar.
Criamos este material para pessoas que ainda não possuem o ferramental matemático avançado de machine learning. Apresentaremos exemplos mais simples como introdução para motivar os iniciantes
O tutorial é dividido em duas partes, sendo a segunda parte publicada posteriormente á publicação da primeira. Como dados utilizaremos um dataset bem conhecido no universo de data science, que é o Pokemons, muito utilizado para fins acadêmicos, como é este caso.


O cientista de dados precisa ter as seguintes habilidades:


  1. Ferramentas básicas: como python, R ou SQL. Você não precisa saber tudo. O que você só precisa é aprender a usar python.
  2. Estatística Básica: Como média, mediana ou desvio padrão. Se você conhece estatísticas básicas, pode usar o python facilmente.
  3. Data Munging/Wrangling: trabalhando com dados confusos e difíceis. Como uma data inconsistente e formatação de string. O Python é uma ajuda precios
  4. Visualização de dados: o título é realmente explicativo. Visualizaremos os dados com python, como matplot e seaborn.
  5. Aprendizado de máquina (Machine Learning): você não precisa entender(por agora) a matemática por trás da técnica de aprendizado de máquina, por trás de cada função, com o tempo e á medida que irá adquirir mais experiência o interesse pelo "motor" que faz  cada função funcionar, o desejo e capacidade de fazer algoritmos do zero, irão surgir, e aí o nível de aprendizado e técnicas será outro, para um iniciante e de forma a desmistificar o universo de Ciência de Dados que muitas vezes e torna assustador para quem começa, você só precisa entender o básico do aprendizado de máquina e aprender como implementá-lo enquanto estiver usando o python.

Conteúdo do Tutorial

  1. Introdução ao Python
    • Matplotlib
    • Dicionários
    • Pandas
    • Lógica, controle de fluxo e filtragem
    • Estruturas de dados em loop
  2. Caixa de ferramentas de ciência de dados do Python:
    • Função definida pelo usuário
    • Escopo
    • Função aninhada
    • Argumentos padrão e flexíveis
    • Função Lambda
    • Função anônima
    • Iteradores
    • Compreensão de lista
  3. Higienização de Dados
    • Diagnosticar dados para limpeza
    • Análise exploratória de dados
    • Análise visual exploratória dos dados
    • Dados organizados
    • Dados dinâmicos
    • Concatenando dados
    • Tipos de dados
    • Dados ausentes e testes com afirmações
  4. Função do Pandas
    • Revisão do pandas
    • Construindo quadros de dados a partir do zero
    • Análise visual exploratória dos dados
    • Análise estatística exploratória dos dados
    • Indexação de séries temporais com pandas
    • Reamostragem de séries temporais com pandas
  5. Manipulando Data Frames com o Pandas
    • Indexando data frames
    • Cortando data frames
    • Filtrando data frames
    • Transformando data frames
    • Objetos de índice e dados rotulados
    • Indexação hierárquica
    • Data frames dinâmicos
    • Empilhamento e desempilhar data frames
    • Unpivot data frames
    • Categorias e grupos
  6. Visualização de Dados
    • Seaborn
    • Bokeh
  7. Pensamento Estatístico
  8. Machine Learning (Aprendizado de Máquina)
    • Aprendizado Supervisionado
      • EDA (Análise Exploratória de Dados)
      • K-Nearest Neighbors (KNN)
      • Regressão
      • Cross Validation (CV) - Validação Cruzada
      • ROC Curve (Curva ROC - Característica de Operação do Receptor)
      • Ajuste do hiperparâmetro
      • Pré-Processamento de Dados
    • Aprendizado Não Supervisionado
      • Kmeans Clustering (Clusterização Kmeans)
      • Avaliação de Clustering
      • Estandardização
      • Hierarquia
      • T - Distributed Stochastic Neighbor Embedding (T - SNE)
      • Análise de Componentes Principais (PCA)
  9. Aprendizado Profundo (Deep Learning)
  10. Predição de Séries Temporais
  11. Deep Learning com Pytorch
    • Artificial Neural Network (Redes Neurais Artificiais)
    • Convolutional Neural Network (Redes Neurais Convulsionais)
    • Recurrent Neural Network (Redes Neurais Recorrentes)



Iniciamos o nosso projeto importando as principais bibliotecas do Python e as que mais utilizaremos neste tutorial.



Os arquivos de dados de entrada estão disponíveis no diretório "../input/". Por exemplo, executar isso (clicando em executar ou pressionando Shift + Enter) listará os arquivos no diretório de entrada




Necessitamos de analisar nossos dados antes de iniciar qualquer processo de ML (Machine Learning)




Vamos agora usar a função coor() para visualizar a correlação dos dados



De forma a termos uma análise mais prática da correlação, iremos plotar os dados.



O resultado é o seguinte:




Após a análise de correlação dos dados, podemos obter um resumo do nosso data set



Obtendo somente as colunas do nosso data set





1. INTRODUÇÃO AO PYTHON

MATPLOTLIB 

Matplot é uma biblioteca python que nos ajuda a plotar dados. Os gráficos mais fáceis e básicos são gráficos de linha, dispersão e histograma.
  • O gráfico de linhas é melhor quando o eixo x é o tempo.
  • A dispersão é melhor quando há correlação entre duas variáveis
  • O histograma é melhor quando precisamos ver a distribuição dos dados numéricos.
  • Personalização: cores, rótulos, espessura da linha, título, opacidade, grade, tamanho, marcas do eixo e estilo de linha




O resultado da plotagem em gráfico de linhas:



O mesmo resultado em gráfico de dispersão:




Em histograma:



Em seguida utilizaremos a função clf() que limpa novamente, você pode iniciar um novo. Não podemos ver o gráfico devido a clf()






DICIONÁRIO 

Por que precisamos de dicionário?
  • Possui 'chave' e 'valor'
  • Mais rápido que as listas
    • O que é chave e valor. Exemplo:
    • dictionary = {'espanha': 'madrid'}
  • Key é a Espanha.
  • Valores é madrid.
É tão fácil! Vamos praticar algumas outras propriedades como keys(), values(), atualizar, adicionar, verificar, remover chave, remover todas as entradas e remover dicionário.

Vamos criar dicionário  e procurar suas chaves e valores:



As chaves devem ser objetos imutáveis, como string, booleano, float, número inteiro ou tubos já as listas não são imutáveis, porém as chaves são únicas.



Para executar todo o código, você precisa comentar esta linha

  • del dictionary         

Irá dar um erro, pois o dicionário foi deletado





PANDAS

O Pandas é uma biblioteca Python que fornece estruturas e ferramentas de análise de dados. Como ela possui uma interface simples, acredito que qualquer pessoa que goste da área, não apenas desenvolvedores, com algum tempo de estudo, seja capaz de analisar e tirar suas próprias conclusões acerca de sua base de dados.
  • CSV: valores separados por vírgula

Vamos efetuar uma carga do dataset usando a função read_csv()




Antes de continuar com os pandas, precisamos aprender lógica, controlar o fluxo e a filtragem. Operador de comparação: ==, <,>, <= Operadores booleanos: and, or, not.

Filtrando pandas

Utilizaremos agora operadores de comparação e booleanos



Agora vamos realizar um filtro comum onde só exibiremos os dados dos Pokemons com o atributo 'defense' maior que 200



Podemos incrementar mais do que um filtro, desta vez adicionaremos ao nosso filtro os Pokemons que alem do atributo "defense" maior que 200, também tenham o atributo 'Attack' maior que 100.



Podemos fazer o mesmo filtro acima, mas utilizando o '&'





WHILE e FOR LOOPS

Iremos aprender o mais básico por enquanto, no que diz respeito a estas duas estruturas de repetição.
Neste exemplo o código permanece em loop se a condição (i não for igual a 5) for verdadeira



Já neste caso pedido ao código que permaneça em loop se a condição (i não for igual a 5) for verdadeira.



Podemos usar loop em dicionários também, como mostrado nas seguintes linhas de código




Até aqui você aprendeu:

  • como importar arquivo csv
  • plotar gráficos de linha, dispersão e histograma
  • recursos básicos do dicionário
  • recursos básicos dos pandas, como a filtragem, que na verdade é algo sempre usado em ciência de dados
  • While e for loops


2. FERRAMENTA DE CIÊNCIA DE DADOS PYTHON

FUNÇÃO DEFINIDA PELO USUÁRIO

O que precisamos saber sobre funções:
  • docstrings: documentação para funções.
    • exemplo: para f():
    • "" "Esta é a documentação para a documentação da função f" ""
  • tuble: sequência de objetos python imutáveis. não é possível modificar valores tuble usa parênteses como tuble = (1,2,3) descompacte o tuble em várias variáveis como a, b, c = tuble


ESCOPO

O que precisamos saber sobre o escopo:
  • global: corpo principal definido no script
  • local: definido em uma função
  • escopo incorporado: nomes no módulo de escopo incorporado predefinido, como print, len
Vamos fazer alguns exemplos básicos

E se não houver escopo local?



Vejamos um pouco mais da construção de escopo




FUNÇÕES ANINHADAS

  • função dentro da função.
  • Existe uma regra LEGB que busca o escopo local, incluindo a função, escopos globais e internos, respectivamente.



ARGUMENTOS PADRÃO E FLEXÍVEIS

  • Exemplo de argumento padrão: def f (a, b = 1):
    • "" "b = 1 é o argumento padrão" ""
  • Exemplo de argumento flexível: def f (* args):
    • """ args can be one or more"""
  • def f(** kwargs)
    • """ kwargs is a dictionary"""
Vamos escrever algum código para praticar



Vejamos os argumentos flexíveis (args) e argumentos flexíveis em dicionários (kwargs)





FUNÇÃO LAMBDA

Funções lambda nada mais são do que funções anônimas. Enquanto funções normais podem ser criada utilizando def como prefixo, as funções lambda são criadas utilizando lambda. Vale notar que as funções lambda não utilizam a keyword return pois o retorno dentro de lambda é implícito.
Mas para que servem essas funções lambda?
Funções lambda funcionam da mesma forma que funções convencionais e, em geral, a escolha de adotar ou não seu uso é exclusivamente baseada em estilo de código.
  1. Maneira mais rápida de escrever a função



FUNÇÕES ANÔNIMAS

Como a função lambda, mas pode levar mais de um argumento.
  • map(func, seq): aplica uma função a todos os itens em uma lista



ITERADORES

  • Iterável é um objeto que pode retornar um iterador
  • Iterável: um objeto com um método iter() associado
    • exemplo: lista, strings e dicionários
  • Iterador: produz o próximo valor com o método next()


COMPREENSÃO DA LISTA

Um dos tópicos mais importantes deste artigo
Usamos a compreensão da lista para análise de dados frequentemente. compreensão da lista: recolhimento de loops para criar listas em uma única linha Ex: num1 = [1,2,3] e queremos torná-lo num2 = [2,3,4]. Isso pode ser feito com o loop for. No entanto, é desnecessariamente longo. Podemos torná-lo um código de linha que é a compreensão da lista.


  • [i + 1 for i in num1]: lista de compreensão
  • i +1: sintaxe de compreensão da lista
  • for i in num1: simntaxe do loop for
  • i: iterador
  • num1: objeto iterável



Vamos retornar pokemon csv e fazer mais um exemplo de compreensão de lista, iremos classificar os pokemons com velocidade alta ou baixa. Nosso limite é a velocidade média.



O que você aprendeu até agora


  • Função definida pelo usuário
  • Escopo
  • Funções Aninhadas
  • Argumentos padrão e flexíveis
  • Função Lambda
  • Função Anônima
  • Iteradores
  • Compreensão de Lista


LIMPEZA DE DADOS

DADOS DE DIAGNÓSTICO PARA LIMPEZA
Precisamos diagnosticar e limpar dados antes de explorar.
Dados impuros:
  • Inconsistência no nome da coluna, como letra maiúscula ou espaço entre as palavras
  • valores faltando
  • tipos/linguagens diferentes
Usaremos métodos de head, tail, columns, shape e metodos de informação para diagnosticar dados
Com a função head() selecionamos somente as primeiras linhas do dataset



A função tail() mostra as últimas 5 linhas



A função columns() fornece nomes de colunas dos recursos



A função shape() fornece o número de linhas e colunas em tupla



Já a função info() fornece tipos de dados como quadro de dados, número de amostra ou linha, número de recurso ou coluna, tipos de recurso e uso de memória



ANÁLISE EXPLORATÓRIA DE DADOS

value_counts(): contagem de frequência outliers: o valor que é consideravelmente mais alto ou mais baixo do restante dos dados
  • Digamos que o valor de 75% seja Q3 e o valor de 25% seja Q1.
  • Os outliers são menores que Q1 - 1,5 (Q3-Q1) e maiores que Q3 + 1,5 (Q3-Q1). (Q3-Q1) = IQR Usaremos o método descrevem (). O método Descrever inclui:
    • count: número de entradas
    • mean: média de entradas
    • std: desvio padrão
    • min: entrada mínima
    • 25%: primeiro quartil
    • 50%: mediana ou segundo quartil
    • 75%: terceiro quartil
    • max: entrada máxima
O que é quartil?
  • exemplo: 1,4,5,6,8,9,11,12,13,14,15,16,17
  • A mediana é o número que está no meio da sequência. Nesse caso, seria 11.
  • O quartil inferior é a mediana entre o menor número e a mediana, ou seja, entre 1 e 11, que é 6.
  • No quartil superior, você encontra a mediana entre a mediana e o maior número, ou seja, entre 11 e 17, que será 14 de acordo com a pergunta acima.

Por exemplo, vamos ver a frequência dos tipos de pokemom, se houver valores nan que também serão contados, como pode ser visto abaixo, existem 112 pokemon de água ou 70 pokemon de grama



Por exemplo, o max HP é 255 ou a min defense é 5


ANÁLISE VISUAL DE DADOS EXPLORATÓRIOS

Box Plot (gráficos de caix): visualiza estatísticas básicas, como outliers, min / max ou quartis
Por exemplo:
compare o ataque de pokemons lendários ou não, vejamos como fica o gráfico

  • A linha preta no topo é máxima
  • A linha azul na parte superior é de 75%
  • Linha vermelha é mediana (50%)
  • A linha azul na parte inferior é de 25%
  • A linha preta na parte inferior é mínima
  • Não há outliers



DADOS ORDINÁRIOS

Organizamos os dados com a função melt(). Esta função é útil para "modelar" um DataFrame em um formato em que uma ou mais colunas são variáveis identificadoras (id_vars), enquanto todas as outras colunas, consideradas variáveis medidas (value_vars), são "não dinâmicas" para o eixo da linha, deixando apenas dois não identificadores colunas, 'variável' e 'valor'.
Em primeiro lugar, crio novos dados a partir de dados de pokemons para explicar facilmente o melt().


Veja como usamos o met() e os resultados de saída:



DADOS PIVOTANTES / PIVOTAR DADOS

É o oposto do melt().
Retorne o DataFrame reformulado, organizado pelos valores de índice / coluna fornecidos.
Remodele os dados (produza uma tabela dinâmica) com base nos valores da coluna. Usa valores exclusivos de índices / colunas especificados para formar eixos do DataFrame resultante. Esta função não suporta agregação de dados, vários valores resultarão em um MultiIndex nas colunas

  • Index é nome
  • Eu quero fazer com que as colunas sejam variáveis
  • Finalmente, os valores nas colunas são valor


CONCATENANDO DADOS / DADOS CONCATENANTES

Podemos concatenar dois dataframes
Em primeiro lugar, vamos criar 2 dataframes, nesta parte do código , axis = 0: adiciona dataframes na linha, vejamos o código:




TIPOS DE DADOS

Existem 5 tipos de dados básicos: objeto (string), booleab, número inteiro, float e categórico. Podemos criar tipos de dados de conversão como str para categórico ou int para flutuantes Por que a categoria é importante:
  • tornar o quadro de dados menor na memória
  • pode ser utilizado para analises especialmente para sklear (aprenderemos mais adiante)

Vamos  converter o objeto (str) em categórico e int em flutuante


Como você pode ver, o Tipo 1 é convertido de objeto em categórico e Speed, é convertido de int para float


FALTA DE DADOS E TESTE COM ASSERT
Se encontrarmos dados ausentes, o que podemos fazer:
  • deixe como está
  • apague-os com dropna()
  • preencha os espaços vazios com fillna()
Declaração de afirmação: verifique se você pode ativar ou desativar quando terminar o teste do programa
Vamos analisar se os dados de pokemon têm valor nan, como você pode ver, existem 800 entradas. No entanto, o Tipo 2  possui 414 objetos não nulos e, portanto, 386 objetos nulos.


Vamos verificar o Tipo 2 e como você pode ver, há 386 valores NAN:


Agora valos apagar os valores NaN e também usaremos dados para preencher o valor que falta, então eu os atribuo à variável data1.

  • inplace = True significa que não o atribuímos a uma nova variável




Vamos verificar com declaração assert que é uma  declaração de afirmação (Assert statement), neste caso não vai retornar nada porque é 'verdade':


 Para executar todo o código, precisamos comentar esta linha:

  • assert 1 == 2 


Com Declaração de afirmação (Assert statement), podemos verificar muita coisa.
  • Por exemplo
    • assert data.columns [1] == 'Name'
    • assert data.Speed.dtypes == np.int
Até aqui você aprendeu:
  • Diagnosticar dados para limpeza
  • Análise exploratória de dados
  • Análise visual exploratória dos dados
  • Dados organizados
  • Dados dinâmicos
  • Concatenando dados
  • Tipos de dados
  • Dados ausentes e testes com assert

PANDAS FOUNDATION

REVISÃO DO PANDAS
Como você percebeu, eu não dou todas as idéias ao mesmo tempo. Embora aprendamos algumas noções básicas de pandas, vamos nos aprofundar aos poucos nospandas.
  • coluna única(single column) = série (series)
  • NaN = não é um número
  • dataframe.values = numpy
CONSTRUIR DATA FRAMES
  • Podemos construir quadros de dados a partir do csv como fizemos anteriormente.
  • Também podemos construir dataframe a partir de dicionários
    • método zip(): Esta função retorna uma lista de tuplas, em que a i-ésima tupla contém o i-ésimo elemento de cada uma das seqüências de argumentos ou iteráveis.
  • Adicionando nova coluna
  • Transmissão (Broadcasting): crie uma nova coluna e atribua um valor a toda a coluna
 Vamos construir um dataframe a partir de um dicionário:


Para adicionar novas colunas:


Executando Broadcasting:



ANÁLISE VISUAL DE DADOS EXPLORATÓRIOS

  • Plot (plotagem)
  • Subplot (sub plotagem)
  • Histograma:
    • caixas(bins): número de caixas
    • range (tuble): valores mínimo e máximo de caixas
    • normed(booleano): normalize ou não cumulativo (booleano): computa distribuição cumulativa
Se plotarmos todos os dados de uma vez, vai ficar muito confuso de interpretar


Para facilitar a interpretação dos dados no gráfico vamos aplicar a função subplot():




Plotando os mesmos dados com scaterplot


Desta vez plotamos um histograma



A função subplot() também pode ser aplicada para histogramas




ANÁLISE ESTATÍSTICA DE DADOS EXPLORATÓRIOS

Eu já expliquei isso em partes anteriores. No entanto, vamos olhar mais uma vez.
  • count: número de entradas
  • mean: média de entradas
  • std: desvio padrão
  • min: entrada mínima
  • 25%: primeiro quantil
  • 50%: mediana ou segundo quantil
  • 75%: terceiro quantil
  • max: entrada máxima


INDEXAÇÃO DE SÉRIES TEMPORAIS COM PANDAS

  • datetime = objeto parse_dates(boolean): Transforme a data no formato ISO 8601 (aaaa-mm-dd hh: mm: ss)


 Agora podemos selecionar de acordo com nosso índice de datas, após o trabalho acima efetuado



O resultado é o seguinte:


REAMOSTRAGEM DE SÉRIE TEMPORAL COM PANDAS

  • Resampling: método estatístico em diferentes intervalos de tempo
    • Precisa de string para especificar a frequência como "M" = mês ou "A" = ano
  • Downsampling: reduza as linhas de data e hora para uma frequência mais lenta, como de diária para semanal
  • Upsampling: aumente as linhas de data e hora para uma frequência mais rápida, como diariamente para a cada hora
  • Interpolate: interpole valores de acordo com diferentes métodos, como "linear", "tempo" ou índice "
Usaremos o data2 que criamos na parte anterior:


Vamos usar Resampling com o mês:
Como você pode ver, existem muitas nan porque o data2 não inclui todos os meses


Na vida real (os dados são reais. Não criados por nós como o data2),  podemos resolver esse problema com interpolação (interpolate), podemos interpolar a partir do primeiro valor:


Ou podemos interpolar com o mean():


MANIPULAR QUADROS DE DADOS COM PANDAS

INDEXAR DATAFRAMES
  • Indexando usando colchetes
  • Usando atributo de coluna e rótulo de linha
  • Usando loc accessor
  • Selecionando apenas algumas colunas
Vamos efetuar a leitura de dados:


Vamos indexar os dados de várias formas; usandp colchetes, usando o atributo de coluna e rótulo de linha,  o loc accessor, e por fim selecionaremos apenas algumas colunas



SLICING (fatiando) DATA FRAME

  • Diferença entre selecionar colunas
    • Séries e Dataframes
  • Indexando e fatiando (slicing) séries
  • Corte reverso (Reverse Slicing)
  • De algum lugar até fim
 Vejamos agora a diferença entre fatiar (slicing) colunas: séries e dataframes


Fatiando (slicing) e indexando séries:


E como ficariam os dados se aplicarmos um reverse slicing?


FILTRANDO DATA FRAMES

Criando séries booleanas Combinando filtros Filtrando outras colunas com base

Para criar séries booleanas usamos o exemplo abaixo:

Combinando filtros:

Pode ser efetuado filtros  de colunas cm base em outras:

TRANSFORMANDO DADOS

  • Funções simples de python
  • Função Lambda: para aplicar a função python arbitrária a todos os elementos
  • Definindo Coluna Usando Outras Coluna

Ou também de uma forma simples podemos usar a função Lambda:

Outra coisa interessante que podemos fazer é definir Coluna Usando Outras Colunas

INDEXAÇÃO DE OBJETOS E RÓTULOS DE DADOS

  • índice: sequência do rótulo

Para modificarmos o índice, precisamos de mudar todos eles, inicialmente devemos efetuar uma cópia dos nossos dados para o objeto data3 e depois alterar o índice.
Iremos fazer com que o índice comece a partir de 100. Não é uma mudança notável, mas é apenas um exemplo


Podemos criar uma das colunas como índice. Na verdade, eu fiz isso no início da manipulação do dataframe com a seção pandas Foi assim:
  • data = data.set_index ("#")
    • também você pode usar
      • data.index = data ["#"]

INDEXAÇÃO HIERÁRQUICA

  • Definindo e configurando a indexação
O código abaixo permite ler o dataframe mais uma vez para começar do início.  Como você pode ver, existe um índice. No entanto, queremos definir uma ou mais colunas para serem indexadas.


Para definir o índice: tipo 1 é externo Tipo 2 é índice interno


PIVOTANDO DATAFRAMES

  • pivoting: ferramenta de remodelação


EMPILHAMENTO E DESEMPILHAMENTO DE DATAFRAME

  • lidar com índices de rótulos múltiplos
  • nível (level): posição do índice não empilhado
  • swaplevel: altera a posição do índice de nível interno e externo


Agora vamos mostrar como alterar a posição do índice de nível interno e externo:


MELTING DATA FRAMES

  • o posto de pivotar dataframes

CATEGORIAS E GROUP BY

Voltamos a usar o dataframe criado, o df.



No próximo bloco de código podemos escolher um dos recursos ou vários recursos.



Como você pode ver, o gênero é objeto. No entanto, se usarmos groupby, podemos converter dados categóricos.
Como os dados categóricos usam menos memória, acelere operações como agrupar df ["gênero"] = df ["gênero"]. astype ("categoria") e df ["tratamento"] = df ["tratamento"]. astype ("categoria")


E pronto, a primeira parte do tutorial fica por aqui, de forma que não fique muito extenso e se torno confuso.
Brevemente lançarei a segunda parte do tutorial com informação um pouquinho mais complexas.

Espero que este tutorial seja útil para vocês e se tiveram alguma dúvida ou sujestão, basta deixarem vosso comentário no artigo.  

Podem obter o notebook completo no meu kaggle:

Ou no meu Git Hub:

Obrigado, um forte abraço e bons estudos!!

Referências:



Comentários

Postar um comentário

Postagens mais visitadas deste blog

Regressão Múltipla com R

Tutorial de Machine Learning com Python - Iniciantes - Parte 2