Introducción a árboles de decisión

1

¿Qué son los árboles de decisión?

2

Tu primer árbol de decisión con scikit-learn

3

Análisis de datos para tu primer árbol de decisión

4

Entrenamiento y evaluación de árbol de decisión con scikit-learn

5

¿Cómo funcionan los árboles de decisión?

6

¿Cuándo usar árboles de decisión?

Quiz: Introducción a árboles de decisión

Proyecto práctico: árboles de decisión

7

Conociendo problema a resolver y dataset de clasificación

8

Análisis exploratorio de datos para árbol de decisión

9

Procesamiento de datos para el entrenamiento de árbol de decisión

10

Entrenamiento de modelo de clasificación con árbol de decisión

11

¿Cómo evaluar un modelo de árbol de decisión?

12

Evaluación de resultados del modelo de árbol de decisión

Quiz: Proyecto práctico: árboles de decisión

Introducción a random forest

13

¿Qué son los random forest o bosques aleatorios?

14

Tu primer random forest con scikit-learn

15

Análisis de datos para tu primer random forest

16

Entrenamiento de tu primer modelo de random forest con scikit-learn

17

Evaluación de tu primer modelo de random forest con scikit-learn

18

¿Cómo funcionan los random forest?

19

¿Cuándo utilizar random forest?

Quiz: Introducción a random forest

Proyecto práctico: random forest

20

Entrenamiento de modelo de clasificación de carros con random forest

21

Evaluación de resultados del modelo de clasificación con random forest

Quiz: Proyecto práctico: random forest

Conclusión

22

Proyecto final y cierre

23

Comparte tu proyecto de Random Forest y obtén tu certificado

No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Convierte tus certificados en títulos universitarios en USA

Antes: $249

Currency
$209

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

19 Días
7 Hrs
9 Min
12 Seg

Evaluación de resultados del modelo de árbol de decisión

12/23
Recursos

Aportes 19

Preguntas 1

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Si quieren implementar el F1-score lo pueden hacer así:

from sklearn.metrics import f1_score

train_f1_tree = f1_score(y_train, y_train_pred_tree, average='micro')
test_f1_tree = f1_score(y_test, y_test_pred_tree, average='micro')

print("El f1 score en train es: ", train_f1_tree)
print("El f1 score en test es: ", test_f1_tree)

Dado que se trata de un ejercicio de clasificación múltiple, hay que ajustar el parámetro average entre varios tipos. Más información se encuentra disponible en la documentación: https://scikit-learn.org/stable/modules/generated/sklearn.metrics.f1_score.html#:~:text=The formula for the F1,more in the User Guide

Recuerden que para hacer la gráfica de feature_importances el código es:

#Verificamos el feature importances
import seaborn as sns

importances = tree.feature_importances_
columns = X.columns
data = pd.DataFrame([importances], columns=columns)
sns.barplot(data,
            palette = 'bright',
            saturation = 2.0,
            edgecolor = 'black',
            linewidth = 2)
plt.title('Importancia de cada feature')
plt.show()

Bien gente, paso a compartir mis resultados

EDA

Primero en el EDA cruce cada feature con el target

Insight

  • Price: Los autos con precio bajo o medio tienen una mayor probabilidad de ser clasificados como vgood o good en comparación con los autos de precio alto.

  • Doors: Los autos con 4 o más puertas tienen una mayor probabilidad de ser clasificados como vgood o good en comparación con los autos de 3 o 2 puertas.

  • Lug_boot: Los autos con maletero grande o mediano tienen una mayor probabilidad de ser clasificados como vgood o good en comparación con los autos con maletero pequeño.

  • Maint: Los autos con costos de mantenimiento bajos o medios tienen una mayor probabilidad de ser clasificados como vgood o good en comparación con los autos con costos de mantenimiento altos.

  • Persons: Los autos con capacidad de 4 o más personas tienen una mayor probabilidad de ser clasificados como vgood o good en comparación con los autos con capacidad de menos de 4 personas.

  • Safety: Los autos con alto nivel de seguridad tienen una mayor probabilidad de ser clasificados como vgood o good en comparación con los autos con bajo o medio nivel de seguridad.

Optimizacion de parametros use este grid

param_grid = {'criterion': ['gini', 'entropy'], 'max_depth': [2, 3, 4, 5]}

Quedo tal que asi los resultados

Mejores hiperparámetros encontrados:
{'criterion': 'gini', 'max_depth': 4}
Mejor puntuación de validación cruzada:
0.8676308539944904

Evaluacion del modelo

El accuracy en train es: 0.8420038535645472
El accuracy en test es: 0.8709677419354839

Relevancia de features

Grafico arbol de decision

Mi aporte para poder graficar la matríz de confusión:

from sklearn.metrics import ConfusionMatrixDisplay
disp = ConfusionMatrixDisplay.from_predictions(
    y_true=Y_train, # Y en train
    y_pred=Y_train_pred_DeciTree, # Y predicho en train.
    cmap=plt.cm.Blues,
    normalize=None,
)
disp.confusion_matrix

