A trained model living only in a notebook's memory is useless the moment that session ends — serialization saves a trained model to disk so it can be reloaded and reused without retraining.
import joblib
joblib.dump(model, "model.joblib") # save a trained model (and pipelines) to disk
loaded_model = joblib.load("model.joblib") # load it back later, in a new session
predictions = loaded_model.predict(new_data) # use it immediately, no retraining needed
# Saving the pipeline (preprocessing + model together) is usually the right choice:
joblib.dump(pipeline, "full_pipeline.joblib")
# Standard library alternative (works for any Python object, not just scikit-learn):
import pickle
with open("model.pkl", "wb") as f:
pickle.dump(model, f)
with open("model.pkl", "rb") as f:
loaded_model = pickle.load(f)
joblib is the standard tool for saving scikit-learn models specifically — it's more efficient than the general-purpose pickle module for objects containing large NumPy arrays (which most trained models do), though pickle works as a general fallback for any Python object.
Crucially, saving the entire pipeline (preprocessing steps plus the model, from the earlier lesson) rather than just the bare model ensures the exact same preprocessing is automatically applied to new data at prediction time — saving only the model and reimplementing scaling/encoding separately elsewhere is a common, subtle source of production bugs, since it's easy for the reimplemented preprocessing to drift out of sync with what the model was actually trained on.
A serialized model file is never guaranteed to be portable across wildly different library versions — the scikit-learn (and Python) version used to save a model should ideally match the version used to load it, since internal object formats can change between releases; pinning dependency versions (via requirements.txt, covered in the core Python notebook) in both training and deployment environments avoids this entire class of problem.