
Proyecto Katy Payne — Sesión 3: entrenamos y comprobamos los resultados
Última sesión de este mini proyecto: entrenamos un Random Forest —el mismo comité de árboles de siempre— y comprobamos si de verdad distingue bien gatos de perros.
Entrenando el modelo
from sklearn.ensemble import RandomForestClassifier
X_entrenamiento = datos_entrenamiento.drop(columns=["clase"])
y_entrenamiento = datos_entrenamiento["clase"]
X_prueba = datos_prueba.drop(columns=["clase"])
y_prueba = datos_prueba["clase"]
bosque = RandomForestClassifier(n_estimators=100, random_state=42)
bosque.fit(X_entrenamiento, y_entrenamiento)
exactitud = bosque.score(X_prueba, y_prueba)
print(f"Exactitud: {exactitud:.2%}")
[COMPLETAR CON VUESTROS DATOS REALES: exactitud del bosque = ___. Comparadla con la de Laennec — ¿cuánto mejor es?]

Matriz de confusión e informe completo
Con solo dos clases, la matriz tiene 4 casillas — la más sencilla de leer de toda la familia de proyectos:
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay, classification_report
etiquetas = ["gato", "perro"]
predicciones = bosque.predict(X_prueba)
cm = confusion_matrix(y_prueba, predicciones, labels=etiquetas)
disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=etiquetas)
disp.plot(cmap="Blues")
plt.title("Matriz de confusión — gatos y perros por sonido")
plt.show()
print(classification_report(y_prueba, predicciones, labels=etiquetas, target_names=etiquetas))
Fijaos en que aquí, como en Laennec, classification_report lleva labels=etiquetas además de target_names=etiquetas — con clases en texto, siempre hace falta para que las filas no se descoloquen.
[COMPLETAR CON VUESTROS DATOS REALES: precisión y exhaustividad de cada clase = ___]

Una escucha rápida de propina
Elegimos un sonido de prueba al azar y comprobamos si el bosque acierta:
import random
indice = random.randrange(len(X_prueba))
print("Predicción del bosque:", bosque.predict(X_prueba.iloc[[indice]])[0])
print("Clase real:", y_prueba.iloc[indice])
nombre_archivo = (reparto["test_cat"].dropna().tolist() + reparto["test_dog"].dropna().tolist())[indice]
Audio(carpeta_audios + nombre_archivo)

Cierre
Con dos clases bien equilibradas y sonidos claramente distintos, el resultado de hoy debería ser notablemente mejor que el de Laennec — el mismo tipo de herramienta (MFCC + Random Forest) rinde de forma muy distinta según el problema. Buena lección para cerrar: la calidad de un modelo no depende solo del algoritmo que elijáis, depende muchísimo de cómo son los datos con los que lo alimentáis. Es, en el fondo, la misma lección de Katy Payne que dio nombre a este proyecto: la herramienta correcta no crea el patrón, solo lo hace visible — si el patrón apenas existe en los datos (como la extrasístole de Laennec, escondida entre pocos ejemplos), ninguna herramienta lo va a sacar mucho mejor.



