CLAUDE LABJP
PRICING — September 1 was the scheduled date for the Sonnet 5 price increase, and it did not happen. The introductory $2/$10 per MTok now stands as the regular pricePARTNER — Salesforce and Anthropic announced Claudeforce, an expanded partnership. The Salesforce in Claude plugin ships with 37 prebuilt sales skills, from meeting prep to pipeline managementTRUST — Claudeforce serves Claude through Amazon Bedrock inside the Salesforce Trust Boundary, so data and inference never leave the security perimeter — an answer aimed squarely at regulated industriesBETA — Salesforce in Claude is with select pilot customers for now, with an open beta expected during SeptemberLIMITS — The 50% weekly-limit boost runs through September 13. From September 14 the permanent level is 25% above the pre-promotion baseline, roughly a 17% cut from todayRELEASE — Claude Code has shipped nothing since v2.1.251 on August 28. Against a pace of one release every 0.8 days, a four-day gap is among the longest yetPRICING — September 1 was the scheduled date for the Sonnet 5 price increase, and it did not happen. The introductory $2/$10 per MTok now stands as the regular pricePARTNER — Salesforce and Anthropic announced Claudeforce, an expanded partnership. The Salesforce in Claude plugin ships with 37 prebuilt sales skills, from meeting prep to pipeline managementTRUST — Claudeforce serves Claude through Amazon Bedrock inside the Salesforce Trust Boundary, so data and inference never leave the security perimeter — an answer aimed squarely at regulated industriesBETA — Salesforce in Claude is with select pilot customers for now, with an open beta expected during SeptemberLIMITS — The 50% weekly-limit boost runs through September 13. From September 14 the permanent level is 25% above the pre-promotion baseline, roughly a 17% cut from todayRELEASE — Claude Code has shipped nothing since v2.1.251 on August 28. Against a pace of one release every 0.8 days, a four-day gap is among the longest yet
Articles/Claude Code
Claude Code/2026-05-03Advanced

Claude Code for Data Science — pandas, scikit-learn, and ML Workflows with AI Pair Programming

A hands-on guide to using Claude Code across the full data science and machine learning workflow. From EDA and feature engineering to model evaluation, hyperparameter tuning with Optuna, SHAP analysis, and MLOps basics — with working Python code throughout.

claude-code131data-sciencemachine-learningpython22pandas2scikit-learnmlops

Premium Article

Most data scientists I know use Claude Code for quick scripts and code completions. Far fewer have tried letting it drive the full pipeline — from raw data through EDA, feature engineering, model training, hyperparameter tuning, and into MLOps tooling.

I was in the first camp for a while. My data analysis lived in Jupyter notebooks, edited by hand, with Claude Code used occasionally for specific snippets. It took actually committing to the full workflow to realize how well-suited data science is for AI pair programming.

The reason is structural. Data science is fundamentally a loop: hypothesis → code → observe → revise. Claude Code excels at compressing that loop. The faster you can move from "I wonder if this feature helps" to "here's the validation curve showing it does," the better your work gets.

This article walks through the patterns that work in practice, with complete working code for each phase.

1. Project Setup: Using CLAUDE.md to Encode Data Science Constraints

Before writing a single line of analysis code, invest a few minutes in a CLAUDE.md that tells Claude Code how this project works. The payoff is substantial: Claude will automatically apply constraints you'd otherwise have to re-state in every prompt.

Installing the Stack

# Prompt to Claude Code:
"Create a requirements.txt for a data science project and install it
in a virtual environment. We need: pandas, numpy, scikit-learn,
matplotlib, seaborn, jupyterlab, optuna, shap, joblib"

Generated requirements.txt:

pandas==2.2.0
numpy==1.26.3
scikit-learn==1.4.0
matplotlib==3.8.2
seaborn==0.13.1
jupyterlab==4.1.0
optuna==3.5.0
shap==0.44.0
joblib==1.3.2
python -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -r requirements.txt

