Spaces:
Sleeping
Sleeping
import streamlit as st | |
import pandas as pd | |
import numpy as np | |
import matplotlib.pyplot as plt | |
from amazon_chronos import ChronosModel, TimeSeriesDataSet | |
import tempfile | |
import os | |
class TimeSeriesForecaster: | |
def __init__(self): | |
self.model = None | |
self.dataset = None | |
self.original_series = None | |
def preprocess_data(self, df, date_column, value_column, context_length=30, prediction_length=7): | |
""" | |
Persiapkan data time series dari DataFrame | |
""" | |
# Pastikan data terurut berdasarkan tanggal | |
df = df.sort_values(by=date_column) | |
# Konversi kolom tanggal ke datetime | |
df[date_column] = pd.to_datetime(df[date_column]) | |
# Set index ke tanggal | |
df.set_index(date_column, inplace=True) | |
# Ekstrak series numerik | |
time_series = df[value_column].values | |
# Buat dataset Chronos | |
self.original_series = time_series | |
self.dataset = TimeSeriesDataSet.from_series( | |
time_series, | |
context_length=context_length, | |
prediction_length=prediction_length | |
) | |
return self.dataset | |
def train_model(self, model_id='chronos-t5-small'): | |
""" | |
Latih model Chronos | |
""" | |
self.model = ChronosModel.from_pretrained(model_id) | |
self.model.fit(self.dataset) | |
return self.model | |
def forecast(self, n_samples=100): | |
""" | |
Lakukan prediksi | |
""" | |
if not self.model or not self.dataset: | |
raise ValueError("Model belum dilatih. Latih model terlebih dahulu.") | |
forecasts = self.model.predict(self.dataset, num_samples=n_samples) | |
return forecasts | |
def visualize_forecast(self, forecasts): | |
""" | |
Buat visualisasi prediksi | |
""" | |
plt.figure(figsize=(12, 6)) | |
# Plot series asli | |
plt.plot(self.original_series, label='Data Historis', color='blue') | |
# Plot prediksi | |
forecast_mean = forecasts.mean(axis=0) | |
forecast_lower = np.percentile(forecasts, 10, axis=0) | |
forecast_upper = np.percentile(forecasts, 90, axis=0) | |
forecast_start = len(self.original_series) | |
plt.plot( | |
range(forecast_start, forecast_start + len(forecast_mean)), | |
forecast_mean, | |
label='Prediksi Rata-rata', | |
color='red' | |
) | |
plt.fill_between( | |
range(forecast_start, forecast_start + len(forecast_mean)), | |
forecast_lower, | |
forecast_upper, | |
alpha=0.3, | |
color='red' | |
) | |
plt.title('Peramalan Time Series dengan Amazon Chronos') | |
plt.xlabel('Indeks Waktu') | |
plt.ylabel('Nilai') | |
plt.legend() | |
return plt | |
def main(): | |
st.title('🕰️ Time Series Forecasting dengan Amazon Chronos') | |
# Sidebar untuk upload dan konfigurasi | |
st.sidebar.header('Pengaturan Prediksi') | |
# Upload file CSV | |
uploaded_file = st.sidebar.file_uploader( | |
"Unggah File CSV", | |
type=['csv'], | |
help="Pastikan file CSV memiliki kolom tanggal dan nilai numerik" | |
) | |
# Pilihan kolom | |
if uploaded_file is not None: | |
# Baca CSV | |
df = pd.read_csv(uploaded_file) | |
# Pilih kolom | |
date_column = st.sidebar.selectbox( | |
'Pilih Kolom Tanggal', | |
options=df.columns | |
) | |
value_column = st.sidebar.selectbox( | |
'Pilih Kolom Nilai', | |
options=[col for col in df.columns if col != date_column] | |
) | |
# Parameter prediksi | |
context_length = st.sidebar.slider( | |
'Panjang Konteks', | |
min_value=10, | |
max_value=100, | |
value=30 | |
) | |
prediction_length = st.sidebar.slider( | |
'Panjang Prediksi', | |
min_value=1, | |
max_value=30, | |
value=7 | |
) | |
# Tombol proses | |
if st.sidebar.button('Lakukan Prediksi'): | |
try: | |
# Inisiasi forecaster | |
forecaster = TimeSeriesForecaster() | |
# Preprocessing | |
dataset = forecaster.preprocess_data( | |
df, | |
date_column, | |
value_column, | |
context_length, | |
prediction_length | |
) | |
# Latih model | |
model = forecaster.train_model() | |
# Lakukan prediksi | |
forecasts = forecaster.forecast() | |
# Tampilkan hasil | |
st.subheader('Visualisasi Prediksi') | |
plt = forecaster.visualize_forecast(forecasts) | |
st.pyplot(plt) | |
# Tampilkan detail prediksi | |
forecast_mean = forecasts.mean(axis=0) | |
forecast_lower = np.percentile(forecasts, 10, axis=0) | |
forecast_upper = np.percentile(forecasts, 90, axis=0) | |
prediction_df = pd.DataFrame({ | |
'Prediksi Rata-rata': forecast_mean, | |
'Batas Bawah (10%)': forecast_lower, | |
'Batas Atas (90%)': forecast_upper | |
}) | |
st.subheader('Detail Prediksi') | |
st.dataframe(prediction_df) | |
except Exception as e: | |
st.error(f"Terjadi kesalahan: {str(e)}") | |
if __name__ == '__main__': | |
main() |