Tempus / app.py
vincentiusyoshuac's picture
Create app.py
ba898b9 verified
raw
history blame
5.67 kB
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()