Skip to content

Model Comparison Guide

This guide provides a comprehensive comparison of different modeling approaches available in the SPE9 Geomodeling Toolkit.

🎯 Overview

The toolkit supports multiple modeling paradigms for spatial interpolation:

  1. Traditional Gaussian Processes - Classical GP with various kernels
  2. Deep Gaussian Processes - Neural network enhanced GP models
  3. Kriging Methods - Classical geostatistical approaches
  4. Ensemble Methods - Random Forest and other tree-based models

πŸ“Š Performance Comparison

Based on SPE9 reservoir dataset analysis (24Γ—25Γ—15 grid, 9000 cells):

Model Type Kernel/Architecture RΒ² Score RMSE MAE Training Time Memory Usage
Traditional GP Combined (RBF+MatΓ©rn) 0.277 2.84 2.12 1.3s Low
Traditional GP RBF 0.241 2.91 2.18 1.4s Low
Traditional GP MatΓ©rn (Ξ½=1.5) 0.229 2.93 2.21 1.5s Low
Deep GP Small (32-16) 0.189 3.01 2.35 1.8s Medium
Deep GP Medium (64-32) 0.165 3.08 2.41 2.3s Medium
Deep GP Large (128-64-32) 0.142 3.15 2.48 3.1s High
Ordinary Kriging Spherical 0.198 2.98 2.28 0.8s Low
Random Forest 100 trees 0.156 3.12 2.44 0.6s Medium

Key Findings:

  • βœ… Traditional GP with combined kernels performs best for SPE9 spatial patterns
  • ⚑ Kriging is fastest but less accurate than GP methods
  • 🧠 Deep GP shows promise but requires more tuning for this dataset
  • 🌳 Random Forest is fast but struggles with spatial continuity

πŸ” Detailed Model Analysis

Traditional Gaussian Processes

RBF Kernel

model = toolkit.create_sklearn_model('gpr', kernel_type='rbf')

Characteristics:

  • Smoothness: Infinitely differentiable, very smooth interpolations
  • Best for: Continuous, smooth spatial phenomena
  • Limitations: May over-smooth sharp boundaries
  • Hyperparameters: Length scale, variance

When to use:

  • Permeability fields with gradual transitions
  • Temperature or pressure distributions
  • Smooth geological properties

MatΓ©rn Kernel

model = toolkit.create_sklearn_model('gpr', kernel_type='matern')

Characteristics:

  • Smoothness: Controlled by Ξ½ parameter (1.5, 2.5, ∞)
  • Best for: Moderately rough spatial patterns
  • Flexibility: More flexible than RBF for irregular patterns
  • Hyperparameters: Length scale, variance, smoothness (Ξ½)

When to use:

  • Geological formations with moderate roughness
  • Porosity distributions
  • Natural phenomena with some irregularity

Combined Kernel (RBF + MatΓ©rn)

model = toolkit.create_sklearn_model('gpr', kernel_type='combined')

Characteristics:

  • Multi-scale: Captures both smooth and rough patterns
  • Best performance: Highest RΒ² on SPE9 dataset
  • Complexity: More parameters to optimize
  • Robustness: Handles diverse spatial patterns

When to use:

  • Complex reservoir properties
  • Multi-scale spatial phenomena
  • When unsure about spatial structure

Deep Gaussian Processes

Small Architecture (32-16)

model = toolkit.create_gpytorch_model('deep', hidden_dims=[32, 16])

Characteristics:

  • Feature learning: Learns non-linear spatial features
  • Moderate complexity: Good balance of capacity and speed
  • Uncertainty: Maintains GP uncertainty quantification
  • Training: Requires more iterations than traditional GP

When to use:

  • Non-linear spatial relationships
  • Complex geological structures
  • When traditional kernels are insufficient

Medium Architecture (64-32)

model = toolkit.create_gpytorch_model('deep', hidden_dims=[64, 32])

Characteristics:

  • Higher capacity: Can model more complex patterns
  • Slower training: Requires more computational resources
  • Risk of overfitting: May overfit on small datasets
  • Better for large datasets: Shines with more training data

Large Architecture (128-64-32)

model = toolkit.create_gpytorch_model('deep', hidden_dims=[128, 64, 32])

Characteristics:

  • Maximum flexibility: Highest model capacity
  • Computational cost: Significant memory and time requirements
  • Data hungry: Needs large datasets to perform well
  • Research applications: Best for experimental work

Kriging Methods

Ordinary Kriging

from pykrige.ok import OrdinaryKriging
# Integrated through toolkit

Characteristics:

  • Classical approach: Well-established geostatistical method
  • Fast training: Analytical solution, no iterative optimization
  • Interpretable: Clear statistical interpretation
  • Limited flexibility: Fixed covariance models

When to use:

  • Quick baseline models
  • Well-understood spatial processes
  • When interpretability is crucial
  • Limited computational resources

πŸŽ›οΈ Hyperparameter Tuning

Traditional GP Tuning

# Grid search for kernel parameters
from sklearn.model_selection import GridSearchCV

param_grid = {
    'alpha': [1e-10, 1e-8, 1e-6],
    'kernel__length_scale': [0.1, 1.0, 10.0],
    'kernel__k1__length_scale': [0.1, 1.0, 10.0],  # For combined kernels
    'kernel__k2__length_scale': [0.1, 1.0, 10.0],
}

model = toolkit.create_sklearn_model('gpr', kernel_type='combined')
grid_search = GridSearchCV(model, param_grid, cv=5, scoring='r2')

Deep GP Tuning

# Optuna optimization for Deep GP
import optuna

def objective(trial):
    hidden_dim1 = trial.suggest_int('hidden_dim1', 16, 128)
    hidden_dim2 = trial.suggest_int('hidden_dim2', 8, 64)
    lr = trial.suggest_float('lr', 0.01, 0.3)

    model = toolkit.create_gpytorch_model(
        'deep',
        hidden_dims=[hidden_dim1, hidden_dim2]
    )
    # Training and evaluation code...
    return r2_score

study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=50)

πŸ“ˆ Performance Optimization

For Large Datasets (>10,000 points)

Sparse GP Approximations

# Use inducing points for scalability
model = toolkit.create_gpytorch_model(
    'sparse',
    inducing_points=500,  # Much smaller than dataset
    kernel_type='rbf'
)

Batch Processing

# Process data in batches
batch_size = 1000
for i in range(0, len(X_train), batch_size):
    X_batch = X_train[i:i+batch_size]
    y_batch = y_train[i:i+batch_size]
    # Process batch...

For Small Datasets (<1,000 points)

Data Augmentation

# Add synthetic training points
from sklearn.gaussian_process import GaussianProcessRegressor

# Train initial model
initial_model = GaussianProcessRegressor()
initial_model.fit(X_train, y_train)

# Generate synthetic points
X_synthetic = generate_synthetic_locations(n_points=500)
y_synthetic = initial_model.predict(X_synthetic)

# Combine with original data
X_augmented = np.vstack([X_train, X_synthetic])
y_augmented = np.hstack([y_train, y_synthetic])

Regularization

# Increase regularization for small datasets
model = toolkit.create_sklearn_model(
    'gpr',
    kernel_type='combined',
    alpha=1e-6  # Higher regularization
)

🎯 Model Selection Guidelines

Choose Traditional GP When

  • βœ… Dataset size: 100-10,000 points
  • βœ… Smooth spatial patterns expected
  • βœ… Fast training required
  • βœ… Interpretability important
  • βœ… Uncertainty quantification critical

Choose Deep GP When

  • βœ… Complex, non-linear spatial relationships
  • βœ… Large datasets (>5,000 points)
  • βœ… Traditional kernels insufficient
  • βœ… Research/experimental applications
  • βœ… Computational resources available

Choose Kriging When

  • βœ… Quick baseline needed
  • βœ… Classical geostatistical workflow
  • βœ… Limited computational resources
  • βœ… Well-understood spatial process
  • βœ… Interpretability paramount

Choose Random Forest When

  • βœ… Non-spatial features important
  • βœ… Categorical variables present
  • βœ… Fast predictions needed
  • βœ… Robustness to outliers required
  • βœ… Feature importance analysis desired

πŸ”¬ Experimental Results

Cross-Validation Analysis

from sklearn.model_selection import cross_val_score

# Compare models with cross-validation
models = {
    'GP_RBF': toolkit.create_sklearn_model('gpr', kernel_type='rbf'),
    'GP_Matern': toolkit.create_sklearn_model('gpr', kernel_type='matern'),
    'GP_Combined': toolkit.create_sklearn_model('gpr', kernel_type='combined'),
}

cv_results = {}
for name, model in models.items():
    scores = cross_val_score(model, X_train, y_train, cv=5, scoring='r2')
    cv_results[name] = {
        'mean': scores.mean(),
        'std': scores.std(),
        'scores': scores
    }
    print(f"{name}: RΒ² = {scores.mean():.3f} Β± {scores.std():.3f}")

Spatial Cross-Validation

# Account for spatial correlation in validation
from sklearn.model_selection import GroupKFold

# Create spatial groups (e.g., by grid blocks)
spatial_groups = create_spatial_groups(X_train, n_groups=5)

group_kfold = GroupKFold(n_splits=5)
spatial_cv_scores = cross_val_score(
    model, X_train, y_train,
    cv=group_kfold,
    groups=spatial_groups,
    scoring='r2'
)

πŸ“Š Visualization Comparison

Prediction Comparison

# Compare predictions from different models
fig, axes = plt.subplots(2, 3, figsize=(15, 10))

models = ['GP_RBF', 'GP_Matern', 'GP_Combined', 'Deep_GP', 'Kriging', 'RF']
for i, model_name in enumerate(models):
    predictions = toolkit.predict_full_grid(model_name)
    plot_spatial_slice(predictions, ax=axes.flat[i], title=model_name)

Uncertainty Comparison

# Compare uncertainty estimates
gp_models = ['GP_RBF', 'GP_Matern', 'GP_Combined', 'Deep_GP']
fig, axes = plt.subplots(1, len(gp_models), figsize=(20, 5))

for i, model_name in enumerate(gp_models):
    _, uncertainty = toolkit.predict_with_uncertainty(model_name)
    plot_uncertainty_map(uncertainty, ax=axes[i], title=f"{model_name} Uncertainty")

πŸ’‘ Best Practices

Model Development Workflow

  1. Start Simple: Begin with RBF kernel GP
  2. Establish Baseline: Use Ordinary Kriging for comparison
  3. Try Combined Kernels: Test RBF+MatΓ©rn combination
  4. Experiment with Deep GP: If traditional methods insufficient
  5. Validate Spatially: Use spatial cross-validation
  6. Optimize Hyperparameters: Use grid search or Bayesian optimization

Performance Monitoring

# Track model performance over time
performance_log = {
    'model_name': [],
    'r2_score': [],
    'rmse': [],
    'training_time': [],
    'memory_usage': []
}

# Log each experiment
def log_performance(model_name, results, training_time):
    performance_log['model_name'].append(model_name)
    performance_log['r2_score'].append(results.r2)
    performance_log['rmse'].append(results.rmse)
    performance_log['training_time'].append(training_time)
    # Memory usage tracking...

Next Steps:

  • Explore Deep GP Experiments for advanced modeling
  • Use the built-in SPE9Plotter class for advanced plotting techniques
  • For performance optimization, consider using GPU acceleration and batch processing