Salta el contingut
 

Regressió amb arbres de decisió

Autor: Joan Puigcerver Ibáñez

Correu electrònic: j.puigcerveribanez@edu.gva.es

Llicència: CC BY-NC-SA 4.0

(Reconeixement - NoComercial - CompartirIgual) 🅭

Regressió amb arbres de decisió

Els arbres de decisió (decision trees o DT) són models d'aprenentatge automàtic supervisat que poden resoldre problemes de classificació i regressió.

Aquests models es basen l'aprenentatge de decisions simples a partir de les dades en forma d'estructura d'arbre.

Exemple d'arbre de decisió

scikit-learn: Decision Trees

Figura 1. Exemple d'arbre de decisió de classificació del conjunt de dades Iris.

Exemple d'arbre de regressió

scikit-learn: Decision Trees

Figura 2. Exemple d'arbre de decisió de regressió de la funció \(\sin(x)\).

Model de regressió amb arbres de decisió

Els arbres de decisió poden ser utilitzats per resoldre problemes de regressió.

Podem crear un model de regressió amb arbres de decisió amb scikit-learn mitjançant la classe DecisionTreeRegressor.

Documentació

Documentació oficial de DecisionTreeRegressor

Preparació de les dades

Anem a generar un conjunt de dades que s'ajusten la funció \(\sin(x)\) amb una lleugera desviació.

import numpy as np
from sklearn.model_selection import train_test_split


def f(x):
    return np.sin(x / 5)

np.random.seed(42)
n_samples = 200

X = np.random.uniform(-50, 50, n_samples)
Y = f(X) + np.random.randn(n_samples) * 0.25
X = X.reshape(-1, 1) # Convertim X en una matriu de 1 columna

X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=42)
X_test, Y_test = zip(*sorted(zip(X_test, Y_test))) # Ordenem les dades de test per visualitzar-les correctament

Dades generades a partir del la funció sinus

Figura 3. Dades generades a partir de la funció \(\sin(x)\).

Creació del model

El model DecisionTreeRegressor té el hiperparàmetre max_depth que determina la profunditat màxima de l'arbre de decisió.

Un valor massa alt d'aquest paràmetre pot provocar sobreajustament (overfitting).

from sklearn.tree import DecisionTreeRegressor

max_depth = 5
model = DecisionTreeRegressor(max_depth=max_depth)

Entrenament del model

Per entrenar el model amb les dades, utilitzem el mètode fit de la classe DecisionTreeRegressor.

model.fit(X_train, Y_train)

Predicció i avaluació del model

Una vegada entrenat, podem fer prediccions amb el model i avaluar-lo.

from sklearn.metrics import mean_squared_error
from sklearn.metrics import r2_score

pred_Y = model.predict(X_test)

rmse = mean_squared_error(Y_test, pred_Y)
r2 = r2_score(Y_test, pred_Y)
print(f'RMSE arbre decisió: {rmse:.2f}')
print(f'R2 arbre decisió: {r2:.2f}')
RMSE arbre decisió: 0.11
R2 arbre decisió: 0.81

Visualització de l'arbre de decisió

Podem visualitzar l'arbre de decisió de les dades de prova amb una gràfica.

import matplotlib.pyplot as plt

plt.scatter(X_train, Y_train, color='blue')
plt.scatter(X_test, Y_test, color='orange')
plt.plot(X_test, pred_Y, color='red', lw=2)
plt.show()

Model de regressió mitjançant arbre de decisió

Figura 4. Model de regressió mitjançant arbre de decisió.

També podem visualitzar l'arbre de decisió amb la llibreria graphviz.

from sklearn.tree import export_graphviz
from graphviz import Source

# Export the tree to a DOT format
dot_data = export_graphviz(
    model,
    out_file=None,  # Leave as None to return the DOT data as a string
    filled=True,  # Color the nodes based on their values
    rounded=True,  # Round the corners of the boxes
    special_characters=True  # Allow for special characters in labels
)

# Render the DOT data to a graph
graph = Source(dot_data)
graph.format = "png"
graph.render("decision_tree")
graph.view()  # Open the PNG file

Arbre de decisió

Figura 5. Arbre de decisió generat pel model.

Codi font

arbres_decisio.py
#!/usr/bin/env python

import numpy as np
from sklearn.model_selection import train_test_split


def f(x):
    return np.sin(x / 5)

np.random.seed(42)
n_samples = 200

X = np.random.uniform(-50, 50, n_samples)
Y = f(X) + np.random.randn(n_samples) * 0.25
X = X.reshape(-1, 1) # Convertim X en una matriu de 1 columna

X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=42)
X_test, Y_test = zip(*sorted(zip(X_test, Y_test))) # Ordenem les dades de test per visualitzar-les correctament

import matplotlib.pyplot as plt

plt.scatter(X_train, Y_train, color='blue')
plt.scatter(X_test, Y_test, color='orange')
plt.show()

from sklearn.tree import DecisionTreeRegressor

max_depth = 5
model = DecisionTreeRegressor(max_depth=max_depth)

model.fit(X_train, Y_train)

from sklearn.metrics import mean_squared_error
from sklearn.metrics import r2_score

pred_Y = model.predict(X_test)

rmse = mean_squared_error(Y_test, pred_Y)
r2 = r2_score(Y_test, pred_Y)
print(f'RMSE arbre decisió: {rmse:.2f}')
print(f'R2 arbre decisió: {r2:.2f}')

import matplotlib.pyplot as plt

plt.scatter(X_train, Y_train, color='blue')
plt.scatter(X_test, Y_test, color='orange')
plt.plot(X_test, pred_Y, color='red', lw=2)
plt.show()

from sklearn.tree import export_graphviz
from graphviz import Source

# Export the tree to a DOT format
dot_data = export_graphviz(
    model,
    out_file=None,  # Leave as None to return the DOT data as a string
    filled=True,  # Color the nodes based on their values
    rounded=True,  # Round the corners of the boxes
    special_characters=True  # Allow for special characters in labels
)

# Render the DOT data to a graph
graph = Source(dot_data)
graph.format = "png"
graph.render("decision_tree")
graph.view()  # Open the PNG file