Setting Up the Python ML Environment
ML work is iterative and exploratory, so the environment matters more than for most Python: you want isolated dependencies, fast interactive execution, and a package set that is current but pinned. The standard setup is a virtual environment, a handful of core packages, and Jupyter as the working surface - all of it reproducible from a requirements file.
The Virtual Environment
python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
python --version # confirm the venv interpreter is active
A virtual environment keeps the project's packages out of the system Python and out of other projects. Create one per project, record its Python version, and recreate it from the requirements file on any machine - that is the whole portability story.
The Core Package Set
pip install numpy pandas scikit-learn matplotlib seaborn jupyter
- numpy - arrays and numerical operations; the substrate.
- pandas - DataFrames for loading, cleaning, and feature work.
- scikit-learn - models, preprocessing, model selection, metrics.
- matplotlib - plotting (the visualization tutorial covers it in depth).
- seaborn - statistical plot styles on top of matplotlib, for fast EDA.
- jupyter - the notebook interface; jupyterlab is the modern variant.
Install extras only when a problem needs them: imbalanced-learn (SMOTE), statsmodels (statistical inference), xgboost/lightgbm (gradient boosting), shap (explanations). Keep the base lean; each dependency is a version to maintain.
Pinning with a Requirements File
pip freeze > requirements.txt # everything, exact versions
cat requirements.txt
# or pin only the direct dependencies, loosely:
cat > requirements.txt <<'EOF'
numpy>=1.26
pandas>=2.1
scikit-learn>=1.4
matplotlib>=3.8
EOF
Two conventions: loose lower bounds (>=) for application projects that want security updates, and exact pins (pip freeze) for research where reproducibility of a result matters more than freshness. Whichever you choose, the file goes in version control and is the only way a fresh machine reproduces the environment.
Jupyter as the Working Surface
jupyter lab --no-browser
- Start Jupyter with the venv activated - the kernel inherits the venv's packages.
- Keep exploration in notebooks and production code in modules: a notebook that does everything is hard to test and hard to rerun.
- Name kernels explicitly when multiple Python environments exist, so a notebook never runs against the wrong pandas.
A Ten-Second Sanity Check
import numpy, pandas, sklearn, matplotlib
print(numpy.__version__, pandas.__version__,
sklearn.__version__, matplotlib.__version__)
from sklearn.datasets import make_classification
X, y = make_classification(n_samples=100, random_state=0)
print("dataset ok:", X.shape, y.shape)
If the imports print versions and the synthetic dataset builds, the stack works end to end: environment, packages, and the scikit-learn API. Run this once per environment before starting real work - it catches the wrong-interpreter and missing-backend problems in seconds.
Summary
Build the environment as: a virtualenv per project, the core stack (numpy, pandas, scikit-learn, matplotlib, seaborn, jupyter), extras only when needed, a committed requirements file with a consistent pinning policy, and Jupyter started from inside the activated venv. The sanity check confirms the whole stack in ten seconds, and the requirements file is what makes the setup reproducible on the next machine.