Jeison Gerardo Rodriguez
Jeison Gerardo Rodriguez
Layla Scheli
ProfesorJeison Gerardo Rodriguez
Jeison Gerardo Rodriguez
Layla Scheli
ProfesorJohnny Campiño
Layla Scheli
ProfesorJoaquín Ricardo Svoboda Abregú
Carlos Mazzaroli
Carlos Mazzaroli
Luis Ernesto Domínguez Velásquez
Jhon Sebastian Alegria Ausecha
Elias Dudamel
Layla Scheli
ProfesorAnabel Chavez Berumen
Layla Scheli
ProfesorSebastian Ponce
Jovanny Delgado
Madison Eduardo Herrera Carrión
Cesar supo
Layla Scheli
ProfesorAlfredo Olmedo
Layla Scheli
ProfesorGonzalo Ceron Denetro
Antonio Demarco Bonino
Jose Martin Horna Aguirre
Eugenio Schiavoni
José Salas Bolívar
William Camilo Correa Sandoval
Juan R. Vergara M.
David Duque Uribe
Diego Mauricio Zuluaga Rodríguez
Diego Mauricio Zuluaga Rodríguez
Jonathan stick Riveros Gamboa
Alex Xiomar Rubio Lopez
Yeison Rodriguez
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%20formula%20for%20the%20F1,more%20in%20the%20User%20Guide
Y aquí una buena explicación de cómo funciona cada average: https://towardsdatascience.com/micro-macro-weighted-averages-of-f1-score-clearly-explained-b603420b292f
Gracias por compartir :)
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()
Gracias Johnny, buen aporte! :)
Gracias genio!
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
SUPER IMPORTANTE RECALCAR
que los datos estan muy desvanlanceados, si hacen un F1-score van a ver que la clasificacion para vgood es de 0 y de unacc casi del 94%
en este caso esta bueno balancear porque ajustando mal los datos
Estos fueron los resultados que obtuve haciendo un undersampling al dataset antes de entrenar al modelo
f1-score
No es de los mejores resultados que podemos obtener, pero es aceptable dentro de todo, por lo menos esta en tre el 60 y 80% de precision el acurracy promedio
Interesante tu EDA, puedes compartir el código ?
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')
Gracias por compartir :)
Me quedo igual, tal vez por la poca cantidad de datos no hubo cambios significativos.
Hola Anabel, Si! proba cambiando algunos parametros adicionales y nos contas :)
Me paso lo mismo, lo unico es qeu cuando uno lo hace en Jupyther Notebook, cambia pero si se hace en Visual Code tiene diferencia.
La precision del modelo se mantiene igual
Me salio la misma gráfica y al evaluar las métricas estadísticas, fueron los mismos resultados
Reto:
Gracias Cesar, continua avanzando! :)
En Seaborn, utilizando la funcion barplot() ya no acepta los argumentos posicionales columns e importances directamente, en versiones recientes de seaborn los parametros x y y deben especificarse explicitamente como argumentos de palabras clave:
asi que cambiar :
sns.barplot(columns, importances, palette='bright', saturation=2.0, edgecolor='black', linewidth=2)
por
sns.barplot(x=columns, y=importances, palette='bright', saturation=2.0, edgecolor='black', linewidth=2)
quedando el codigo como:
import matplotlib.pyplot as plt
import seaborn as sns
# Verificamos la importancia de las características
importances = tree.feature_importances_
columns = X.columns
# Corrección: usar parámetros x e y explícitamente
sns.barplot(x=columns, y=importances, palette='bright', saturation=2.0, edgecolor='black', linewidth=2)
plt.title('Importancia de cada Feature')
plt.xticks(rotation=90) # Si hay muchas columnas, mejorar la legibilidad
plt.show()
Gracias Alfredo, muy provechoso tus comentarios, saludos :)
En clases pasadas habíamos visto que los árboles de decisión son una caja blanca, porque podemos ver a detalle como es que se construyen y porque se toman ciertas decisiones. Para visualizar nuestro árbol de decisión con Sci-kit Learn importamos el siguiente módulo:
from sklearn.tree import export_graphviz ```Y como argumentos le pasamos la instancia que creamos de nuestro árbol de decisión, los features, las clases, y el archivo que queremos que nos regrese. Para visualizarlo importamos. ```js from graphviz import Source ```El código completo quedaría: ```js from sklearn.tree import export_graphviz from graphviz import Source tree_model = DecisionTreeClassifier(max_depth=4, criterion='gini', random_state=42) tree_model.fit(X_train, Y_train) y_predict = tree_model.predict(X_test) #LOOK DECISION TREE export_graphviz( tree_model, out_file='tree.dot', feature_names=X.columns, class_names=['unacc', 'acc', 'good', 'vgood'], filled=True, rounded=True ) Source.from_file('tree.dot')
* Igual se puede importar el árbol en fomato .png y .pdf
Me puse a jugar un poco con las variables y logré otros resultados como estos:
También logré que la gráfica sea diferente:
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()
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)
Hola, segun tengo entendido ese algoritmo de arboles es muy robusto ante datasets desbalanceados (desconozco la lógica interna), por lo que no sería descabellado asumir que ese es el performance que obtuviste. Repite el ejercicio con Sklearn y compara los resultados.
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%
### Entrenar el modelo solamente con persons y safety X_train_selected = X_train_encoder[['persons', 'safety']] X_test_selected = X_test_encoder[['persons', 'safety']] y_train_selected = y_train y_test_selected = y_test print("Shape of X_train_selected:", X_train_selected.shape) print("Shape of X_test_selected:", X_test_selected.shape) display(X_train_selected.head()) import seaborn as sns import matplotlib.pyplot as plt import pandas as pd importances = tree.feature_importances_ columns = X.columns # Create a Series for feature importances and filter for non-zero values feature_importance_series = pd.Series(importances, index=columns) important_features = feature_importance_series[feature_importance_series > 0] # Training the model with the selected features tree_selected = DecisionTreeClassifier(max_depth=2, random_state=0) tree_selected.fit( X_train_selected[['persons', 'safety']], y_train ) y_test_pred_selected = tree_selected.predict( X_test_selected[['persons', 'safety']] ) #Calculo el accuracy en Train train_accuracy_tree = accuracy_score(y_train, y_train_pred_tree) #Calculo el accuracy en Test test_accuracy_tree = accuracy_score(y_test, y_test_pred_selected) #Imprimimos los resultados print("\nResultados del Modelo:") print("Accuracy en Train:", train_accuracy_tree) print("Accuracy en Test:", test_accuracy_tree) print("\n") # Sort for better visualization important_features = important_features.sort_values(ascending=False) sns.barplot(x=important_features.index, y=important_features.values, palette = 'bright', saturation = 2.0, edgecolor ='black', linewidth = 2) plt.title('Importancia de cada Feature (Top Importantes)') plt.xlabel('Features') plt.ylabel('Importance Score') plt.show()
Resultados del Modelo:
Accuracy en Train: 0.7733664185277088
Accuracy en Test: 0.7591522157996147
# Select only the 'persons' and 'safety' columns from X_train and X_test
X_train_selected = X_train[['persons', 'safety']]
X_test_selected = X_test[['persons', 'safety']]
print("Shape of X_train_selected:", X_train_selected.shape)
print("Shape of X_test_selected:", X_test_selected.shape)
display(X_train_selected.head())
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
importances = tree.feature_importances_
columns = X.columns
# Create a Series for feature importances and filter for non-zero values
feature_importance_series = pd.Series(importances, index=columns)
important_features = feature_importance_series[feature_importance_series > 0]
# Sort for better visualization
important_features = important_features.sort_values(ascending=False)
sns.barplot(x=important_features.index, y=important_features.values, palette = 'bright', saturation = 2.0, edgecolor ='black', linewidth = 2)
plt.title('Importancia de cada Feature (Top Importantes)')
plt.xlabel('Features')
plt.ylabel('Importance Score')
plt.show()
Al dejar unicamente las variables de Persons y safety se sigue obteniendo el mismo accuracy que se tenia usando el resto de las variables
Al quitar features de dataset no supone ningún cambio puesto que las features más importantes se mantienen. Si se quiere obtener diferentes valores de las métrica se puede manipular la aleatoriedad o la produndida del árbol, teniendo en cuenta lo que conlleva esto: el sobreajuste; o si se quiere optimizar, aplicar XGBoost.