Menu
CoddyTech

Classi sbilanciate

Fa parte della sezione Apprendimento supervisionato del percorso Machine Learning di Coddy. Lezione 24 di 58.

Quando 95 pazienti su 100 sono sani, un modello che dice sempre che sono sani ottiene un'accuratezza del 95% e non ne individua nessuno. Con classi sbilanciate, l'accuratezza è fuorviante:

Barre di accuratezza e richiamo per tre modelli su dati con il 5% di pazienti malati. Sempre sani: accuratezza 0.95, richiamo 0.00. Modello semplice: 0.98 e 0.62. Modello bilanciato: 0.94 e 0.92

Due correzioni. stratify=y mantiene la proporzione 95 a 5 in entrambi gli insiemi, così l’insieme di test contiene pazienti malati da individuare. class_weight="balanced" fa sì che ogni riga rara abbia più peso:

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")

Il modello bilanciato sacrifica un po’ di accuratezza per individuare molti più casi. Nei casi rari, considera il richiamo e la precisione, non l’accuratezza.

challenge icon

Sfida

Medio

Circa il 5% dei cuscinetti di una fabbrica si guasta precocemente. Il codice iniziale suddivide i dati di un banco di prova e valuta un modello semplice, ma il set di test contiene solo 2 cuscinetti difettosi, quindi il suo 0.993 dice poco.

  1. Correggi la suddivisione in modo che entrambi i set mantengano la stessa proporzione di cuscinetti difettosi.
  2. Addestra un secondo modello che assegni un peso maggiore alle righe relative ai cuscinetti difettosi e stampa la sua riga come mostrato sotto.

Per un altro banco di prova:

Faulty bearings: train 8.1%, test 7.8%
Plain: accuracy 0.947, recall 0.417
Balanced: accuracy 0.900, recall 0.833

Provalo tu

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 riga per ogni cuscinetto del banco di prova: 1 in faulty significa che si è guastato poco dopo
parts = pd.read_csv("bearings.csv")
features = ["vibration_mm_s", "temp_c", "noise_db", "hours_k"]
X = parts[features]
y = parts["faulty"]

# Correggi questa suddivisione
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}")

# Scrivi il tuo codice qui sotto
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Apprendimento supervisionato

Esercitati da solo: Compilatore Python online