The CLAUDE.md That Changes Everything

The constraints below aren't obvious to Claude Code without being told. Once they're in CLAUDE.md, you stop having to re-state them:

# Data Science Project Guidelines
 
## Stack
- Python 3.12, pandas 2.2, scikit-learn 1.4, matplotlib/seaborn
- Data: data/raw/ (source), data/processed/ (transformed)
- Models: models/ (pkl via joblib)
 
## Rules — Always Apply
- Always .copy() DataFrames before mutation
- Use RANDOM_STATE = 42 everywhere, consistently
- Split data BEFORE fitting any preprocessor (prevents data leakage)
- Save models with joblib.dump, load with joblib.load
- For datasets >500k rows, use chunked reading

With this in place, Claude Code will include .copy() on every DataFrame operation, set seeds across every library, and structure preprocessing to avoid leakage — without being asked each time.

2. EDA: Getting Claude Code to Do the Boring Parts

Exploratory data analysis is where projects start, and where a lot of time gets lost to boilerplate. The goal here is to get to insights fast, not to hand-write histogram loops.

A Complete EDA Report Generator

# Prompt to Claude Code:
# "Write src/eda_report.py that performs basic EDA on data/raw/sales.csv:
# - dtypes, missing values, summary statistics for numeric columns
# - histograms and boxplots for numeric features
# - value counts (top 10) for categorical columns
# - correlation heatmap
# Save all figures to reports/eda/ as PNG files."

Generated script:

# src/eda_report.py
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from pathlib import Path
 
RANDOM_STATE = 42
REPORTS_DIR = Path("reports/eda")
REPORTS_DIR.mkdir(parents=True, exist_ok=True)
 
def generate_eda_report(filepath: str) -> dict:
    """Run EDA and save figures. Returns summary dict."""
    df = pd.read_csv(filepath)
    report = {}
 
    report["shape"] = df.shape
    report["missing_pct"] = (df.isnull().sum() / len(df) * 100).to_dict()
 
    numeric_cols = df.select_dtypes(include=np.number).columns.tolist()
    report["stats"] = df[numeric_cols].describe().to_dict()
 
    # Correlation heatmap
    if len(numeric_cols) > 1:
        fig, ax = plt.subplots(figsize=(12, 10))
        sns.heatmap(
            df[numeric_cols].corr(),
            annot=True, fmt=".2f",
            cmap="coolwarm", center=0, ax=ax
        )
        ax.set_title("Feature Correlation Matrix")
        fig.savefig(REPORTS_DIR / "correlation_heatmap.png",
                    dpi=150, bbox_inches="tight")
        plt.close(fig)
        print("[OK] Correlation heatmap saved.")
 
    # Histograms
    n_cols = 3
    n_rows = (len(numeric_cols) + n_cols - 1) // n_cols
    fig, axes = plt.subplots(n_rows, n_cols, figsize=(15, 5 * n_rows))
    axes = axes.flatten()
 
    for i, col in enumerate(numeric_cols):
        axes[i].hist(df[col].dropna(), bins=30, edgecolor="black", alpha=0.7)
        axes[i].set_title(
            f"{col} (missing: {report['missing_pct'][col]:.1f}%)"
        )
        axes[i].set_xlabel(col)
        axes[i].set_ylabel("Count")
 
    for j in range(i + 1, len(axes)):
        axes[j].set_visible(False)
 
    plt.tight_layout()
    fig.savefig(REPORTS_DIR / "histograms.png", dpi=150, bbox_inches="tight")
    plt.close(fig)
    print(f"[OK] Histograms saved ({len(numeric_cols)} features)")
 
    return report
 
if __name__ == "__main__":
    report = generate_eda_report("data/raw/sales.csv")
    print(f"\nShape: {report['shape']}")
    print("\nMissing values (%):")
    for col, pct in report["missing_pct"].items():
        if pct > 0:
            print(f"  {col}: {pct:.1f}%")

