Coding for ML

Writing ML Code Someone Else Can Run

Writing modular, reproducible machine learning code bases with configuration management, clean functions, and unit test coverage.

🟡 intermediate5 min readcodingpractical
Writing Testable ML Code ensures that machine learning code bases can be reproduced, maintained, and audited by teammates. Jupyter notebooks are great for quick exploratory analysis but suffer from out of order cell execution and global state pollution. Production ML code modularizes pipelines into pure functions, manages parameters using YAML configuration files, sets deterministic random seeds, and writes unit tests.

Moving Beyond Jupyter Notebooks

Jupyter notebooks are useful for early data exploration and quick plotting.

However, deploying raw Jupyter notebooks into production creates serious engineering problems:

Messy Notebook:   Global state pollution ──► Hardcoded paths ──► Cannot be unit tested!
Modular Codebase: Pure Python functions ──► External YAML configs ──► Automated pytest suite!

4 Principles of Production ML Code

┌──────────────────────────┬──────────────────────────┬──────────────────────────┬──────────────────────────┐
│ 1. MODULARIZATION        │ 2. CONFIG MANAGEMENT     │ 3. PURE FUNCTIONS        │ 4. DETERMINISTIC SEEDS   │
├──────────────────────────┼──────────────────────────┼──────────────────────────┼──────────────────────────┤
│ Refactor notebooks into  │ Store paths, learning    │ Write functions that     │ Set fixed random seeds   │
│ modular Python packages  │ rates, and parameters    │ depend exclusively on    │ for Python, NumPy, and   │
│ (src/data, src/models).  │ in YAML or Hydra files.  │ explicit arguments.      │ PyTorch.                 │
└──────────────────────────┴──────────────────────────┴──────────────────────────┘

1. Modular Directory Structure

Structure your codebase like a professional Python software package:

my_ml_project/
  ├── configs/
  │   └── train_config.yaml
  ├── src/
  │   ├── data/
  │   │   └── make_dataset.py
  │   ├── features/
  │   │   └── build_features.py
  │   └── models/
  │       └── train_model.py
  ├── tests/
  │   └── test_features.py
  └── requirements.txt

2. Parameter Configuration Management

Never hardcode file paths or hyperparameters inside Python scripts:

# train_config.yaml
data:
  raw_path: "data/raw/housing.csv"
  processed_path: "data/processed/housing_features.parquet"
model:
  learning_rate: 0.001
  batch_size: 64
  random_seed: 42

Parse configuration files cleanly using PyYAML or Hydra.

3. Pure Functions and Unit Testing

Write pure, single-purpose functions that take inputs and return outputs without mutating global variables:

# src/features/build_features.py
def scale_income_feature(df, max_income=100000.0):
  """Scales income column linearly to [0, 1] range."""
  return (df['income'] / max_income).clip(0.0, 1.0)


# tests/test_features.py
def test_scale_income_feature():
  df = pd.DataFrame({'income': [50000.0, 150000.0, -10.0]})
  result = scale_income_feature(df, max_income=100000.0)
  assert result.tolist() == [0.5, 1.0, 0.0]

Say this out loud

Writing testable machine learning code requires moving beyond Jupyter notebooks into modular Python packages. Extracting hyperparameters into external YAML config files separates configuration from execution code. Writing pure functions with explicit inputs and outputs enables automated unit testing with pytest and guarantees code reproducibility.

Followups to expect

  1. What is Cookiecutter Data Science? A popular standardized project directory structure template for organizing machine learning data science codebases.
  2. What is Type Hinting in Python ML code? Adding static type annotations (def predict(X: np.ndarray) -> np.ndarray:) to function signatures, catching type errors early using static type checkers like mypy.

Check yourself

Question 1 of 3

Why are raw Jupyter notebooks unsuitable as production machine learning codebase deployments?

More in Coding for ML

See all →
Implement Linear Regression from Scratch5 minImplement Self-Attention from Scratch5 minNumPy Broadcasting & Vectorization5 min