Skip to main content
skill CX Codex

Model Hyperparameter Tuning — Claude Code skill: tune model params

A skill for tuning model hyperparameters: grid search, random search, Bayesian optimization with Optuna. Useful once baseline settings stop improving.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add aj-geddes/useful-ai-prompts --skill model-hyperparameter-tuning -a claude-code
Open on GitHub

What Model Hyperparameter Tuning does

The skill walks through a systematic search for the best combination of model configuration parameters, scored on validation data. It covers the methods: exhaustive grid search, random sampling from the parameter space, Bayesian optimization, Hyperband, evolutionary algorithms and population-based training.

Hyperparameters are broken down by model type. Tree models get max_depth, min_samples_split and learning_rate; neural networks get learning_rate, batch_size, num_layers and dropout; SVM gets C, kernel and gamma. The Python examples lean on scikit-learn (GridSearchCV, RandomizedSearchCV), optuna with TPESampler, and torch with the Adam optimizer. So set up the environment first — the examples won't run without those libraries.

It helps when you want to compare configurations under one method instead of hand-picking values. One caveat: grid search grows with every parameter you add, so on a wide space it burns through your time budget fast. Random search or Optuna is the better call there.

What it helps with

  • compare model configurations under one method
  • pick learning rate and dropout for a neural net
  • find the optimum for gradient boosting without manual sweeps
  • decide between grid search and Bayesian optimization
  • measure how parameters move the validation metric

Example prompts for the agent

  • Tune RandomForest hyperparameters with GridSearchCV on accuracy
  • Set up an Optuna study with TPESampler to find the best model params
  • Compare learning rates for a torch network and show which one drops loss faster

How to install Model Hyperparameter Tuning

1Skills CLI (Vercel)

npx skills add aj-geddes/useful-ai-prompts --skill model-hyperparameter-tuning -a claude-code

2Manually: put the files in place

~/.claude/skills/model-hyperparameter-tuning/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/model-hyperparameter-tuning/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about Model Hyperparameter Tuning

How do I install Model Hyperparameter Tuning in Claude?

Run npx skills add aj-geddes/useful-ai-prompts --skill model-hyperparameter-tuning -a claude-code. The skill lands at ~/.claude/skills/model-hyperparameter-tuning/SKILL.md.

What does Model Hyperparameter Tuning do?

It lays out hyperparameter search methods — grid search, random search, Bayesian optimization — with Python examples for tree models, neural networks and SVM.

What do the skill's examples need to run?

The scikit-learn, optuna and torch libraries, since the code samples are built on them. Without those, the examples won't run.

Source text

SKILL.md · MIT
---
name: Model Hyperparameter Tuning
description: Optimize hyperparameters using grid search, random search, Bayesian optimization, and automated ML frameworks like Optuna and Hyperopt
---

# Model Hyperparameter Tuning

## Overview

Hyperparameter tuning is the process of systematically searching for the best combination of model configuration parameters to maximize performance on validation data.

## When to Use

- When optimizing model performance beyond baseline configurations
- When comparing different parameter combinations systematically
- When fine-tuning complex models with many hyperparameters
- When seeking the best trade-off between bias, variance, and training time
- When improving model generalization on validation and test data
- When exploring parameter spaces for neural networks, tree models, or ensemble methods

## Tuning Methods

- **Grid Search**: Exhaustive search over parameter grid
- **Random Search**: Random sampling from parameter space
- **Bayesian Optimization**: Probabilistic model-based search
- **Hyperband**: Multi-fidelity optimization
- **Evolutionary Algorithms**: Genetic algorithm based search
- **Population-based Training**: Distributed parameter optimization

## Hyperparameters by Model Type

- **Tree Models**: max_depth, min_samples_split, learning_rate
- **Neural Networks**: learning_rate, batch_size, num_layers, dropout
- **SVM**: C, kernel, gamma
- **Ensemble**: n_estimators, max_features, min_samples_leaf

## Python Implementation

