Como criar uma árvore de decisão

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

Esta unidade foi inspirada no tutorial 🧭 Como começar com o YDF.

Informações preliminares

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

  1. Crie um novo bloco do Colab.
  2. Instale a biblioteca YDF colocando e executando a seguinte linha de código no novo notebook do Colab:
    !pip install ydf -U
  3. Importe as bibliotecas a seguir:
    import ydf
    import numpy as np
    import pandas as pd

Conjunto de dados de pinguins de Palmer

Este Colab usa o conjunto de dados Palmer Penguins, que contém medições de tamanho para três espécies de pinguins:

  • Pinguim-de-barbicha
  • Gentoo
  • Adelie

Este é um problema de classificação. O objetivo é prever a espécie de pinguim com base nos dados do conjunto de dados de pinguins de Palmer. Estes são os pinguins:

Três espécies diferentes de pinguins.

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

 

O código a seguir chama uma função pandas para carregar o conjunto de dados Palmer Penguins 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 Palmer Penguins:

Tabela 3. Os três primeiros exemplos no Palmer Penguins

espécie ilha bill_length_mm bill_depth_mm flipper_length_mm body_mass_g sex ano
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 feminino 2007
2 Adelie Torgersen 40,3 18.0 195,0 3250,0 feminino 2007

O conjunto de dados completo contém uma mistura de recursos 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 a todos esses tipos de recursos de forma nativa, então você não precisa fazer codificação one-hot, normalização ou recurso extra is_present.

O código a seguir divide o conjunto de dados em um conjunto de treinamento e um conjunto 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

Treinar árvores de decisão com hiperparâmetros padrão

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

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

A chamada anterior não especificou colunas para usar como features 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 atributos de entrada. Portanto, a semântica do recurso é inferida automaticamente.

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

model.plot_tree()

No Colab, é possível usar o mouse para mostrar 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, você pode lembrar que 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 espécies diferentes dependendo do resultado da primeira condição.

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

Espécie Probabilidade
Adelie (vermelha) 8%
Gentoo (azul) 58%
Faixa para queixo (verde) 36%

 

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

Espécie Probabilidade
Adelie (vermelha) 97%
Gentoo (azul) 2%
Faixa para queixo (verde) 0%

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

Se bill_depth_mm ≥ 42.3 for verdadeiro, teste se o flipper_length_mm ≥ 207.5 pode separar quase perfeitamente os Gentoos e os Gentoos+Adelie.

O código abaixo fornece a precisão de treinamento e 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 precisão do teste seja maior do que a precisão do treinamento. Nesse caso, o conjunto de teste provavelmente é diferente do conjunto de treinamento. No entanto, esse não é o caso aqui, já que o treinamento e o teste foram divididos de forma aleatória. Uma explicação mais provável é que o conjunto de dados de teste é muito pequeno (apenas 72 exemplos), então a estimativa de precisão é ruidosa.

Na prática, para um conjunto de dados tão pequeno, o uso da validação cruzada é preferível, porque ele calcula valores de métricas de avaliação mais precisos. No entanto, neste exemplo, continuamos com um treinamento e teste para simplificar.

Como melhorar os hiperparâmetros do modelo

O modelo é uma única árvore de decisão treinada com valores de hiperparâmetro padrão. Para receber previsões melhores, você pode:

  1. Use um aprendiz mais poderoso, como uma floresta aleatória ou um modelo de árvores otimizadas com gradiente. Esses algoritmos de aprendizado serão explicados na próxima página.

  2. Otimize o hiperparâmetro usando suas observações e intuição. O guia de melhoria de modelos 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 de árvores de gradiente boosted e o número de exemplos é muito pequeno para fazer um ajuste automático de hiperparâmetros, você vai melhorar o modelo manualmente.

A árvore de decisão mostrada acima é pequena, e a folha com o exemplo 61 contém uma mistura de rótulos Adelie e Chinstrap. Por que o algoritmo não dividiu essa folha 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 podada para evitar o ajuste excessivo.

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 saber se a divisão do nó é valiosa, 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 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, provavelmente poderíamos alcançar uma precisão perfeita. No entanto, em vez desse processo manual, podemos treinar um modelo mais poderoso, como uma floresta aleatória, e conferir se ele funciona melhor.

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

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

Uso e limitação

Como mencionado anteriormente, uma única árvore de decisão geralmente tem qualidade inferior aos métodos modernos de aprendizado de máquina, como florestas aleatórias, árvores impulsionadas por gradiente e redes neurais. No entanto, as árvores de decisão ainda são úteis nos seguintes casos:

  • Como uma referência simples e barata para avaliar abordagens mais complexas.
  • Quando há uma compensação entre a qualidade e a interpretabilidade do modelo.
  • Como um substituto para a interpretação do modelo de floresta de decisão, que o curso vai abordar mais adiante.