Data_sheets / src /modeling /advanced_models.py
Navya-Sree's picture
Update src/modeling/advanced_models.py
4b79491 verified
import numpy as np
import pandas as pd
import torch
import torch.nn as nn
from torch.utils.data import DataLoader, TensorDataset
from prophet import Prophet
from pmdarima import auto_arima
import logging
logger = logging.getLogger(__name__)
class LSTMForecaster(nn.Module):
"""LSTM model for time series forecasting."""
def __init__(self, input_size: int, hidden_size: int, num_layers: int,
output_size: int, dropout: float = 0.2):
super(LSTMForecaster, self).__init__()
self.hidden_size = hidden_size
self.num_layers = num_layers
self.lstm = nn.LSTM(input_size, hidden_size, num_layers,
batch_first=True, dropout=dropout)
self.dropout = nn.Dropout(dropout)
self.linear = nn.Linear(hidden_size, output_size)
def forward(self, x):
lstm_out, _ = self.lstm(x)
lstm_out = self.dropout(lstm_out[:, -1, :]) # Take the last output
out = self.linear(lstm_out)
return out
class AdvancedModelTrainer:
"""Trainer for advanced forecasting models."""
def __init__(self, config: dict):
self.config = config
def train_lstm(self, X_train: np.ndarray, y_train: np.ndarray,
X_val: np.ndarray = None,
y_val: np.ndarray = None) -> nn.Module:
"""Train LSTM model."""
model_config = self.config['lstm']
# Convert to PyTorch tensors
train_dataset = TensorDataset(
torch.FloatTensor(X_train),
torch.FloatTensor(y_train)
)
train_loader = DataLoader(train_dataset, batch_size=model_config['batch_size'], shuffle=True)
# Initialize model
model = LSTMForecaster(
input_size=X_train.shape[2],
hidden_size=model_config['hidden_size'],
num_layers=model_config['num_layers'],
output_size=y_train.shape[1],
dropout=model_config['dropout']
)
# Training setup
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=model_config['learning_rate'])
# Training loop
for epoch in range(model_config['epochs']):
model.train()
epoch_loss = 0
for batch_X, batch_y in train_loader:
optimizer.zero_grad()
predictions = model(batch_X)
loss = criterion(predictions, batch_y)
loss.backward()
# Gradient clipping
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
optimizer.step()
epoch_loss += loss.item()
if epoch % 10 == 0:
logger.info(f'Epoch {epoch}, Loss: {epoch_loss/len(train_loader):.4f}')
return model
def train_prophet(self, df: pd.DataFrame,
date_col: str,
value_col: str) -> Prophet:
"""Train Facebook Prophet model."""
prophet_df = df[[date_col, value_col]].rename(
columns={date_col: 'ds', value_col: 'y'}
)
model = Prophet(
changepoint_prior_scale=self.config['prophet'].get('changepoint_prior_scale', 0.05),
seasonality_prior_scale=self.config['prophet'].get('seasonality_prior_scale', 10),
yearly_seasonality=self.config['prophet'].get('yearly_seasonality', True),
weekly_seasonality=self.config['prophet'].get('weekly_seasonality', True),
daily_seasonality=self.config['prophet'].get('daily_seasonality', False)
)
model.fit(prophet_df)
return model
def train_auto_arima(self, series: pd.Series) -> object:
"""Train auto ARIMA model."""
model = auto_arima(
series,
start_p=1,
start_q=1,
max_p=3,
max_q=3,
seasonal=True,
m=7,
stepwise=True,
suppress_warnings=True,
error_action='ignore'
)
return model