Obtener un resumen de las principlaes métricas

from sklearn.metrics import classification_report
target_names = Y_train.unique()
print(classification_report(Y_train, Y_train_pred_DeciTree, target_names=target_names))

Les dejo la representación del árbol hecho en la clase. Admito que es super sencillo de entender y hacer entender a otros.

from io import StringIO
from IPython.display import Image, display
from sklearn import tree as tr
import pydotplus

out = StringIO()
tr.export_graphviz(tree, out_file = out, feature_names=list(X.columns))

graph = pydotplus.graph_from_dot_data(out.getvalue())
graph.write_png('cars.png')

Me quedo igual, tal vez por la poca cantidad de datos no hubo cambios significativos.

La precision del modelo se mantiene igual

Reto:

Me puse a jugar un poco con las variables y logré otros resultados como estos: ![](https://static.platzi.com/media/user_upload/image-283e2897-c15c-4385-8321-0c1592b09b9c.jpg) También logré que la gráfica sea diferente: ```python importances = tree.feature_importances_ column = X.columns importance_df = pd.DataFrame({'feature': column, 'importance': importances}) importance_df = importance_df.sort_values(by='importance', ascending=False) plt.figure(figsize=(10, 6)) sns.barplot(x=column, y=importances, palette='rocket', edgecolor='black', order=importance_df['feature']) plt.xlabel('Features') plt.ylabel('Importance') plt.title('Feature Importance') for i, value in enumerate(importance_df['importance']): plt.text(i, value + 0.01, f'{value * 100:.2f}%', ha='center') plt.xticks(rotation=0) plt.tight_layout() plt.show() ``` ![](https://static.platzi.com/media/user_upload/image-d271aa9f-35a5-4369-b856-2ea40572cfc1.jpg)
![](https://static.platzi.com/media/user_upload/image-77a8b5af-8f53-4f0b-a6eb-1ebda06fc016.jpg)![](https://static.platzi.com/media/user_upload/image-127e05e5-c11a-4e0a-98af-60ef536eed60.jpg)

Hola con XGBClassifier me da un accuracy de 0.98 y me resulta raro cual es mi error o es perfecta la prediccion ??
Adjunto codigo y comparacion de modelos

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

from sklearn.model_selection import train_test_split
import category_encoders as ce
from sklearn.tree import DecisionTreeClassifier

df = pd.read_csv('car_evaluation.csv')
col_names = ['buying', 'maint', 'doors', 'persons', 'lug_boot', 'safety', 'class']
df.columns = col_names

df['class'] = pd.factorize(df['class'])[0]

X = df.drop(['class'], axis=1)
y = df['class']

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=0)

encoder = ce.OrdinalEncoder(cols=['buying', 'maint', 'doors', 'persons', 'lug_boot', 'safety'])
X_train = encoder.fit_transform(X_train)
X_test = encoder.transform(X_test)

tree = DecisionTreeClassifier(max_depth=2, random_state=0)
tree.fit(X_train, y_train)

y_train_pred_tree = tree.predict(X_train)
y_test_pred_tree = tree.predict(X_test)

from sklearn.metrics import accuracy_score
train_accuracy = accuracy_score(y_train, y_train_pred_tree)
test_accuracy = accuracy_score(y_test, y_test_pred_tree)
print('El accuracy en train es:', train_accuracy)
print('El accuracy en test es:', test_accuracy)

from xgboost import XGBClassifier
model = XGBClassifier()
model.fit(X_train, y_train)
y_train_pred_xgb = model.predict(X_train)
y_test_pred_xgb = model.predict(X_test)

train_accuracy_xgb = accuracy_score(y_train, y_train_pred_xgb)
test_accuracy_xgb = accuracy_score(y_test, y_test_pred_xgb)
print('El accuracy en train (XGBoost) es:', train_accuracy_xgb)
print('El accuracy en test (XGBoost) es:', test_accuracy_xgb)

El accuracy no es recomendable por el sesgo que hay en los datos si evaluamos las otras métricas encontramos el contraste:

# Cálculo de métricas
import sklearn.metrics as metrics

def metrics_model(y_test, y_pred):
    precision = metrics.precision_score(y_test, y_pred, average='macro')
    recall = metrics.recall_score(y_test, y_pred, average='macro')
    accuracy = metrics.accuracy_score(y_test, y_pred)
    print("Precision:", precision)
    print("Recall:", recall)
    print("Accuracy:", accuracy)

print("Metricas en Train")
metrics_model(y_train, y_train_pred_tree)
print("Metricas en Test")
metrics_model(y_test, y_test_pred_tree)

Metricas en Train
Precision: 0.3341661493896131
Recall: 0.31447751302431937
Accuracy: 0.7444168734491315
Metricas en Test
Precision: 0.3258999772157667
Recall: 0.3091268415379087
Accuracy: 0.7360308285163777

Entrenando el modelo nuevamente solo con persons y safety me salieron estos resultados:
El accuracy en train es: 0.7733664185277088
El accuracy en test es: 0.7591522157996147

Realizando el modelo con los dos features más importantes obtuve un accuracy bastante similar.
Entre el 75% y 78%

Vi muchos comentarios buenos que tratan de explicar los valores del paramétro average. Yo les dejo algo más útil y claro usando analogías. (Se lo pedi a ChatGPT) ### 1. **Micro Average**: enfoque global Imagina que estás organizando una competencia de ajedrez con varios equipos. En lugar de fijarte en el desempeño individual de cada equipo, decides evaluar a todos los participantes de todos los equipos como un solo grupo. Esto es lo que hace `micro`: considera todas las predicciones como si fueran una sola clasificación y calcula una precisión, un recall o un F1-score global. * **Uso**: `average='micro'` es ideal cuando quieres medir el rendimiento general de tu modelo sin preocuparte por cómo le fue a cada clase en específico. * **Diferencia**: Abarca todas las clases, dando el mismo peso a cada instancia (predicción) en lugar de cada clase. ### 2. **Macro Average**: enfoque por equipo Siguiendo con la analogía de la competencia de ajedrez, ahora decides evaluar a cada equipo por separado, calculando su rendimiento individual y luego promediando estos valores. Es como si te importara que cada equipo destaque en igual medida, sin importar si uno tiene muchos jugadores y otro tiene pocos. * **Uso**: `average='macro'` es útil cuando quieres asegurarte de que cada clase reciba el mismo peso en el cálculo, independientemente de su tamaño. * **Diferencia**: A diferencia de `micro`, no toma en cuenta la cantidad de muestras de cada clase. Cada clase tiene el mismo impacto en el promedio, incluso si tiene pocas o muchas instancias. ### 3. **Weighted Average**: enfoque equilibrado Ahora imagina que cada equipo de ajedrez tiene diferentes cantidades de jugadores, y decides darles a los equipos con más jugadores un peso proporcionalmente mayor al calcular el rendimiento general. Esto es `weighted`: calcula el promedio ponderado, donde cada clase contribuye de acuerdo con su número de instancias. * **Uso**: `average='weighted'` es útil en datasets desbalanceados, ya que permite que las clases con más instancias tengan un peso proporcional en el resultado. * **Diferencia**: Se parece a `macro` pero, en lugar de tratar a todas las clases por igual, tiene en cuenta la cantidad de ejemplos en cada clase para dar un peso proporcional a cada resultado. ### 4. **Samples Average**: enfoque por instancia Imagina que en tu competencia de ajedrez, cada jugador es evaluado individualmente en lugar de como parte de un equipo. Cada jugador obtiene un puntaje que luego se promedia. Así funciona `samples`: se enfoca en cada muestra individual, evaluando cada predicción como un evento separado y luego calculando el promedio. Este tipo es especialmente útil en modelos multilabel. * **Uso**: `average='samples'` se usa cuando tienes datos multilabel, es decir, donde cada instancia puede pertenecer a múltiples clases al mismo tiempo. * **Diferencia**: A diferencia de los otros métodos, que son más comunes en clasificaciones de una sola etiqueta, `samples` se adapta mejor a escenarios donde cada instancia puede tener múltiples etiquetas, calculando el rendimiento para cada muestra y luego promediando. ### 5. **Binary Average**: enfoque específico para problemas binarios Este valor solo aplica cuando tienes una clasificación binaria (una clase positiva y otra negativa). En lugar de mirar múltiples clases, simplemente calcula la precisión, recall o F1-score basándose en la clase positiva (la que te interesa identificar). * **Uso**: `average='binary'` se usa exclusivamente para problemas binarios, y generalmente no necesitas especificarlo porque es el valor por defecto en clasificaciones binarias. * **Diferencia**: Este método ignora clases adicionales y se enfoca solo en la métrica para la clase positiva.

En estos casos sería bueno hacer un heatmap de la correlación entre las variables antes de hacer el modelo, de esta manera sería posible identificar y seleccionar las variables con más altas correlaciones y utilizarlas en el modelo. ¿Es esto correcto?

Hice el cambio de las features, usando solamente las 2 features mas imporantes y el accuracy me queda exactamente igual al predicto con las features anteriores.
Reto: ```python x_2 = df[['persons', 'safety']] y_2 = df['class'] x2_train, x2_test, y2_train, y2_test = train_test_split( x_2, y_2, test_size=.3, shuffle=True, random_state=42) from sklearn.preprocessing import OrdinalEncoder enc_x = OrdinalEncoder() x2_train = pd.DataFrame(enc_x.fit_transform(x2_train)) x2_test = pd.DataFrame(enc_x.transform(x2_test)) x2_train.shape, x2_test.shape # ((1208, 2), (519, 2)) tree_2 = DecisionTreeClassifier(max_depth=2, random_state=0) tree_2.fit(x2_train, y2_train) tree_2.score(x2_test, y2_test) # 0.7726396917148363 ```

Reto:

Salieron los mismos resultados