You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ML-For-Beginners/4-Classification/1-Introduction/translations/README.pt-br.md

14 KiB

Introdução à classificação

Nestas quatro lições, você explorará um foco fundamental da aprendizagem de máquina clássica - classificação. Usaremos vários algoritmos de classificação com um datset (conjunto de dados) sobre todas as cozinhas brilhantes da Ásia e da Índia. Espero que esteja com fome!

Só uma pitada!

Celebre a cozinha pan-asiática nestas aulas! Imagem por Jen Looper.

A classificação é uma forma de aprendizado supervisionado que tem muito em comum com as técnicas de regressão. O aprendizado de máquina tem tudo a ver com prever valores ou nomes para coisas usando datasets. A classificação geralmente se divide em dois grupos: classificação binária e classificação de multiclasse.

Introdução à classificação

🎥 Clique na imagem acima para ver o vídeo: John Guttag do MIT introduz classificação (vídeo em inglês).

Lembre-se:

  • A regressão linear ajudou a prever relações entre variáveis e fazer previsões precisas sobre onde um novo ponto de dados cairia em relação a uma linha. Então, você poderia prever que preço teria uma abóbora em setembro vs. dezembro, por exemplo.
  • A regressão logística ajudou a descobrir "categorias binárias": em uma faixa de preço, essa abóbora é laranja ou não?

A classificação usa vários algoritmos para determinar outras maneiras de determinar o rótulo ou a classe de um ponto de dados ou objeto. Vamos trabalhar com dados sobre culinária para ver se, observando um grupo de ingredientes, podemos determinar sua culinária de origem.

Questionário inicial

Esta lição está disponível em R!

Introdução

Classificação é uma das atividades fundamentais do pesquisador de aprendizado de máquina e cientista de dados. Desde a classificação básica de um valor binário ("este e-mail é spam ou não?"), até a classificação e segmentação de imagens complexas usando visão computacional, é sempre útil ser capaz de classificar os dados em classes e fazer perguntas sobre eles.

Para declarar o processo de uma maneira mais científica, seu método de classificação cria um modelo preditivo que permite mapear o relacionamento entre as variáveis de entrada e as variáveis de saída.

Classificação binária vs multiclasse

Problemas binários vs. multiclasse para algoritmos de classificação lidarem. Infográfico por Jen Looper.

Antes de iniciar o processo de limpar, visualizar e preparar nossos dados para tarefas de ML, vamos aprender um pouco sobre as várias maneiras pelas quais o aprendizado de máquina pode ser usado ao classificar dados.

Derivado da estatística, a classificação no aprendizado de máquina clássico usa características como fumante, peso e idade para determinar a possibilidade de desenvolver a doença X. Como uma técnica de aprendizado supervisionado semelhante aos exercícios de regressão que você realizou anteriormente, seus dados são rotulados e os algoritmos de ML usam esses rótulos para classificar e prever classes (ou 'características') de um dataset e atribuí-los a um grupo ou resultado.

Imagine um dataset sobre culinárias. O que um modelo multiclasse seria capaz de responder? O que um modelo binário seria capaz de responder? E se você quisesse determinar se uma determinada cozinha usaria feno-grego? E se você quisesse ver se usando uma sacola de supermercado cheia de anis estrelado, alcachofras, couve-flor e raiz-forte, você poderia criar um prato típico indiano?

Cestas de mistério malucas

🎥 Clique na imagem acima para assistir a um vídeo (em inglês). O foco de cada episódio do programa 'Chopped' é a 'cesta misteriosa' onde os chefs têm que fazer um prato a partir de uma escolha aleatória de ingredientes. Certamente um modelo de ML teria ajudado!

Olá 'classificador'

A pergunta que queremos fazer sobre este dataset de culinária é, na verdade, uma questão multiclasse, pois temos várias cozinhas nacionais em potencial para trabalhar. Dado um lote de ingredientes, em qual dessas muitas classes os dados se encaixam?

Dependendo do tipo de problema que você deseja resolver, o Scikit-learn oferece vários algoritmos diferentes para classificar dados. Nas próximas tarefas, você aprenderá sobre esses algoritmos.

Exercício - limpe e balanceie seus dados

A primeira tarefa, antes de iniciar este projeto, é limpar e balancear seus dados para obter melhores resultados. Comece com o arquivo notebook.ipynb na raiz da pasta desta tarefa.

