import streamlit as st import pandas as pd import numpy as np import matplotlib.pyplot as plt import torch from chronos import ChronosPipeline class TimeSeriesForecaster: def __init__(self, model_name="amazon/chronos-t5-small"): self.pipeline = ChronosPipeline.from_pretrained( model_name, device_map="cuda" if torch.cuda.is_available() else "cpu", torch_dtype=torch.bfloat16 if torch.cuda.is_available() else torch.float32 ) self.original_series = None self.context = None def preprocess_data(self, df, date_column, value_column, context_length=100, prediction_length=30): """ Prepare time series data from DataFrame """ # Validasi panjang prediksi if prediction_length > 30: st.warning("Prediction length dibatasi maksimal 30 langkah. Akan disesuaikan.") prediction_length = min(prediction_length, 30) # Ensure data is sorted by date df = df.sort_values(by=date_column) # Convert date column to datetime df[date_column] = pd.to_datetime(df[date_column]) # Set index to date df.set_index(date_column, inplace=True) # Extract numeric series self.original_series = df[value_column].values # Convert to tensor self.context = torch.tensor(self.original_series[-context_length:], dtype=torch.float32) return self.context, prediction_length def forecast(self, context, prediction_length=30, num_samples=100): """ Perform time series forecasting """ # Pastikan prediksi tidak melebihi 30 langkah prediction_length = min(prediction_length, 30) forecasts = self.pipeline.predict(context, prediction_length, num_samples=num_samples) return forecasts def visualize_forecast(self, forecasts, original_series): """ Create comprehensive visualization of predictions """ plt.figure(figsize=(16, 8), dpi=100, facecolor='white') # Calculate forecast statistics forecast_np = forecasts[0].numpy() low, median, high = np.quantile(forecast_np, [0.1, 0.5, 0.9], axis=0) # Plot original series plt.plot( range(len(original_series)), original_series, label='Historical Data', color='#2C3E50', linewidth=2, alpha=0.7 ) # Forecast index forecast_index = range(len(original_series), len(original_series) + len(median)) # Plot median forecast plt.plot( forecast_index, median, color='#3498DB', linewidth=3, label='Median Forecast' ) # Plot prediction interval plt.fill_between( forecast_index, low, high, color='#3498DB', alpha=0.2, label='90% Prediction Interval' ) plt.title('Advanced Time Series Forecast (Max 30 Steps)', fontsize=18, fontweight='bold', color='#2C3E50') plt.xlabel('Time Steps', fontsize=12, color='#34495E') plt.ylabel('Value', fontsize=12, color='#34495E') plt.legend(frameon=False) plt.grid(True, linestyle='--', color='#BDC3C7', alpha=0.5) # Sophisticated styling plt.tight_layout() return plt def main(): # Page configuration st.set_page_config( page_title="Tempus", page_icon="📊", layout="wide" ) # Modern, minimalist styling st.markdown(""" """, unsafe_allow_html=True) # Elegant title st.markdown( "