Plot Cv PredictΒΆ
==================================== Plotting Cross-Validated PredictionsΒΆ
This example shows how to use
- func:
~sklearn.model_selection.cross_val_predicttogether with- class:
~sklearn.metrics.PredictionErrorDisplayto visualize prediction errors.
Imports for Cross-Validated Prediction DiagnosticsΒΆ
cross_val_predict for out-of-fold predictions: Unlike cross_val_score which returns per-fold metric values, cross_val_predict returns a prediction for every sample in the dataset by concatenating the test-fold predictions across all CV iterations. With cv=10, the dataset is split 10 ways, a LinearRegression model is trained on 9 folds each time, and the held-out fold receives predictions β so every sample gets exactly one out-of-fold prediction. This produces an array the same size as y that can be used to create global diagnostic plots like actual-vs-predicted or residual plots via PredictionErrorDisplay.from_predictions.
Interpreting prediction error displays: The actual-vs-predicted plot reveals systematic bias (points consistently above or below the diagonal indicate over- or under-prediction), while the residual-vs-predicted plot exposes heteroscedasticity (fan-shaped residuals suggest the modelβs error variance depends on the predicted value). However, it is important to note that computing a single aggregate metric from cross_val_predict outputs can be misleading when fold sizes or distributions vary β cross_val_score or cross_validate should be preferred for rigorous performance estimation, as they report per-fold metrics that capture variability.
# Authors: The scikit-learn developers
# SPDX-License-Identifier: BSD-3-Clause
# %%
# We will load the diabetes dataset and create an instance of a linear
# regression model.
from sklearn.datasets import load_diabetes
from sklearn.linear_model import LinearRegression
X, y = load_diabetes(return_X_y=True)
lr = LinearRegression()
# %%
# :func:`~sklearn.model_selection.cross_val_predict` returns an array of the
# same size of `y` where each entry is a prediction obtained by cross
# validation.
from sklearn.model_selection import cross_val_predict
y_pred = cross_val_predict(lr, X, y, cv=10)
# %%
# Since `cv=10`, it means that we trained 10 models and each model was
# used to predict on one of the 10 folds. We can now use the
# :class:`~sklearn.metrics.PredictionErrorDisplay` to visualize the
# prediction errors.
#
# On the left axis, we plot the observed values :math:`y` vs. the predicted
# values :math:`\hat{y}` given by the models. On the right axis, we plot the
# residuals (i.e. the difference between the observed values and the predicted
# values) vs. the predicted values.
import matplotlib.pyplot as plt
from sklearn.metrics import PredictionErrorDisplay
fig, axs = plt.subplots(ncols=2, figsize=(8, 4))
PredictionErrorDisplay.from_predictions(
y,
y_pred=y_pred,
kind="actual_vs_predicted",
subsample=100,
ax=axs[0],
random_state=0,
)
axs[0].set_title("Actual vs. Predicted values")
PredictionErrorDisplay.from_predictions(
y,
y_pred=y_pred,
kind="residual_vs_predicted",
subsample=100,
ax=axs[1],
random_state=0,
)
axs[1].set_title("Residuals vs. Predicted Values")
fig.suptitle("Plotting cross-validated predictions")
plt.tight_layout()
plt.show()
# %%
# It is important to note that we used
# :func:`~sklearn.model_selection.cross_val_predict` for visualization
# purpose only in this example.
#
# It would be problematic to
# quantitatively assess the model performance by computing a single
# performance metric from the concatenated predictions returned by
# :func:`~sklearn.model_selection.cross_val_predict`
# when the different CV folds vary by size and distributions.
#
# It is recommended to compute per-fold performance metrics using:
# :func:`~sklearn.model_selection.cross_val_score` or
# :func:`~sklearn.model_selection.cross_validate` instead.