Scikit-Learn: ModuleNotFoundError: No module named sklearn.cross_validation
This error occurs when Python tries to import from the deprecated sklearn.cross_validation submodule, which was removed in Scikit-Learn 0.20+. Import train_test_split, KFold, and cross_val_score from sklearn.model_selection instead.
Root Cause Analysis
This error occurs when Python machine learning scripts, legacy tutorials, or outdated GitHub repositories attempt to execute from sklearn.cross_validation import train_test_split or from sklearn.cross_validation import KFold in modern Scikit-Learn environments (v0.20+ through v1.5+).
Root Cause 1: Deprecation and Removal of sklearn.cross_validation
In Scikit-Learn release 0.18, model evaluation routines were restructured into a unified subpackage called sklearn.model_selection. The legacy sklearn.cross_validation, sklearn.grid_search, and sklearn.learning_curve modules were marked as deprecated and subsequently deleted in Scikit-Learn 0.20. Attempting to import from sklearn.cross_validation in any modern Scikit-Learn release fails with ModuleNotFoundError: No module named 'sklearn.cross_validation'.
Root Cause 2: Copying Pre-2018 Machine Learning Code and Books
Many classical machine learning textbooks, introductory online tutorials, and Kaggle kernels written prior to 2018 hardcode import sklearn.cross_validation. Running these snippets in modern Python 3.10+ environments triggers an immediate import failure.
Root Cause 3: Grid Search Module Consolidation
Similarly, classes like GridSearchCV and RandomizedSearchCV previously resided in sklearn.grid_search and were moved into sklearn.model_selection.
Root Cause 4: Outdated Pinned Dependencies in Legacy Packages
Third-party AutoML or feature selection packages authored years ago may attempt to load the old submodule during package initialization.
Reproduction Code (MCVE)
# Simulating import of obsolete sklearn.cross_validation module removed in Scikit-Learn 0.20+
class MockSklearnModule:
"""Simulates modern Scikit-Learn package namespace."""
__name__ = "sklearn"
sklearn_pkg = MockSklearnModule()
# Attempting to access removed cross_validation submodule triggers ModuleNotFoundError
if not hasattr(sklearn_pkg, "cross_validation"):
raise ModuleNotFoundError("No module named 'sklearn.cross_validation'")
Solution 1: Import from sklearn.model_selection
Replace all imports from sklearn.cross_validation with the official sklearn.model_selection module.
from sklearn.model_selection import train_test_split, KFold, cross_val_score
import numpy as np
# Sample dataset
X = np.arange(20).reshape(10, 2)
y = np.array([0, 1] * 5)
# Modern train_test_split from sklearn.model_selection
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
print("X_train shape:", X_train.shape)
print("X_test shape:", X_test.shape)
assert len(X_train) == 8
assert len(X_test) == 2
Solution 2: Migrate GridSearchCV from sklearn.grid_search to model_selection
Import hyperparameter search utilities directly from sklearn.model_selection.
from sklearn.model_selection import GridSearchCV
from sklearn.tree import DecisionTreeClassifier
# Modern GridSearchCV instantiation
param_grid = {"max_depth": [2, 4, 6]}
grid_search = GridSearchCV(DecisionTreeClassifier(), param_grid, cv=3)
print("GridSearchCV configured successfully:", grid_search.__class__.__name__)
assert grid_search.cv == 3
Whenever you copy code from a tutorial that contains from sklearn.cross_validation import ... or from sklearn.grid_search import ..., perform a global find-and-replace to change the import source to from sklearn.model_selection import .... The function signatures and parameter names (such as test_size, random_state, stratify) remain identical.
Contrast sklearn.cross_validation with sklearn.model_selection: cross_validation is the legacy name from Scikit-Learn <= 0.19; model_selection is the standard modern package in Scikit-Learn 0.20+ through 1.5+.