Sergio Andrés Majé Franco
Layla Scheli
ProfesorGracias Sergio es correcto :)
Joaquín Ricardo Svoboda Abregú
muchas gracias por tu aporte! me ayudó mucho :D
Sergio Andrés Majé Franco
Layla Scheli
ProfesorGracias Sergio es correcto :)
Joaquín Ricardo Svoboda Abregú
muchas gracias por tu aporte! me ayudó mucho :D
Optimización de parametros , construccióm y evaluación del modelo
from sklearn.tree import DecisionTreeClassifier from sklearn.model_selection import GridSearchCV from sklearn.datasets import load_iris # Definir el clasificador y los valores de los hiperparámetros a probar clf = DecisionTreeClassifier() param_grid = {'criterion': ['gini', 'entropy'], 'max_depth': [2, 3, 4, 5]} # Realizar la búsqueda de hiperparámetros utilizando GridSearchCV grid_search = GridSearchCV(clf, param_grid=param_grid, cv=10) grid_search.fit(X_train, y_train) # Imprimir los resultados print("Mejores hiperparámetros encontrados:") print(grid_search.best_params_) print("Mejor puntuación de validación cruzada:") print(grid_search.best_score_) # Modelo con parametros optimizados best_clf = grid_search.best_estimator_ # Predecimos Y y_train_pred = best_clf.predict(X_train) y_test_pred = best_clf.predict(X_test) # Importamos matriz de confusion from sklearn.metrics import confusion_matrix confusion_matrix(y_test,y_pred)
# Graficamos matriz de confusion from sklearn.metrics import confusion_matrix from sklearn.metrics import ConfusionMatrixDisplay cm = confusion_matrix(y_test,y_test_pred,labels=best_clf.classes_) ConfusionMatrixDisplay(cm, display_labels=best_clf.classes_).plot()
# Calculo de las predicciones en Train y test y_train_pred = best_clf.predict(X_train) y_test_pred = best_clf.predict(X_test)
from sklearn.metrics import accuracy_score print('El accuracy en train es:',accuracy_score(y_train,y_train_pred)) print('El accuracy en test es:', accuracy_score(y_test,y_test_pred))
# Verificamos el feature importances importances = grid_search.best_estimator_.feature_importances_ importances = np.sort(importances)[::-1] columns = X.columns sns.barplot(x=columns, y=importances); plt.title('Factores principales que influyen en la supervivencia del pasajero');
Julián Cárdenas
Sí les sale el error solo asignen la variable x=columns y la variable y=importances; de esta manera:
import seaborn as sns importances = tree.feature_importances_ columns = X.columns sns.barplot(x= columns,y= importances, palette = 'bright', saturation = 2.0, edgecolor = 'black', linewidth = 2) plt.title('Importancia de cada Feature') plt.show()
Jeinfferson Bernal G
Wow... Una solucion muy simple. Gracias 👍🏻👏
Mauricio Combariza
En lo personal me gustaria saber como funciona sklearn en su interior para hacer las predicciones.
Layla Scheli
ProfesorHola! se agrego un material complementario :)
Julián Cárdenas
Sí pero no es lo suficientemente profundo, ya que sklearn tiene demasiados modelos
Ana Muñoz Maquera
Que el acc en train no este tan alejado que el acc en test nos indica una buena performance. Si el acc en train hubiese sido 95% vs el acc en test 76% diríamos que el modelo estaría con overfiting y tendríamos que cambiar sus parámetros
Arazani Balcazar Martínez
Si el acc en el test es de 76% y el acc en el train es de 95% dado el overfiting al cambiar los parametros no estariamos escogiendo el modelo que más se adapte solo a una parte del conjunto de datos y no el dataset completo. (?)
Layla Scheli
ProfesorGracias Ana y Arazani, por sus aporte :)
Santiago Ahumada Lozano
Solo un pequeño comentario: Al analizar la importancia de cada caracteristica para inferir cuales son las variables necesarias para construir un modelo mas simple/eficaz estamos "tomando decisiones sobre el modelo" Esto tipicamente debería hacerse en una fase conocida como validación, en donde básicamente optimizamos a un nivel alto las configuraciones de nuestro modelo.
En este caso pienso que es mejor llamar a X_test y a y_test como X_val y y_val (Haciendo referencia a que son datos que el modelo va usar para ser mejorado) Y que sirven para tomar decisiones.
El conjunto de testeo solo debería ser usado para reportar resultados, ya que es pensado exclusivamente para estimar el bias del modelo.
Juan José Mamani Tarqui
USO DE LA SEMILLA (random_state)
El parámetro random_state en diversas funciones de bibliotecas como scikit-learn se utiliza para controlar la reproducibilidad de los resultados aleatorios. Puede tomar varios valores, y cada valor producirá un resultado diferente. Aquí hay algunos detalles sobre cómo puedes elegir y utilizar el random_state:
Número Entero Fijo: Puedes proporcionar un número entero fijo como semilla. Esto garantiza que, si vuelves a ejecutar tu código con la misma semilla, obtendrás los mismos resultados aleatorios.pythonCopy coderandom_state = 42 # Puedes elegir cualquier número entero
None (o Sin Especificar): Si no proporcionas un valor para random_state o lo estableces en None, el resultado será diferente en cada ejecución. Esto es útil si deseas resultados aleatorios diferentes cada vez.pythonCopy coderandom_state = None # O simplemente no establecer random_state
Número Aleatorio: También puedes usar cualquier número aleatorio como semilla. En este caso, el resultado variará en cada ejecución.pythonCopy codeimport random
random_state = random.randint(1, 1000) # Un número aleatorio
Seed Fijo y Variable Aleatoria: Puedes combinar un número fijo con una parte aleatoria para obtener reproducibilidad y variabilidad.pythonCopy codeimport random
random_state = 42 + random.randint(1, 1000) # Semilla fija + parte aleatoria
En resumen, la elección del random_state depende de tus necesidades. Si deseas resultados reproducibles, establece un número fijo. Si buscas variabilidad en cada ejecución, déjalo como None o no lo especifiques.
Sebastian Ponce
Sebastian Ponce
Este error es por la versión, con la actualización desde las 0.12 ya no se pueden pasar dos parametros, solo una data.
¿Saben como poner columns y importance como una lista ?
Sergio Andrés Majé Franco
Alberto Bernaola
si tienes un DataFrame, solo necesitas pasar los nombres de las columnas directamente a Seaborn, y si no tienes un DataFrame, puedes especificar los datos usando los parámetros x e y.
sns.barplot(x=columns, y=importances, palette='bright', saturation=2, edgecolor='black', linewidth=2)
Layla Scheli
ProfesorBuen aporte Alberto :)
Isaac Bryan Ascanoa Roncall
Me gusta esta demostracion en la cual se debe analizar el funcionamiento de este y como lo podemos implementar por medio de una grafica de seaborn. En la universidad nunca enseñaron esa parte. Solo era el codigo y ver la metrica si coincidia el resultado.
Juan Esteban
Una mejor forma de hacer el barplot con matplotlib sería:
importances = np.sort(dt.feature_importances_) columns = X.columns[np.argsort(importances)] ax = plt.figure().gca() ax.bar(x=columns, height=importances, edgecolor='k') ax.invert_xaxis() ax.set(title='Importancia de cada feature') plt.show()
De esta manera se muestran las barras en orden descendente (primero se ordenan ascendentemente y se invierte el orden del eje x).
Edwin Uldarico Hernandez Osorio
me parece curioso el uso de 00000 para el random_state, la documentación dice.
Integer values must be in the range [0, 2**32 - 1].
supongo que viene siendo simplemente un solo 0
https://scikit-learn.org/stable/glossary.html#term-random_state
Layla Scheli
ProfesorHola Edwin, es simplemente cualquier nros, podrias poner otro en su lugar :)
Diego Mauricio Zuluaga Rodríguez
¿Cuál es la mejor forma de evaluarlo?
La mejor forma de evaluarlo depende de tu problema. Si estás clasificando categorías, la métrica Accuracy es un buen inicio usando el método .score(). Sin embargo, para un análisis más profundo, es vital generar una Matriz de Confusión (confusion_matrix) y un Reporte de Clasificación (classification_report). Estas herramientas te mostrarán exactamente dónde se está equivocando tu modelo, desglosando los falsos positivos y falsos negativos. Si tu dataset está desbalanceado, enfócate siempre en las métricas Precision y Recall.
Diego Mauricio Zuluaga Rodríguez
¿Cuándo debo limitar la profundidad del árbol?
Debes limitar la profundidad de tu árbol cuando notes que el rendimiento en tus datos de entrenamiento es casi perfecto, pero la precisión cae drásticamente al evaluarlo con tus datos de prueba. Un árbol sin restricciones crecerá hasta que cada hoja contenga una sola muestra, volviéndose demasiado complejo y perdiendo capacidad de generalización. Configurar el parámetro max_depth en scikit-learn a un valor conservador suele ser un excelente punto de partida para mantener un equilibrio entre aprendizaje y predicción en el mundo real.
Diego Mauricio Zuluaga Rodríguez
¿Cómo evito que el árbol memorice datos?
Para evitar que tu modelo simplemente memorice los datos de entrenamiento (un problema conocido como overfitting o sobreajuste), debes controlar su crecimiento. En scikit-learn, puedes lograr esto ajustando hiperparámetros clave durante la instanciación del modelo. Por ejemplo, usar max_depth limita cuántas divisiones puede hacer el árbol, mientras que min_samples_split exige un número mínimo de datos para permitir una nueva ramificación. Al restringir su complejidad, obligas al algoritmo a encontrar patrones generales en lugar de crear reglas perfectas pero inútiles para datos nuevos.
Martha Patricia Ortiz Martinez
Cada semilla tienen algún comportamiento diferente?
Jhustyn Estévez
Company_adminCada seed define una secuencia distinta de números aleatorios
Sebastián Franco
Mario Alexander Vargas Celis
Aquí tienes un ejemplo completo y explicado paso a paso de cómo entrenar y evaluar un árbol de decisión usando scikit-learn con el dataset del Titanic:
🧪 1. Cargar y preparar los datos
import pandas as pd from sklearn.model_selection import train_test_split from sklearn.tree import DecisionTreeClassifier from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
# Cargar el dataset (puede ser desde seaborn, kaggle o archivo local) titanic = pd.read_csv('titanic.csv') # o usa seaborn.load_dataset('titanic')
# Selección de variables features = ['Pclass', 'Sex', 'Age', 'Fare'] target = 'Survived'
# Eliminar nulos simples (sólo para simplificar el ejemplo) titanic = titanic.dropna(subset=features + [target])
# Convertir variables categóricas a numéricas titanic = pd.get_dummies(titanic, columns=['Sex'], drop_first=True, dtype=int)
# Variables predictoras y variable objetivo X = titanic[['Pclass', 'Age', 'Fare', 'Sex_male']] y = titanic[target]
🧠 2. Dividir en conjunto de entrenamiento y prueba
X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42 )
🌲 3. Entrenar el árbol de decisión
model = DecisionTreeClassifier(random_state=42) model.fit(X_train, y_train)
📊 4. Evaluación del modelo
# Predicciones y_pred = model.predict(X_test)
# Métricas print("Accuracy:", accuracy_score(y_test, y_pred)) print("\nClassification Report:\n", classification_report(y_test, y_pred)) print("\nConfusion Matrix:\n", confusion_matrix(y_test, y_pred))
🌳 5. (Opcional) Visualizar el árbol
from sklearn.tree import plot_tree import matplotlib.pyplot as plt
plt.figure(figsize=(20, 10)) plot_tree(model, feature_names=X.columns, class_names=['No', 'Yes'], filled=True) plt.show()
✅ Resultado
Con esto obtendrás:
accuracy, precision, recall, f1-score).Diego Andrés Rojas Pinzón
Una pregunta intente volver a hacer el modelo pero esta vez quitándole los campos que no tienen mucha importancia en los features, como lo son: 'SibSp','Parch'
pero sigue dando el mismo acurracy, no debería mejorar aunque sea un poco ?
Layla Scheli
ProfesorHola Diego, no necesariamente, dado que esos campos no tienen relevancia, no modifican el resultado final :)
Jose Diaz
Hay diferencia entre un random state de valor 0 y 0000?
Layla Scheli
ProfesorHola Jose, si en realidad la semilla de los datos de prueba puede variar entre un parametro y otro, podes ir probando el codigo con diferentes valores justamente para analizar el fenomeno de aleatoriedad :)
Para los que les lance este error
TypeError: barplot() takes from 0 to1 positional arguments but 2 positional arguments
Es porque están trabajando con una versión más reciente de seaborn, que la que se emplea en el curso.
Para resolver este error toca que crear un nuevo DataFrame con los importances y columns
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()
Así, de esta forma, ya podemos obtener nuestra gráfica sin ningún error
Hola, tengo el siguente Error, ¿Me pueden ayudar a solucionarlo? Llevo horas buscando u no encuentro cual es el problema
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[52], line 6 4 importances = tree.feature_importances_ 5 columns = X.columns ----> 6 sns.barplot(columns, importances, palette = 'bright', saturation = 2.0, edgecolor = 'black', linewidth = 2) 7 plt.title('Importancia de cada Feature') 8 plt.show() TypeError: barplot() takes from 0 to 1 positional arguments but 2 positional arguments (and 2 keyword-only arguments) were given
Para resolverlo toca que crear un nuevo DataFrame con los importances y columns
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()
Ahora se va a crear y evaluar un árbol de decisión
Lo primero será splitter el dataset en 70% train y 30% test, luego crearemos el árbol de decisión desde la librería de scikit-learn, finalmente entrenaremos con la data de entrenamiento
from sklearn.model\_selection import train\_test\_split \# Split data - 70% train and 30% test X\_train, X\_test, Y\_train, Y\_test = train\_test\_split(X, Y, test\_size=0.3, random\_state=42) from sklearn.tree import DecisionTreeClassifier \# Create tree model tree = DecisionTreeClassifier( max\_depth=2, random\_state=42 ) \# Train model tree.fit(X\_train, Y\_train)
Ahora se evaluará el performance del modelo, para esto se predecirá los resultados del modelo y se usará de métrica el accuracy
\# Model evaluation y\_train\_pred = tree.predict(X\_train) y\_test\_pred = tree.predict(X\_test) from sklearn.metrics import accuracy\_score \# Metric calculation train\_accuracy = accuracy\_score(Y\_train, y\_train\_pred) test\_accuracy = accuracy\_score(Y\_test, y\_test\_pred) print(f"Train accuracy: {train\_accuracy}") print(f"Test accuracy: {test\_accuracy}") \# Train accuracy: 0.8064516129032258 \# Test accuracy: 0.7378277153558053
El performance en train y test es similar, pero no es óptimo (al menos no se ha overfitteado)
Ahora se graficará la la relevancia de los features
import seaborn as sns \# Checking features importancy importances = tree.feature\_importances\_ columns = X.columns sns.barplot( x=columns, y=importances, hue=columns, palette="bright", saturation=2.0, edgecolor="black", linewidth=2 ) plt.title("Feature Importance Barplot") plt.xlabel("Features") plt.ylabel("Imporance") plt.show()
Aquí se puede notar que el feature Sex es el más relevante de todos, seguido por Pclass y un poco age. SibSp y ParCh no fueron relevantes para esta decisión, por lo que podrían ser eliminados del entrenamiento en una futura iteración
Como nota extra, se puede calcular la relevancia de las variables por el cómo aporta esa variable a reducir la impureza del árbol, esto no es posible en algoritmos como redes neuronales sin mecanismos de explicabilidad explícitos como SHAP