```python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from sklearn.model_selection import GridSearchCV, RandomizedSearchCV
import optuna
from optuna.samplers import TPESampler
import torch
import torch.nn as nn
from torch.optim import Adam
import time

# Create dataset
X, y = make_classification(n_samples=2000, n_features=50, n_informative=30,
                          n_redundant=10, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

print("Dataset shapes:", X_train_scaled.shape, X_test_scaled.shape)

# 1. Grid Search
print("\n=== 1. Grid Search ===")
start = time.time()

param_grid = {
    'n_estimators': [50, 100, 200],
    'max_depth': [5, 10, 15],
    'min_samples_split': [2, 5, 10],
    'min_samples_leaf': [1, 2, 4]
}

grid_search = GridSearchCV(
    RandomForestClassifier(random_state=42),
    param_grid,
    cv=5,
    scoring='accuracy',
    n_jobs=-1,
    verbose=0
)

grid_search.fit(X_train_scaled, y_train)
grid_time = time.time() - start

print(f"Best parameters: {grid_search.best_params_}")
print(f"Best CV score: {grid_search.best_score_:.4f}")
print(f"Test score: {grid_search.score(X_test_scaled, y_test):.4f}")
print(f"Time taken: {grid_time:.2f}s")

# 2. Random Search
print("\n=== 2. Random Search ===")
start = time.time()

param_dist = {
    'n_estimators': np.arange(50, 300, 10),
    'max_depth': np.arange(5, 30, 1),
    'min_samples_split': np.arange(2, 20, 1),
    'min_samples_leaf': np.arange(1, 10, 1),
    'max_features': ['sqrt', 'log2']
}

random_search = RandomizedSearchCV(
    RandomForestClassifier(random_state=42),
    param_dist,
    n_iter=20,
    cv=5,
    scoring='accuracy',
    n_jobs=-1,
    random_state=42,
    verbose=0
)

random_search.fit(X_train_scaled, y_train)
random_time = time.time() - start

print(f"Best parameters: {random_search.best_params_}")
print(f"Best CV score: {random_search.best_score_:.4f}")
print(f"Test score: {random_search.score(X_test_scaled, y_test):.4f}")
print(f"Time taken: {random_time:.2f}s")

# 3. Bayesian Optimization with Optuna
print("\n=== 3. Bayesian Optimization (Optuna) ===")

def objective(trial):
    params = {
        'n_estimators': trial.suggest_int('n_estimators', 50, 300),
        'max_depth': trial.suggest_int('max_depth', 5, 30),
        'min_samples_split': trial.suggest_int('min_samples_split', 2, 20),
        'min_samples_leaf': trial.suggest_int('min_samples_leaf', 1, 10),
        'max_features': trial.suggest_categorical('max_features', ['sqrt', 'log2'])
    }

    model = RandomForestClassifier(**params, random_state=42)
    scores = cross_val_score(model, X_train_scaled, y_train, cv=5, scoring='accuracy')
    return scores.mean()

start = time.time()
sampler = TPESampler(seed=42)
study = optuna.create_study(sampler=sampler, direction='maximize')
study.optimize(objective, n_trials=20, show_progress_bar=False)
optuna_time = time.time() - start

best_trial = study.best_trial
print(f"Best parameters: {best_trial.params}")
print(f"Best CV score: {best_trial.value:.4f}")

# Train final model with best params
best_model = RandomForestClassifier(**best_trial.params, random_state=42)
best_model.fit(X_train_scaled, y_train)
print(f"Test score: {best_model.score(X_test_scaled, y_test):.4f}")
print(f"Time taken: {optuna_time:.2f}s")

# 4. Gradient Boosting hyperparameter tuning
print("\n=== 4. Gradient Boosting Tuning ===")

gb_param_grid = {
    'learning_rate': [0.01, 0.05, 0.1, 0.2],
    'n_estimators': [100, 200, 300],
    'max_depth': [3, 5, 7, 9],
    'min_samples_split': [2, 5, 10],
    'subsample': [0.8, 0.9, 1.0]
}

gb_search = GridSearchCV(
    GradientBoostingClassifier(random_state=42),
    gb_param_grid,
    cv=5,
    scoring='accuracy',
    n_jobs=-1,
    verbose=0
)

gb_search.fit(X_train_scaled, y_train)

print(f"Best parameters: {gb_search.best_params_}")
print(f"Best CV score: {gb_search.best_score_:.4f}")
print(f"Test score: {gb_search.score(X_test_scaled, y_test):.4f}")

# 5. Learning rate tuning for neural networks
print("\n=== 5. Learning Rate Tuning for Neural Networks ===")

class SimpleNN(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(50, 128)
        self.fc2 = nn.Linear(128, 64)
        self.fc3 = nn.Linear(64, 1)
        self.relu = nn.ReLU()
        self.dropout = nn.Dropout(0.3)

    def forward(self, x):
        x = self.relu(self.fc1(x))
        x = self.dropout(x)
        x = self.relu(self.fc2(x))
        x = self.dropout(x)
        x = torch.sigmoid(self.fc3(x))
        return x

learning_rates = [0.0001, 0.001, 0.01, 0.1]
lr_results = {}

device = torch.device('cpu')

for lr in learning_rates:
    model = SimpleNN().to(device)
    optimizer = Adam(model.parameters(), lr=lr)
    criterion = nn.BCELoss()

    X_train_tensor = torch.FloatTensor(X_train_scaled)
    y_train_tensor = torch.FloatTensor(y_train).unsqueeze(1)

    best_loss = float('inf')
    patience = 10
    patience_counter = 0

    for epoch in range(100):
        output = model(X_train_tensor)
        loss = criterion(output, y_train_tensor)

        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        if loss.item() < best_loss:
            best_loss = loss.item()
            patience_counter = 0
        else:
            patience_counter += 1

        if patience_counter >= patience:
            break

    lr_results[lr] = best_loss
    print(f"Learning Rate {lr}: Best Loss = {best_loss:.6f}")

# 6. Comparison visualization
fig, axes = plt.subplots(2, 2, figsize=(14, 10))

# Search method comparison
methods = ['Grid Search', 'Random Search', 'Bayesian Opt']
times = [grid_time, random_time, optuna_time]
scores = [grid_search.best_score_, random_search.best_score_, study.best_value]

x = np.arange(len(methods))
axes[0, 0].bar(x, times, color='steelblue', alpha=0.7)
axes[0, 0].set_ylabel('Time (seconds)')
axes[0, 0].set_title('Tuning Method Comparison - Time')
axes[0, 0].set_xticks(x)
axes[0, 0].set_xticklabels(methods)

axes[0, 1].bar(x, scores, color='coral', alpha=0.7)
axes[0, 1].set_ylabel('CV Accuracy')
axes[0, 1].set_title('Tuning Method Comparison - Accuracy')
axes[0, 1].set_xticks(x)
axes[0, 1].set_xticklabels(methods)
axes[0, 1].set_ylim([0.8, 1.0])

# Hyperparameter importance from Optuna
importance_dict = {}
for param_name in study.best_trial.params.keys():
    trial_values = []
    for trial in study.trials:
        if param_name in trial.params:
            trial_values.append(trial.value)
    if trial_values:
        importance_dict[param_name] = np.std(trial_values)

axes[1, 0].barh(list(importance_dict.keys()), list(importance_dict.values()),
               color='lightgreen', edgecolor='black')
axes[1, 0].set_xlabel('Importance (Std Dev)')
axes[1, 0].set_title('Hyperparameter Importance')

# Learning rate tuning for NN
axes[1, 1].plot(list(lr_results.keys()), list(lr_results.values()), marker='o',
               linewidth=2, markersize=8, color='purple')
axes[1, 1].set_xlabel('Learning Rate')
axes[1, 1].set_ylabel('Best Training Loss')
axes[1, 1].set_title('Learning Rate Impact on Neural Network')
axes[1, 1].set_xscale('log')
axes[1, 1].grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('hyperparameter_tuning.png', dpi=100, bbox_inches='tight')
print("\nVisualization saved as 'hyperparameter_tuning.png'")

print("\nHyperparameter tuning completed!")
```

## Tuning Strategy by Model

- **Tree Models**: Focus on depth, min_samples, max_features
- **Boosting**: Learning_rate, n_estimators, subsample
- **Neural Networks**: Learning rate, batch size, regularization
- **SVM**: C and kernel type are most important

## Best Practices

- Scale search space logarithmically for continuous parameters
- Use cross-validation for robust estimates
- Start with random search for initial exploration
- Use Bayesian optimization for final refinement
- Monitor for diminishing returns

## Deliverables

- Optimal hyperparameters found
- Performance metrics for top configurations
- Tuning efficiency analysis
- Visualization of parameter impact
- Tuning report and recommendations

© aj-geddes · MIT · aj-geddes/useful-ai-prompts

Similar skills

Everything for AI and ML →

From the same set118

stress-testing A skill for stress testing: push a system past normal capacity to find breaking points, check auto-scaling and recovery after overload. CX Codex +1 497installs application-logging A skill that walks your agent through structured logging: levels, context, request tracing and centralized aggregation. CX Codex +1 496installs changelog-maintenance A skill that gets your agent to write and maintain CHANGELOG.md in Keep a Changelog format, with Added, Changed, Fixed and Security sections. CX Codex +1 495installs grafana-dashboard Lets your agent write Grafana dashboards: panels, template variables, alerts and provisioning. Handy when you need monitoring up before the next deploy. CX Codex +1 494installs api-reference-documentation A skill that walks the agent through writing API reference docs: endpoints, auth, request and response examples, OpenAPI specs. CX Codex +1 494installs database-performance-debugging A skill that walks your agent through finding slow SQL queries and reading their execution plans. Useful when the app drags or the database burns CPU. CX Codex +1 493installs code-documentation A skill that makes the agent write documentation inside your code: JSDoc, Python docstrings, JavaDoc, inline comments and API notes. Useful when functions and classes need describing, not rewriting. CX Codex +1 492installs reactive-programming A skill for reactive streams in RxJS: observables, operators, backpressure. Useful when a project leans on async data and events. CX Codex +1 491installs

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor