Data_sheets / src /modeling /advanced_models.py
Navya-Sree's picture
Update src/modeling/advanced_models.py
4b79491 verified
Raw
History Blame Contribute Delete
4.2 kB
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