A primeira coisa a instalar é o imblearn. O imblearn é um pacote Scikit-learn que permitirá que você balanceie melhor os dados (vamos aprender mais sobre isso já já).

  1. Para instalar o imblearn, rode pip install:

    pip install imblearn
    
  2. Importe os pacotes que você precisa para obter seus dados e visualizá-los, importe também a classe SMOTE.

    import pandas as pd
    import matplotlib.pyplot as plt
    import matplotlib as mpl
    import numpy as np
    from imblearn.over_sampling import SMOTE
    

    Agora você está pronto para obter os dados do dataset.

  3. O próximo passo é obter os dados do dataset a ser usado:

    df  = pd.read_csv('../data/cuisines.csv')
    

    Usando o método read_csv(), leremos o conteúdo do arquivo csv cusines.csv e colocaremos na variável df.

  4. Vamos observar o formato dos dados:

    df.head()
    

    As primeiras cinco linhas são assim:

    |     | Unnamed: 0 | cuisine | almond | angelica | anise | anise_seed | apple | apple_brandy | apricot | armagnac | ... | whiskey | white_bread | white_wine | whole_grain_wheat_flour | wine | wood | yam | yeast | yogurt | zucchini |
    | --- | ---------- | ------- | ------ | -------- | ----- | ---------- | ----- | ------------ | ------- | -------- | --- | ------- | ----------- | ---------- | ----------------------- | ---- | ---- | --- | ----- | ------ | -------- |
    | 0   | 65         | indian  | 0      | 0        | 0     | 0          | 0     | 0            | 0       | 0        | ... | 0       | 0           | 0          | 0                       | 0    | 0    | 0   | 0     | 0      | 0        |
    | 1   | 66         | indian  | 1      | 0        | 0     | 0          | 0     | 0            | 0       | 0        | ... | 0       | 0           | 0          | 0                       | 0    | 0    | 0   | 0     | 0      | 0        |
    | 2   | 67         | indian  | 0      | 0        | 0     | 0          | 0     | 0            | 0       | 0        | ... | 0       | 0           | 0          | 0                       | 0    | 0    | 0   | 0     | 0      | 0        |
    | 3   | 68         | indian  | 0      | 0        | 0     | 0          | 0     | 0            | 0       | 0        | ... | 0       | 0           | 0          | 0                       | 0    | 0    | 0   | 0     | 0      | 0        |
    | 4   | 69         | indian  | 0      | 0        | 0     | 0          | 0     | 0            | 0       | 0        | ... | 0       | 0           | 0          | 0                       | 0    | 0    | 0   | 0     | 1      | 0        |
    
  5. Conseguimos informações sobre esses dados chamando info():

    df.info()
    

    O resultado será mais ou menos assim:

    <class 'pandas.core.frame.DataFrame'>
    RangeIndex: 2448 entries, 0 to 2447
    Columns: 385 entries, Unnamed: 0 to zucchini
    dtypes: int64(384), object(1)
    memory usage: 7.2+ MB
    

Exercício - aprendendo sobre cozinhas

Agora o trabalho começa a ficar mais interessante. Vamos descobrir a distribuição de dados por cozinha.

  1. Plote os dados como gráfico de barras chamando o método barh():

    df.cuisine.value_counts().plot.barh()
    

    distribuição de dados de culinária

    Há um número finito de cozinhas, mas a distribuição de dados é desigual. Você pode consertar isso! Mas antes, explore um pouco mais.

  2. Descubra quantos dados estão disponíveis por cozinha e imprima-os:

    thai_df = df[(df.cuisine == "thai")]
    japanese_df = df[(df.cuisine == "japanese")]
    chinese_df = df[(df.cuisine == "chinese")]
    indian_df = df[(df.cuisine == "indian")]
    korean_df = df[(df.cuisine == "korean")]
    
    print(f'thai df: {thai_df.shape}')
    print(f'japanese df: {japanese_df.shape}')
    print(f'chinese df: {chinese_df.shape}')
    print(f'indian df: {indian_df.shape}')
    print(f'korean df: {korean_df.shape}')
    

    O resultado será mais ou menos assim:

    thai df: (289, 385)
    japanese df: (320, 385)
    chinese df: (442, 385)
    indian df: (598, 385)
    korean df: (799, 385)
    

Descobrindo ingredientes

Vamos nos aprofundar nos dados e aprender quais são os ingredientes típicos de cada cozinha. Para isso, devemos limpar os dados recorrentes que criam confusão entre cozinhas.

  1. Crie uma função em Python chamada create_ingredient() para criar um dataframe de ingredientes. Esta função começará eliminando uma coluna inútil ("Unnamed: 0") e classificando os ingredientes por quantidade:

    def create_ingredient_df(df):
        ingredient_df = df.T.drop(['cuisine','Unnamed: 0']).sum(axis=1).to_frame('value')
        ingredient_df = ingredient_df[(ingredient_df.T != 0).any()]
        ingredient_df = ingredient_df.sort_values(by='value', ascending=False,
        inplace=False)
        return ingredient_df
    

    Você pode usar essa função para ter uma ideia dos dez ingredientes mais populares de uma culinária.

  2. Chame a função create_ingredient() usando os dados de cozinha tailandesa, e plote-os usando o método barh():

    thai_ingredient_df = create_ingredient_df(thai_df)
    thai_ingredient_df.head(10).plot.barh()
    

    tailandesa

  3. Faça o mesmo para cozinha japonesa:

    japanese_ingredient_df = create_ingredient_df(japanese_df)
    japanese_ingredient_df.head(10).plot.barh()
    

    japonesa

  4. E para cozinha chinesa:

    chinese_ingredient_df = create_ingredient_df(chinese_df)
    chinese_ingredient_df.head(10).plot.barh()
    

    chinesa

  5. Plote os ingredientes indianos:

    indian_ingredient_df = create_ingredient_df(indian_df)
    indian_ingredient_df.head(10).plot.barh()
    

    indiana

  6. Por fim, os ingredientes da cozinha coreana:

    korean_ingredient_df = create_ingredient_df(korean_df)
    korean_ingredient_df.head(10).plot.barh()
    

    coreana

  7. Agora, remova os ingredientes mais comuns que criam confusão entre cozinhas distintas, chamando drop():

    Todo mundo adora arroz, alho e gengibre!

    feature_df = df.drop(['cuisine','Unnamed: 0','rice','garlic','ginger'], axis=1)
    labels_df = df.cuisine #.unique()
    feature_df.head()
    

Balanceie o dataset

Agora que você limpou os dados, use a SMOTE - "Técnica de sobreamostragem de minoria sintética" - para balancear.

  1. Chame o método fit_resample(), esta estratégia gera novas amostras por interpolação.

    oversample = SMOTE()
    transformed_feature_df, transformed_label_df = oversample.fit_resample(feature_df, labels_df)
    

    Ao balancear seus dados, você terá melhores resultados ao classificá-los. Pense em uma classificação binária. Se a maioria dos seus dados for uma classe, um modelo de ML vai prever essa classe com mais frequência, simplesmente porque há mais dados para ela. O balanceamento de dados pega todos os dados distorcidos e ajuda a remover esse desequilíbrio.

  2. Verifique o número de rótulos por ingrediente:

    print(f'new label count: {transformed_label_df.value_counts()}')
    print(f'old label count: {df.cuisine.value_counts()}')
    

    O resultado será mais ou menos assim:

    new label count: korean      799
    chinese     799
    indian      799
    japanese    799
    thai        799
    Name: cuisine, dtype: int64
    old label count: korean      799
    indian      598
    chinese     442
    japanese    320
    thai        289
    Name: cuisine, dtype: int64
    

    Os dados são bons e limpos, equilibrados e muito deliciosos!

  3. A última etapa é salvar seus dados balanceados, incluindo rótulos e características, em um novo dataframe que pode ser exportado para um arquivo:

    transformed_df = pd.concat([transformed_label_df,transformed_feature_df],axis=1, join='outer')
    
  4. Você pode dar mais uma olhada nos dados usando o método transform_df.head() e transform_df.info(). Salve uma cópia desses dados para usar nas próximas tarefas:

    transformed_df.head()
    transformed_df.info()
    transformed_df.to_csv("../data/cleaned_cuisines.csv")
    

    Este novo csv pode ser encontrado na pasta raiz, onde estão todos os arquivos com os dados dos datasets.


🚀Desafio

Esta lição contém vários datasets interessantes. Explore os arquivos da pasta data e veja quais datasets seriam apropriados para classificação binária ou multiclasse. Quais perguntas você faria sobre estes datasets?

Questionário para fixação

Revisão e Auto Aprendizagem

Explore a API do SMOTE. Para quais casos de uso ela é melhor usada? Quais problemas resolve?

Tarefa

Explore métodos de classificação