Clases desequilibradas
Parte de la sección Aprendizaje supervisado del Journey de Machine Learning de Coddy. Lección 24 de 58.
Cuando 95 de cada 100 pacientes están sanos, un modelo que siempre dice «sano» obtiene una precisión del 95 % y no detecta a nadie. Con clases desequilibradas, la precisión da una impresión engañosa:
Dos soluciones. stratify=y mantiene la proporción de 95 a 5 en ambos conjuntos, así que el conjunto de prueba incluye pacientes enfermos que detectar. class_weight="balanced" hace que cada fila poco frecuente cuente más:
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.25, random_state=0, stratify=y)
model = LogisticRegression(max_iter=1000, class_weight="balanced")El modelo equilibrado sacrifica un poco de precisión para detectar muchos más casos. En casos poco frecuentes, fíjate en la exhaustividad y la precisión, no en la exactitud.
Desafío
IntermedioAproximadamente el 5% de los rodamientos de una fábrica fallan antes de tiempo. El código inicial divide los registros de un banco de pruebas y evalúa un modelo simple, pero su conjunto de prueba contiene solo 2 rodamientos defectuosos, así que su valor de 0.993 significa poco.
- Corrige la división para que ambos conjuntos mantengan la misma proporción de rodamientos defectuosos.
- Entrena un segundo modelo que dé más peso a las filas defectuosas e imprime su línea como se muestra abajo.
Para otro banco:
Faulty bearings: train 8.1%, test 7.8%
Plain: accuracy 0.947, recall 0.417
Balanced: accuracy 0.900, recall 0.833Pruébalo tú mismo
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, recall_score
# Una fila por rodamiento del banco de pruebas: 1 en faulty significa que falló poco después
parts = pd.read_csv("bearings.csv")
features = ["vibration_mm_s", "temp_c", "noise_db", "hours_k"]
X = parts[features]
y = parts["faulty"]
# Corrige esta división
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=0)
print(f"Faulty bearings: train {y_train.mean() * 100:.1f}%, test {y_test.mean() * 100:.1f}%")
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
plain = LogisticRegression(max_iter=1000)
plain.fit(X_train, y_train)
pred = plain.predict(X_test)
print(f"Plain: accuracy {accuracy_score(y_test, pred):.3f}, recall {recall_score(y_test, pred):.3f}")
# Escribe tu código a continuación
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Aprendizaje supervisado
1Tu primer modelo
Aprender de ejemplosConjuntos de entrenamiento y pruebaAjustar y predecirEvaluar un modeloRepaso: clasificador de semillas4Regresión logística
Predicciones de sí o noEl umbral de decisiónLos pesos como evidenciaVarias clasesRepaso: filtro de spam2Vecinos más cercanos
Cómo decide k-NNCómo elegir kFronteras de decisiónEscalado para los vecinosRepaso: vecinos del vino5Medición de clasificadores
La matriz de confusiónPrecisión y exhaustividadLa puntuación F1Clases desequilibradasCurvas ROCRepaso: prueba de detección8Validación cruzada
Validación K-FoldComparación justa de modelosBúsqueda en cuadrículaRepaso: reparaciones de monopatines11Proyecto: especies de pingüinos
Conoce a los pingüinosPrepara los datosElige un modeloAjusta el modelo ganadorPublica el modelo3Regresión lineal
Predicción de númerosVarias característicasMedición de erroresGráficos de residuosRepaso: alquiler de bicicletas6Árboles de decisión
Los árboles hacen preguntasLeer un árbolProfundidad del árbolImportancia de las característicasRepaso: decisiones de préstamosPractica por tu cuenta: Compilador de Python online