Machine Learning Academy · Lezione

Strategie di mitigazione dei bias: pre-processing, in-processing e post-processing

Applicherà il reweighting (pre-processing), aggiungerà un vincolo di fairness all'addestramento (in-processing) e calibrerà le soglie decisionali per ciascun gruppo (post-processing), confrontando i compromessi.

Lezione 4 di 413 passaggi

Strategie di mitigazione dei bias: pre-processing, in-processing e post-processing è una lezione Machine Learning Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Machine Learning Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Machine Learning Academy include 4 lezioni in totale.

Le tre fasi della mitigazione dei bias

Le strategie di mitigazione dei bias rientrano in tre categorie, in base al punto della pipeline di ML in cui intervengono. I metodi di pre-processing modificano i dati di addestramento prima di addestrare qualsiasi modello. I metodi di in-processing modificano direttamente l'algoritmo di apprendimento per imporre l'equità durante l'addestramento. I metodi di post-processing modificano gli output del modello dopo l'addestramento senza cambiare il modello. Ogni approccio comporta compromessi diversi in termini di accuratezza, flessibilità e costo computazionale.

Pre-processing: ripesatura

La ripesatura assegna pesi diversi agli esempi di addestramento in modo che la distribuzione ponderata sia equa rispetto all'attributo protetto. Agli esempi appartenenti a combinazioni (etichetta, gruppo) sottorappresentate viene assegnato un peso maggiore; alle combinazioni sovrarappresentate, un peso minore. Il modello viene quindi addestrato con questi pesi usando il parametro sample_weight, accettato dalla maggior parte degli stimatori di scikit-learn. Non sono necessarie modifiche all'algoritmo.

from fairlearn.preprocessing import CorrelationRemover
import numpy as np
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler

# Reweighing: compute weights to balance (group, label) combinations
def compute_reweighing_weights(y, sensitive):
    n = len(y)
    weights = np.ones(n)
    for label in np.unique(y):
        for group in np.unique(sensitive):
            mask = (y == label) & (sensitive == group)
            expected = (y == label).mean() * (sensitive == group).mean()
            actual = mask.mean()
            if actual > 0:
                weights[mask] = expected / actual
    return weights

# Usage: model.fit(X_train, y_train, sample_weight=weights)

Pre-processing: rimozione delle feature proxy

Anche in assenza dell'attributo protetto, feature proxy come il codice postale o il cognome possono codificare informazioni demografiche. La rimozione della correlazione proietta le feature in modo da ridurne la correlazione con l'attributo sensibile. fairlearn.preprocessing.CorrelationRemover implementa questa tecnica sottraendo da ogni feature la sua proiezione sull'attributo sensibile e producendo feature decorrelate. In questo modo si riduce la capacità del modello di apprendere pattern discriminatori attraverso i proxy.

from fairlearn.preprocessing import CorrelationRemover
import numpy as np

X = np.random.randn(500, 5)
sensitive = np.random.choice([0, 1], 500)

# Project out correlation with sensitive attribute
cr = CorrelationRemover(sensitive_feature_ids=[0])  # column 0 is sensitive
X_fair = cr.fit_transform(X)

print('Original correlation with sensitive:', np.corrcoef(X[:, 0], sensitive)[0, 1])
print('After removal:', np.corrcoef(X_fair[:, 0], sensitive)[0, 1])

In-processing: Exponentiated Gradient

L'algoritmo Exponentiated Gradient di fairlearn è un meta-algoritmo che avvolge qualsiasi classificatore di scikit-learn e lo addestra iterativamente con pesi dei campioni modificati per soddisfare un vincolo di equità (ad esempio, le odds equalizzate). Risolve un problema di ottimizzazione vincolata: minimizzare l'errore di classificazione rispettando il vincolo di equità entro una tolleranza epsilon. Il risultato è un insieme randomizzato di classificatori che bilancia accuratezza ed equità.

