Tworzenie drzewa decyzyjnego

W tym module użyjesz biblioteki YDF (Yggdrasil Decision Forest) do trenowania i interpretowania drzewa decyzyjnego.

Ten moduł jest inspirowany samouczkiem 🧭 Wprowadzenie do YDF.

Eliminacje

Zanim zaczniesz analizować zbiór danych, wykonaj te czynności:

  1. Utwórz nowy notatnik Colab.
  2. Zainstaluj bibliotekę YDF, umieszczając i wykonując w nowym notatniku Colab ten wiersz kodu:
    !pip install ydf -U
  3. Zaimportuj te biblioteki:
    import ydf
    import numpy as np
    import pandas as pd

Zbiór danych Palmer Penguins

Ten Colab korzysta ze zbioru danych Palmer Penguins, który zawiera pomiary wielkości 3 gatunków pingwinów:

  • Pasek podbródkowy
  • Gentoo
  • Adelie

Jest to problem klasyfikacji – celem jest przewidywanie gatunku pingwina na podstawie danych ze zbioru danych Palmer's Penguins. Oto pingwiny:

3 różne gatunki pingwinów.

Rysunek 16. 3 różne gatunki pingwinów. Obraz autorstwa @allisonhorst

 

Poniższy kod wywołuje funkcję pandas, aby wczytać do pamięci zbiór danych Palmer Penguins:

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)

W tej tabeli pierwsze 3 przykłady z zbioru danych Palmer Penguins są sformatowane w ten sposób:

Tabela 3. Pierwsze 3 przykłady w zbiorze danych Palmer Penguins

gatunek wyspa bill_length_mm bill_depth_mm flipper_length_mm body_mass_g seks rok
0 Adelie Torgersen 39,1 18.7 181,0 3750,0 mężczyźni 2007
1 Adelie Torgersen 39,5 17,4 186,0 3800,0 kobiety 2007
2 Adelie Torgersen 40,3 18,0 195,0 3250,0 kobiety 2007

Pełny zbiór danych zawiera cechy numeryczne (np. bill_depth_mm), kategorialne (np. island) i brakujące. W przeciwieństwie do sieci neuronowych lasy decyzyjne obsługują wszystkie te typy funkcji natywnie, więc nie musisz stosować kodowania one-hot, normalizacji ani dodatkowej funkcji is_present.

Poniższa komórka kodu dzieli zbiór danych na zbiór treningowy i zbiór testowy:

# 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

Trenowanie drzewa decyzyjnego z domyślnymi hiperparametrami

Pierwsze drzewo decyzyjne możesz wytrenować za pomocą algorytmu uczenia CART (Classification and Regression Trees), czyli klasyfikacji i drzew regresji, bez określania żadnych hiperparametrów. Dzieje się tak, ponieważ ydf.CartLearner zapewnia dobre domyślne wartości hiperparametrów. Więcej informacji o tym, jak działa ten typ modelu, znajdziesz w dalszej części tego kursu.

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

W poprzednim wywołaniu nie określono kolumn, które mają być używane jako funkcje wejściowe. Dlatego używana jest każda kolumna w zbiorze treningowym. W wywołaniu nie określono też semantyki (np. numerycznej, kategorialnej, tekstowej) funkcji wejściowych. Dlatego semantyka funkcji jest wnioskowana automatycznie.

Wywołaj model.plot_tree(), aby wyświetlić wynikowe drzewo decyzyjne:

model.plot_tree()

W Colab możesz użyć myszy, aby wyświetlić szczegółowe informacje o poszczególnych elementach, takich jak rozkład klas w każdym węźle.

Drzewo decyzyjne wytrenowane z użyciem domyślnych hiperparametrów.

Rysunek 17. Drzewo decyzyjne wytrenowane z użyciem domyślnych hiperparametrów.

Colab pokazuje, że warunek główny zawiera 243 przykłady. Pamiętaj jednak, że zbiór danych treningowych zawierał 272 przykłady. Pozostałe 29 przykładów zostało automatycznie zarezerwowanych na potrzeby weryfikacji i przycinania drzewa.

Pierwszy warunek sprawdza wartość bill_depth_mm. W tabelach 4 i 5 przedstawiono prawdopodobieństwo wystąpienia różnych gatunków w zależności od wyniku pierwszego warunku.

Tabela 4. Prawdopodobieństwo wystąpienia różnych gatunków, jeśli bill_depth_mm ≥ 42.3

Gatunek Prawdopodobieństwo
Adelie (czerwony) 8%
Gentoo (niebieski) 58%
Pasek pod brodą (zielony) 36%

 

Tabela 5. Prawdopodobieństwo wystąpienia różnych gatunków, jeśli bill_depth_mm < 42.3

Gatunek Prawdopodobieństwo
Adelie (czerwony) 97%
Gentoo (niebieski) 2%
Pasek pod brodą (zielony) 0%

bill_depth_mm to cecha numeryczna. Wartość 42, 3 została więc obliczona za pomocą algorytmu dokładnego podziału w przypadku klasyfikacji binarnej z cechami numerycznymi.

Jeśli bill_depth_mm ≥ 42.3 ma wartość Prawda, przeprowadź dalsze testy, aby sprawdzić, czy flipper_length_mm ≥ 207.5 może niemal idealnie oddzielić pingwiny białobrewe od pingwinów białobrewych i Adeli.

Poniższy kod podaje dokładność trenowania i testowania modelu:

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

Rzadko, ale może się zdarzyć, że dokładność testu jest wyższa niż dokładność trenowania. W takim przypadku zbiór testowy może się różnić od zbioru treningowego. W tym przypadku tak nie jest, ponieważ zbiory danych do trenowania i testowania zostały podzielone losowo. Bardziej prawdopodobne jest to, że zbiór danych testowych jest bardzo mały (tylko 72 przykłady), więc oszacowanie dokładności jest obarczone szumem.

W praktyce w przypadku tak małego zbioru danych lepiej byłoby użyć walidacji krzyżowej, ponieważ obliczyłaby ona dokładniejsze wartości wskaźników oceny. W tym przykładzie jednak dla uproszczenia kontynuujemy trenowanie i testowanie.

Ulepszanie hiperparametrów modelu

Model to pojedyncze drzewo decyzyjne wytrenowane z użyciem domyślnych wartości hiperparametrów. Aby uzyskać lepsze prognozy, możesz:

  1. Użyj bardziej zaawansowanego algorytmu uczenia, np. lasu losowego lub modelu drzew decyzyjnych z gradient boostingiem. Algorytmy uczenia się zostaną omówione na następnej stronie.

  2. Optymalizuj hiperparametr na podstawie obserwacji i intuicji. Pomocny może być przewodnik po ulepszaniu modelu.

  3. Użyj dostrajania hiperparametrów, aby automatycznie przetestować dużą liczbę możliwych hiperparametrów.

Nie widzieliśmy jeszcze algorytmu lasu losowego i drzewa wzmocnionego gradientowo, a liczba przykładów jest zbyt mała, aby przeprowadzić automatyczne dostrajanie hiperparametrów, więc model ulepszysz ręcznie.

Przedstawione powyżej drzewo decyzyjne jest małe, a liść z 61 przykładami zawiera etykiety pingwinów Adeli i pingwinów maskowych. Dlaczego algorytm nie podzielił tego liścia na mniejsze części? Są dwie możliwe przyczyny takiej sytuacji:

  • Mogła zostać osiągnięta minimalna liczba próbek na liść (domyślnie min_examples=5).
  • Drzewo mogło zostać podzielone, a następnie przycięte, aby zapobiec przeuczeniu.

Zmniejsz minimalną liczbę przykładów do 1 i sprawdź wyniki:

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

Drzewo decyzyjne wytrenowane z parametrem min_examples=1.

Rysunek 18. Drzewo decyzyjne wytrenowane z parametrem min_examples=1.

 

Węzeł liścia zawierający 61 przykładów został wielokrotnie podzielony.

Aby sprawdzić, czy dalsze dzielenie węzła jest przydatne, oceniamy jakość tego nowego modelu na zbiorze danych testowych:

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

Jakość modelu wzrosła, a dokładność testu zwiększyła się z 0,9167 do 0,97222. Zmiana hiperparametru była dobrym pomysłem.

Podgląd lasów decyzyjnych

Dalsze ulepszanie hiperparametrów prawdopodobnie pozwoli nam osiągnąć idealną dokładność. Zamiast tego ręcznego procesu możemy jednak wytrenować bardziej zaawansowany model, np. las losowy, i sprawdzić, czy działa lepiej.

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

Dokładność lasu losowego jest większa niż w przypadku naszego prostego drzewa. Na kolejnych stronach dowiesz się, dlaczego tak jest.

Wykorzystanie i ograniczenia

Jak wspomnieliśmy wcześniej, pojedyncze drzewo decyzyjne często ma niższą jakość niż nowoczesne metody uczenia maszynowego, takie jak lasy losowe, drzewa wzmocnione gradientowo i sieci neuronowe. Schematy decyzyjne są jednak przydatne w tych przypadkach:

  • Jako proste i niedrogie rozwiązanie bazowe do oceny bardziej złożonych podejść.
  • Gdy istnieje kompromis między jakością modelu a jego interpretowalnością.
  • Jako przybliżenie interpretacji modelu lasów decyzyjnych, który omówimy w dalszej części kursu.