Salvare i modelli con joblib e pickle
Imparerete a serializzare una pipeline addestrata con joblib e pickle, ricaricarla e verificare che le previsioni siano identiche, confermando la corretta serializzazione e deserializzazione.
Salvare i modelli con joblib e pickle è una lezione Machine Learning Academy gratuita su CoddyKit. Questa è la lezione 1 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.
Perché la persistenza del modello è importante
Addestrare un modello di machine learning è costoso: può richiedere da alcuni minuti a diverse ore e consumare notevoli risorse di calcolo. La persistenza del modello salva su disco il modello adattato, così da poterlo ricaricare immediatamente per l’inferenza senza ripetere l’addestramento. Questo costituisce il collegamento tra il notebook di data science e un sistema di produzione: il file del modello serializzato è l’artefatto distribuibile che i data engineer preparano e mettono a disposizione.
Che cosa viene salvato in un file del modello?
Quando si serializza un modello o una pipeline sklearn adattati, il file contiene: tutti i parametri adattati, come media e varianza dello scaler, struttura dell’albero e coefficienti della regressione logistica; le impostazioni degli iperparametri; e il riferimento alla definizione della classe Python. I dati di addestramento NON sono inclusi. Il caricamento del file ricostruisce un oggetto Python pronto per chiamare immediatamente predict.
Salvataggio con joblib.dump
joblib è lo strumento di serializzazione consigliato per gli oggetti sklearn. Gestisce in modo efficiente i grandi array NumPy usando il memory mapping e supporta la compressione trasparente. Il flusso di lavoro standard consiste nell’addestrare il modello, salvarlo in un file .joblib e poi caricarlo in uno script o servizio separato per l’inferenza.
import joblib
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_breast_cancer
X, y = load_breast_cancer(return_X_y=True)
pipe = Pipeline([
('scaler', StandardScaler()),
('clf', LogisticRegression(C=1.0, max_iter=300))
])
pipe.fit(X, y)
# Save
joblib.dump(pipe, '/tmp/cancer_model.joblib')
print('Model saved to /tmp/cancer_model.joblib')Caricamento con joblib.load
joblib.load deserializza il file e restituisce esattamente l’oggetto pipeline adattato. Il modello caricato possiede gli stessi attributi dell’originale, tra cui named_steps, i parametri adattati dello scaler e i coefficienti del classificatore. È possibile chiamare immediatamente predict, predict_proba o score senza alcuna configurazione aggiuntiva.
import joblib
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
# Load in a fresh context
model = joblib.load('/tmp/cancer_model.joblib')
predictions = model.predict(X_test[:5])
print('Predictions:', predictions)
print('Test accuracy:', model.score(X_test, y_test).round(4))Uso di pickle per la serializzazione
Anche il modulo pickle della libreria standard di Python serializza gli oggetti sklearn. Apra i file in modalità binaria: 'wb' per la scrittura e 'rb' per la lettura. La costante pickle.HIGHEST_PROTOCOL usa il protocollo più efficiente disponibile. Per i modelli piccoli o nei contesti di scripting, pickle è assolutamente adeguato.
import pickle
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_iris
X, y = load_iris(return_X_y=True)
model = LogisticRegression().fit(X, y)
# Save
with open('/tmp/iris_model.pkl', 'wb') as f:
pickle.dump(model, f, protocol=pickle.HIGHEST_PROTOCOL)
# Load
with open('/tmp/iris_model.pkl', 'rb') as f:
loaded = pickle.load(f)
print('Score:', loaded.score(X, y).round(4))
print('Coefficients shape:', loaded.coef_.shape)Confronto delle dimensioni dei file joblib e pickle
Per un modello grande, come un RandomForest con 1000 alberi, la memorizzazione degli array NumPy tramite memory mapping di joblib è più efficiente. La differenza è particolarmente evidente quando il modello contiene grandi matrici di parametri. Per i modelli piccoli, come LogReg e SVM, la differenza di dimensioni è trascurabile.
import joblib
import pickle
import os
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_classification
X, y = make_classification(n_samples=1000, n_features=20, random_state=0)
rf = RandomForestClassifier(n_estimators=100, random_state=0).fit(X, y)
# joblib
joblib.dump(rf, '/tmp/rf_model.joblib')
# pickle
with open('/tmp/rf_model.pkl', 'wb') as f:
pickle.dump(rf, f)
print(f'joblib size: {os.path.getsize("/tmp/rf_model.joblib"):,} bytes')
print(f'pickle size: {os.path.getsize("/tmp/rf_model.pkl"):,} bytes')Compressione con joblib
Utilizzi joblib.dump(model, path, compress=3) per comprimere il file usando zlib. I livelli di compressione vanno da 1 (veloce, file più grande) a 9 (lento, file più piccolo). Il livello 3 è un valore predefinito pratico. Per la compressione LZ4 (più veloce di zlib): compress=('lz4', 1). Il tempo di caricamento aumenta leggermente per i file compressi, ma il risparmio nel trasferimento di rete e nello spazio di archiviazione vale spesso la pena.
import joblib
import os
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_classification
X, y = make_classification(n_samples=1000, random_state=0)
rf = RandomForestClassifier(n_estimators=100, random_state=0).fit(X, y)
for level in [0, 3, 6, 9]:
path = f'/tmp/rf_compress_{level}.joblib'
joblib.dump(rf, path, compress=level)
size = os.path.getsize(path)
print(f'compress={level}: {size:,} bytes')Verifica della coerenza round-trip
Dopo il caricamento, verifichi sempre che il modello caricato produca previsioni identiche a quelle del modello originale. In questo modo si prevengono corruzioni silenziose, incompatibilità tra versioni o scritture incomplete del file. Confronti le previsioni con np.array_equal sullo stesso input.
import joblib
import numpy as np
from sklearn.datasets import load_iris
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
X, y = load_iris(return_X_y=True)
pipe = Pipeline([('sc', StandardScaler()), ('lr', LogisticRegression())]).fit(X, y)
original_preds = pipe.predict(X)
joblib.dump(pipe, '/tmp/verify_pipe.joblib')
loaded = joblib.load('/tmp/verify_pipe.joblib')
loaded_preds = loaded.predict(X)
if np.array_equal(original_preds, loaded_preds):
print('Round-trip PASSED: predictions are identical.')
else:
diff = (original_preds != loaded_preds).sum()
print(f'Round-trip FAILED: {diff} different predictions!')Blocco della versione e metadati
Un modello serializzato con scikit-learn 1.2 potrebbe non essere caricato correttamente in scikit-learn 1.5 a causa di modifiche interne. Salvi sempre un file di metadati insieme al modello, indicando: versione di sklearn, versione di Python, data di addestramento, versione del dataset e metriche principali. Questa è la model card del modello, il documento di governance che spiega che cos'è il modello e come è stato prodotto.
import json
import sklearn
import sys
from datetime import datetime
metadata = {
'model_file': 'cancer_model.joblib',
'sklearn_version': sklearn.__version__,
'python_version': sys.version.split()[0],
'training_date': datetime.utcnow().isoformat(),
'dataset': 'breast_cancer',
'test_accuracy': 0.9789,
'features': 30,
'algorithm': 'LogisticRegression'
}
with open('/tmp/cancer_model_metadata.json', 'w') as f:
json.dump(metadata, f, indent=2)
print(json.dumps(metadata, indent=2))Sicurezza: non carichi mai file pickle non attendibili
Avviso di sicurezza fondamentale: sia pickle sia joblib possono eseguire codice Python arbitrario durante il caricamento. Non carichi mai un file di modello proveniente da una fonte non attendibile: potrebbe trattarsi di un payload dannoso camuffato da modello. Per i modelli condivisi tra organizzazioni, valuti formati più sicuri: ONNX (Open Neural Network Exchange) è un formato standardizzato e ispezionabile, supportato dalla maggior parte dei framework.
Convenzioni per i nomi dei file
Le buone convenzioni di denominazione incorporano nel nome del file le informazioni principali: algoritmo, dataset, data e metrica. In questo modo il registro dei modelli è autoesplicativo e si evita di caricare accidentalmente in produzione la versione errata del modello.
from datetime import date
from sklearn.metrics import accuracy_score
import joblib
# Example naming convention
dataset = 'breast_cancer'
algorithm = 'logreg'
test_acc = 0.9789
today = date.today().strftime('%Y%m%d')
filename = f'{dataset}_{algorithm}_{today}_acc{int(test_acc*100)}.joblib'
print('Model filename:', filename)
# e.g.: breast_cancer_logreg_20260620_acc97.joblib
# Load the model we saved earlier (demo)
model = joblib.load('/tmp/cancer_model.joblib')
print('Loaded OK')Verifica rapida
Verifichi la comprensione della serializzazione dei modelli con joblib e pickle trattata in questa lezione.
Riepilogo della lezione
In questa lezione ha imparato che: joblib.dump e joblib.load serializzano e ripristinano in modo efficiente i modelli sklearn addestrati; pickle funziona, ma joblib è preferibile per i modelli con grandi array NumPy grazie al memory mapping; inoltre, è necessario salvare sempre un file di metadati insieme al modello, indicando le versioni delle librerie, la data di addestramento e le metriche principali per la governance. Prossimamente progetteremo una convenzione per i nomi delle versioni e un sidecar di metadati per tenere traccia di più versioni del modello in un registro dei modelli.
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 «Salvare i modelli con joblib e pickle» è gratuita?
Sì — il testo completo di «Salvare i modelli con joblib e pickle» è 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 «Salvare i modelli con joblib e pickle»?
Imparerete a serializzare una pipeline addestrata con joblib e pickle, ricaricarla e verificare che le previsioni siano identiche, confermando la corretta serializzazione e deserializzazione. 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 1 di 4.
Quanto tempo richiede la lezione «Salvare i modelli con joblib e pickle»?
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
- Salvare i modelli con joblib e pickle
- Versionare i modelli: perché nomi dei file e metadati sono importanti
- Servire previsioni con un endpoint FastAPI
- Monitorare le previsioni: registrare input e output