from fairlearn.reductions import ExponentiatedGradient, EqualizedOdds
from sklearn.linear_model import LogisticRegression
import numpy as np

np.random.seed(42)
X = np.random.randn(600, 4)
sensitive = np.random.choice(['A', 'B'], 600)
y = (X[:, 0] + np.random.randn(600) * 0.5 > 0).astype(int)

base_estimator = LogisticRegression(max_iter=1000)
mitigator = ExponentiatedGradient(
    base_estimator,
    constraints=EqualizedOdds(),
    eps=0.05  # allowed violation
)
mitigator.fit(X, y, sensitive_features=sensitive)
y_pred_fair = mitigator.predict(X)
print('Predictions generated:', y_pred_fair[:10])

In-processing: GridSearch per l'equità

fairlearn.reductions.GridSearch è un'alternativa più semplice che esegue una ricerca a griglia sui moltiplicatori di Lagrange del vincolo di equità, addestrando un modello separato per ogni valore del moltiplicatore. Il risultato è un insieme di punti di compromesso (accuratezza, equità) che formano una frontiera di Pareto. È quindi possibile selezionare il modello che raggiunge la soglia minima di equità con la massima accuratezza. È pienamente compatibile con qualsiasi stimatore di sklearn.

from fairlearn.reductions import GridSearch, DemographicParity
from sklearn.tree import DecisionTreeClassifier

gs = GridSearch(
    DecisionTreeClassifier(max_depth=4),
    constraints=DemographicParity(),
    grid_size=10
)
gs.fit(X, y, sensitive_features=sensitive)

# Inspect trade-off frontier
for pred in gs.predictors_:
    y_hat = pred.predict(X)
    acc = (y_hat == y).mean()
    dp_diff = abs(
        y_hat[sensitive == 'A'].mean() - y_hat[sensitive == 'B'].mean()
    )
    print(f'Accuracy={acc:.3f} | DP difference={dp_diff:.3f}')

Post-processing: calibrazione della soglia per gruppo

La calibrazione della soglia applica soglie decisionali diverse a ciascun gruppo demografico, in modo da soddisfare un criterio di equità scelto. Ad esempio, per ottenere pari opportunità, si abbassa la soglia per un gruppo svantaggiato finché il suo tasso di veri positivi non corrisponde a quello del gruppo avvantaggiato. Questo è l'approccio di post-processing più semplice e non richiede un nuovo addestramento, perciò è facile da applicare a qualsiasi modello in produzione.

import numpy as np
from sklearn.metrics import recall_score

# Assume model outputs probabilities: proba_A, proba_B for each group
np.random.seed(0)
proba = np.random.beta(2, 5, 600)  # model probability scores
y_true = (proba > 0.3 + np.random.randn(600) * 0.1).astype(int)

mask_A = sensitive == 'A'
mask_B = sensitive == 'B'

# Find threshold for group B to match group A's TPR at threshold 0.5
base_tpr = recall_score(y_true[mask_A], (proba[mask_A] >= 0.5).astype(int))
for thresh in np.arange(0.2, 0.7, 0.01):
    tpr_B = recall_score(y_true[mask_B], (proba[mask_B] >= thresh).astype(int))
    if abs(tpr_B - base_tpr) < 0.02:
        print(f'Equal-opportunity threshold for group B: {thresh:.2f} (TPR={tpr_B:.3f})')
        break

Post-processing: ThresholdOptimizer in fairlearn