Outlier Detection: Comparing Three Strategies

Rather than picking an outlier strategy upfront, generate a comparison script that shows all three options side by side:

# src/outlier_handling.py
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pathlib import Path
 
def detect_outliers_iqr(series: pd.Series, multiplier: float = 1.5) -> pd.Series:
    """Return Boolean mask of IQR-based outliers."""
    Q1, Q3 = series.quantile(0.25), series.quantile(0.75)
    IQR = Q3 - Q1
    return (series < Q1 - multiplier * IQR) | (series > Q3 + multiplier * IQR)
 
def compare_outlier_strategies(
    df: pd.DataFrame, col: str, output_dir: str = "reports/eda"
) -> dict:
    """Compare drop / clip / log-transform and save a side-by-side plot."""
    Path(output_dir).mkdir(parents=True, exist_ok=True)
    mask = detect_outliers_iqr(df[col])
    print(f"Outliers detected: {mask.sum()} / {len(df)} "
          f"({mask.sum()/len(df)*100:.1f}%)")
 
    Q1, Q3 = df[col].quantile(0.25), df[col].quantile(0.75)
    IQR = Q3 - Q1
    lower, upper = Q1 - 1.5 * IQR, Q3 + 1.5 * IQR
 
    df_drop = df[~mask].copy()
    df_clip = df.copy()
    df_clip[col] = df_clip[col].clip(lower=lower, upper=upper)
    df_log = None
    if df[col].min() > 0:
        df_log = df.copy()
        df_log[f"{col}_log"] = np.log1p(df_log[col])
 
    fig, axes = plt.subplots(1, 3, figsize=(18, 5))
    axes[0].hist(df_drop[col], bins=30, alpha=0.7, color="steelblue")
    axes[0].set_title(f"① Drop (n={len(df_drop)})")
    axes[1].hist(df_clip[col], bins=30, alpha=0.7, color="orange")
    axes[1].set_title(f"② Clip [{lower:.1f}, {upper:.1f}]")
    if df_log is not None:
        axes[2].hist(df_log[f"{col}_log"], bins=30, alpha=0.7, color="green")
        axes[2].set_title("③ Log Transform (log1p)")
    else:
        axes[2].text(0.5, 0.5, "Log transform unavailable\n(non-positive values)",
                     ha="center", va="center", transform=axes[2].transAxes)
    plt.suptitle(f"Outlier Strategy Comparison: '{col}'", fontsize=14)
    plt.tight_layout()
    fig.savefig(f"{output_dir}/outlier_comparison_{col}.png",
                dpi=150, bbox_inches="tight")
    plt.close(fig)
 
    return {"drop_n": len(df_drop), "lower": lower, "upper": upper}

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
A reproducible layout that turns an exploratory notebook into six tested modules in ~25 minutes
Wiring data-leakage detection into CLAUDE.md — a real case that caught leakage in 3 of 11 features
A full production workflow: Optuna 100 trials (RMSE 0.0421->0.0388), pytest, and a single run script
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $15 for lifetime access
View Membership →

Related Articles

Claude Code2026-04-25
Claude Code × uv: Blazing-Fast Python Environment Setup — 10x Faster Than pip in Practice
Learn how to combine uv — Astral's Rust-powered Python package manager — with Claude Code for dramatically faster environment setup. Covers project initialization, dependency management automation, CI integration, and migrating from pip.
Claude Code2026-04-21
Claude Code × Python Hybrid Development Patterns: A Production Guide to 50% Token Reduction
Seven production-tested patterns for hybrid Claude Code × Python workflows, each with working code and real-world token reduction data.
Claude Code2026-08-28
A small script that catches invisible characters in plugin names before you install
Control characters and zero-width characters hiding in plugin or skill names are invisible in a terminal listing. I built six deliberately confusing names, compared what ls actually shows, and wrote a short check you can run before installing anything — plus an honest note on what that check misses.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →