Como criar uma árvore de decisão

Nesta unidade, você vai usar o treinamento da biblioteca YDF (Yggdrasil Decision Forest) e interpretar uma árvore de decisão.

Esta unidade é inspirada no tutorial 🧭 YDF (Introdução ao YDF).

Informações preliminares

Antes de estudar o conjunto de dados, faça o seguinte:

  1. Crie um novo notebook do Colab (em inglês).
  2. Para instalar a biblioteca YDF, coloque e execute a seguinte linha de código no novo bloco do Colab:
    !pip install ydf -U
    
  3. Importe as seguintes bibliotecas:
    import ydf
    import numpy as np
    import pandas as pd
    

O conjunto de dados de pinguins de Palmer

Este Colab usa o conjunto de dados Palmer Penguins, que contém medidas de tamanho para três espécies de pinguim:

  • Chinstrap
  • Gentoo
  • Adelie

Esse é um problema de classificação. O objetivo é prever as espécies de pinguins com base nos dados do conjunto de dados do conjunto de pinguins de Palmer. Aqui estão os pinguins:

Três espécies de pinguins
diferentes.

Figura 16. Três espécies de pinguim diferentes. Imagem de @allisonhorst

 

O código a seguir chama uma função pandas para carregar o conjunto de dados de pinguins Palmer na memória:

path = "https://storage.googleapis.com/download.tensorflow.org/data/palmer_penguins/penguins.csv"
dataset = pd.read_csv(path)
label = "species"

# Display the first 3 examples.
dataset.head(3)

A tabela a seguir formata os três primeiros exemplos no conjunto de dados do Palmer Penguins:

Tabela 3. Os três primeiros exemplos em Palmer pinguins

espécie Ilha bill_length_mm bill_depth_mm flipper_length_mm body_mass_g sex year
0 Adelie Torgersen 39,1 18,7 181,0 3.750,0 masculino 2007
1 Adelie Torgersen 39,5 17,4 186,0 3.800,0 de mulheres 2007
2 Adelie Torgersen 40,3 18.0 195,0 3.250,0 de mulheres 2007

O conjunto de dados completo contém uma combinação de atributos numéricos (por exemplo, bill_depth_mm), categóricos (por exemplo, island) e ausentes. Ao contrário das redes neurais, as florestas de decisão oferecem suporte nativo a todos esses tipos de atributos. Assim, você não precisa fazer codificação one-hot, normalização ou atributo is_present extra.

A célula de código a seguir divide o conjunto de dados em um conjunto de treinamento e outro de teste:

# Use the ~20% of the examples as the testing set
# and the remaining ~80% of the examples as the training set.
np.random.seed(1)
is_test = np.random.rand(len(dataset)) < 0.2

train_dataset = dataset[~is_test]
test_dataset = dataset[is_test]

print("Training examples: ", len(train_dataset))
# >> Training examples: 272

print("Testing examples: ", len(test_dataset))
# >> Testing examples: 72

Como treinar uma árvore de decisão com hiperparâmetros padrão

É possível treinar sua primeira árvore de decisão com o algoritmo de aprendizado CART (árvores de classificação e regressão) (também conhecido como aprendiz) sem especificar nenhum hiperparâmetro. Isso ocorre porque o aprendizado ydf.CartLearner fornece bons valores de hiperparâmetros padrão. Você vai saber como esse tipo de modelo funciona posteriormente no curso.

model = ydf.CartLearner(label=label).train(train_dataset)

A chamada anterior não especificou colunas a serem usadas como recursos de entrada. Portanto, todas as colunas do conjunto de treinamento são usadas. A chamada também não especificou a semântica (por exemplo, numérica, categórica, de texto) dos recursos de entrada. Portanto, a semântica de atributos é inferida automaticamente.

Chame model.plot_tree() para exibir a árvore de decisão resultante:

model.plot_tree()

No Colab, você pode usar o mouse para exibir detalhes sobre elementos específicos, como a distribuição de classes em cada nó.

Uma árvore de decisão treinada com hiperparâmetros
padrão.

Figura 17. Uma árvore de decisão treinada com hiperparâmetros padrão.

O Colab mostra que a condição raiz contém 243 exemplos. No entanto, o conjunto de dados de treinamento continha 272 exemplos. Os 29 exemplos restantes foram reservados automaticamente para validação e poda de árvore.

A primeira condição testa o valor de bill_depth_mm. As tabelas 4 e 5 mostram a probabilidade de diferentes espécies, dependendo do resultado da primeira condição.

Tabela 4. Probabilidade de espécies diferentes se bill_depth_mm ≥ 42.3

Espécie Probabilidade
Adelie (vermelho) 8%
Gentoo (azul) 58%
Chinstrap (verde) 36%

 

Tabela 5. Probabilidade de espécies diferentes se bill_depth_mm < 42.3

Espécie Probabilidade
Adelie (vermelho) 97%
Gentoo (azul) 2%
Chinstrap (verde) 0%

bill_depth_mm é um atributo numérico. Portanto, o valor 42,3 foi encontrado usando a divisão exata para classificação binária com atributos numéricos.

Se bill_depth_mm ≥ 42.3 for verdadeira, vamos testar mais se o flipper_length_mm ≥ 207.5 consegue separar perfeitamente os Gentoos e os Gentoos+Adelie.

O código a seguir fornece a acurácia do treinamento e do teste do modelo:

train_evaluation = model.evaluate(train_dataset)
print("train accuracy:", train_evaluation.accuracy)
# >> train accuracy:  0.9338

test_evaluation = model.evaluate(test_dataset)
print("test accuracy:", test_evaluation.accuracy)
# >> test accuracy:  0.9167

É raro, mas possível, que a acurácia do teste seja maior que a do treinamento. Nesse caso, o conjunto de teste pode ser diferente do conjunto de treinamento. No entanto, esse não é o caso, já que o treinamento e o teste foram divididos aleatoriamente. Uma explicação mais provável é que o conjunto de dados de teste é muito pequeno (apenas 72 exemplos), o que resulta em ruído na estimativa de precisão.

Na prática, para um conjunto de dados tão pequeno, o uso de validação cruzada seria preferível porque calcularia valores de métrica de avaliação mais precisos. Neste exemplo, continuamos com um treinamento e um teste para simplificar.

Como melhorar os hiperparâmetros do modelo

O modelo é uma árvore de decisão única, treinada com valores de hiperparâmetros padrão. Para receber previsões melhores, é possível:

  1. Use um modelo de aprendizado mais avançado, como um modelo de floresta aleatória ou de árvores com aumento de gradiente. Esses algoritmos de aprendizado serão explicados na próxima página.

  2. Otimizar o hiperparâmetro usando suas observações e intuição. O guia de melhoria do modelo pode ser útil.

  3. Use o ajuste de hiperparâmetros para testar automaticamente um grande número de hiperparâmetros possíveis.

Como ainda não vimos o algoritmo de floresta aleatória e árvores otimizadas com gradiente e, como o número de exemplos é muito pequeno para fazer um ajuste automático de hiperparâmetros, você vai melhorar manualmente o modelo.

A árvore de decisão mostrada acima é pequena, e a folha com 61 exemplos contém uma combinação de rótulos Adelie e Chinstrap. Por que o algoritmo não dividiu essa folha ainda mais? Há dois possíveis motivos:

  • O número mínimo de amostras por folha (min_examples=5 por padrão) pode ter sido atingido.
  • A árvore pode ter sido dividida e depois podada para evitar o overfitting.

Reduza o número mínimo de exemplos para 1 e confira os resultados:

model = ydf.CartLearner(label=label, min_examples=1).train(train_dataset)
model.plot_tree()

Uma árvore de decisão treinada com
min_examples=1.

Figura 18. Uma árvore de decisão treinada com min_examples=1.

 

O nó de folha que contém 61 exemplos foi dividido várias vezes.

Para ver se a divisão do nó é útil, avaliamos a qualidade desse novo modelo no conjunto de dados de teste:

print(model.evaluate(test_dataset).accuracy)
# >> 0.97222

A qualidade do modelo aumentou com uma precisão de teste que vai de 0,9167 para 0,97222. Essa mudança de hiperparâmetro foi uma boa ideia.

Anterior de uma floresta de decisão

Ao continuar melhorando os hiperparâmetros, é provável que a precisão seja perfeita. No entanto, em vez desse processo manual, podemos treinar um modelo mais poderoso, como uma floresta aleatória, e ver se ele funciona melhor.

model = ydf.RandomForestLearner(label=label).train(pandas_train_dataset)
print("Test accuracy: ", model.evaluate(pandas_test_dataset).accuracy)
# >> Test accuracy: 0.986111

A precisão da floresta aleatória é melhor do que nossa árvore simples. Você vai saber nas próximas páginas o porquê.

Uso e limitação

Como mencionado anteriormente, uma única árvore de decisão geralmente tem qualidade inferior ao dos métodos modernos de machine learning, como florestas aleatórias, árvores com gradiente otimizado e redes neurais. No entanto, as árvores de decisão ainda são úteis nos seguintes casos:

  • Como uma linha de base simples e barata para avaliar abordagens mais complexas.
  • Quando há um equilíbrio entre a qualidade e a interpretabilidade do modelo.
  • Como substituto da interpretação do modelo de florestas de decisão, que o curso vai explorar mais tarde.