fairlearn.postprocessing.ThresholdOptimizer automatizza la calibrazione delle soglie per gruppo. Riceve uno stimatore addestrato, lo avvolge e individua le soglie specifiche per gruppo che minimizzano un obiettivo scelto (ad esempio, l'accuratezza bilanciata) nel rispetto di un vincolo di equità. In fase di previsione, indirizza ogni campione alla soglia appropriata in base all'appartenenza al gruppo: il processo è trasparente e verificabile.

from fairlearn.postprocessing import ThresholdOptimizer
from fairlearn.metrics import equalized_odds_difference
from sklearn.linear_model import LogisticRegression

base_model = LogisticRegression(max_iter=1000)
base_model.fit(X, y)

to = ThresholdOptimizer(
    estimator=base_model,
    constraints='equalized_odds',
    objective='balanced_accuracy_score',
    predict_method='predict_proba'
)
to.fit(X, y, sensitive_features=sensitive)
y_pred_to = to.predict(X, sensitive_features=sensitive)

print('EO difference before:', equalized_odds_difference(y, base_model.predict(X), sensitive_features=sensitive))
print('EO difference after:', equalized_odds_difference(y, y_pred_to, sensitive_features=sensitive))

Confronto tra i tre approcci

Ogni fase di intervento comporta implicazioni pratiche. Il pre-processing non dipende dal modello e può essere applicato una sola volta a tutti i modelli successivi, ma può comportare una perdita di informazioni. L'in-processing integra l'equità nell'obiettivo di ottimizzazione e spesso raggiunge il miglior equilibrio tra accuratezza ed equità, ma richiede un nuovo addestramento. Il post-processing è il metodo più semplice da applicare a un modello già in produzione senza riaddestrarlo, ma può essere meno efficace quando i punteggi di probabilità sono calibrati male tra i gruppi.

comparison = {
    'Pre-processing (reweighing/removal)': {
        'requires_retraining': True,
        'model_agnostic': True,
        'typical_accuracy_cost': 'Low to medium'
    },
    'In-processing (Exp. Gradient)': {
        'requires_retraining': True,
        'model_agnostic': True,
        'typical_accuracy_cost': 'Medium'
    },
    'Post-processing (threshold optimizer)': {
        'requires_retraining': False,
        'model_agnostic': True,
        'typical_accuracy_cost': 'Low (if scores are calibrated)'
    }
}
for method, props in comparison.items():
    print(method, '->', props)

Misurare l'efficacia della mitigazione

Dopo aver applicato una strategia di mitigazione, ricalcoli l'intero insieme di metriche di equità per verificare il miglioramento. Misuri inoltre il costo in termini di accuratezza: la differenza tra l'accuratezza complessiva del modello non mitigato e quella del modello mitigato. Tracci la curva del compromesso tra equità e accuratezza per diversi livelli di mitigazione, così da aiutare gli stakeholder a scegliere un punto operativo. Documenti il punto scelto e la motivazione nella model card.

from fairlearn.metrics import MetricFrame, demographic_parity_difference
from sklearn.metrics import accuracy_score
import numpy as np

results = []
for threshold_offset in [0.0, -0.05, -0.10, -0.15]:
    y_hat = np.where(
        sensitive == 'B',
        (proba >= 0.5 + threshold_offset).astype(int),
        (proba >= 0.5).astype(int)
    )
    acc = accuracy_score(y_true, y_hat)
    dp = demographic_parity_difference(y_true, y_hat, sensitive_features=sensitive)
    results.append({'offset': threshold_offset, 'accuracy': acc, 'dp_diff': abs(dp)})
    print(f'offset={threshold_offset:.2f}: accuracy={acc:.3f}, dp_diff={abs(dp):.3f}')

L'equità oltre le metriche tecniche

La mitigazione tecnica è necessaria, ma non sufficiente per un'IA responsabile. Le comunità interessate devono partecipare alla definizione di ciò che significa equità nel loro contesto. I team responsabili della messa in produzione dovrebbero stabilire un monitoraggio continuo del deterioramento dell'equità dovuto ai cambiamenti nella distribuzione della popolazione. Audit periodici condotti da terze parti, meccanismi di ricorso chiari per le persone interessate e una comunicazione trasparente dell'approccio di mitigazione fanno tutti parte di una pratica completa di IA responsabile.

# Non-technical checklist for responsible deployment
checklist = [
    'Affected community consulted on fairness definition',
    'Model card documents protected attributes, metrics, and mitigation',
    'Fairness metrics monitored in production alongside accuracy',
    'Individual appeal process exists for adverse decisions',
    'Third-party audit scheduled before high-stakes deployment',
    'Data provenance documented to detect historical bias sources'
]
for item in checklist:
    print('[x]', item)

Pipeline di equità end-to-end

Una pipeline di ML completa e orientata all'equità combina tutte le fasi. Inizi con il pre-processing (rimuova le feature proxy e applichi la ripesatura), addestri il modello con un vincolo di in-processing per integrare l'equità nell'obiettivo e applichi la calibrazione delle soglie di post-processing se rimangono disparità. Dopo la messa in produzione, integri il monitoraggio per rilevare quando i cambiamenti nella distribuzione fanno variare le metriche di equità e avvii un nuovo addestramento quando vengono superate le soglie.

# Sketch of a full fairness-aware pipeline
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from fairlearn.reductions import ExponentiatedGradient, EqualizedOdds
from sklearn.linear_model import LogisticRegression

# Step 1: pre-process (reweighing done externally via sample_weight)
preprocessor = StandardScaler()
X_scaled = preprocessor.fit_transform(X)

# Step 2: in-processing with fairness constraint
mitigator = ExponentiatedGradient(
    LogisticRegression(max_iter=1000),
    constraints=EqualizedOdds(),
    eps=0.05
)
mitigator.fit(X_scaled, y, sensitive_features=sensitive)

# Step 3: evaluate and document
y_fair = mitigator.predict(X_scaled)
print('Fair model accuracy:', (y_fair == y).mean().round(3))

Verifica rapida

Verifichi la Sua comprensione dei concetti di Machine Learning con Python trattati in questa lezione.

Riepilogo della lezione

In questa lezione ha imparato che: i metodi di pre-processing (ripesatura, rimozione della correlazione) modificano i dati di addestramento prima dell'addestramento del modello, i metodi di in-processing (Exponentiated Gradient, GridSearch) integrano i vincoli di equità nell'obiettivo di apprendimento e i metodi di post-processing (ThresholdOptimizer) calibrano le soglie per gruppo dopo l'addestramento. Insieme, questi strumenti consentono di ridurre sistematicamente i bias misurati tramite parità demografica, pari opportunità e odds equalizzate. Ora inizieremo il progetto finale definendo un problema reale di ML end-to-end.

Gratis per iniziare

Impara Python con un tutor IA — gratis

Scrivi ed esegui vero codice nel tuo browser, ricevi aiuto istantaneo da un tutor IA disponibile 24/7, e riprendi da dove hai lasciato sul web o nell'app.

Corsi
30
Lezioni
120

Domande Frequenti

La lezione «Strategie di mitigazione dei bias: pre-processing, in-processing e post-processing» è gratuita?

Sì — il testo completo di «Strategie di mitigazione dei bias: pre-processing, in-processing e post-processing» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Machine Learning Academy, passa a CoddyKit PRO. Il corso Machine Learning Academy include 4 lezioni in totale.

Cosa imparerò in «Strategie di mitigazione dei bias: pre-processing, in-processing e post-processing»?

Applicherà il reweighting (pre-processing), aggiungerà un vincolo di fairness all'addestramento (in-processing) e calibrerà le soglie decisionali per ciascun gruppo (post-processing), confrontando i… Eserciti Machine Learning Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Machine Learning Academy?

Non è richiesta alcuna esperienza precedente. Machine Learning Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.

Quanto tempo richiede la lezione «Strategie di mitigazione dei bias: pre-processing, in-processing e post-processing»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Machine Learning Academy?

Sì. Ogni lezione Machine Learning Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Valori SHAP: importanza globale e locale delle feature
  2. LIME: spiegazioni locali e interpretabili indipendenti dal modello
  3. Metriche di fairness: parità demografica e pari opportunità
  4. Strategie di mitigazione dei bias: pre-processing, in-processing e post-processing
← Torna a Machine Learning Academy