Spaces:
Sleeping
Sleeping
File size: 7,753 Bytes
ba898b9 0dc2bb2 ba898b9 db99fa0 0dc2bb2 ba898b9 0dc2bb2 ba898b9 631262b ba898b9 0dc2bb2 ba898b9 631262b 0dc2bb2 ba898b9 0dc2bb2 ba898b9 0dc2bb2 ba898b9 0dc2bb2 ba898b9 0dc2bb2 ba898b9 631262b ba898b9 631262b ba898b9 0dc2bb2 ba898b9 631262b 0dc2bb2 ba898b9 58edeb6 ba898b9 58edeb6 ba898b9 58edeb6 ba898b9 0dc2bb2 ba898b9 58edeb6 ba898b9 58edeb6 631262b 58edeb6 ba898b9 58edeb6 468610e 8a839a2 58edeb6 468610e 58edeb6 468610e 58edeb6 468610e 58edeb6 468610e ba898b9 58edeb6 468610e 58edeb6 468610e 58edeb6 468610e 58edeb6 8a839a2 58edeb6 468610e 58edeb6 468610e 58edeb6 ba898b9 58edeb6 ba898b9 468610e ba898b9 0dc2bb2 ba898b9 58edeb6 468610e 58edeb6 468610e 58edeb6 468610e ba898b9 58edeb6 468610e 58edeb6 468610e 58edeb6 631262b 468610e ba898b9 58edeb6 468610e ba898b9 58edeb6 ba898b9 0dc2bb2 631262b ba898b9 0dc2bb2 ba898b9 58edeb6 ba898b9 58edeb6 0dc2bb2 ba898b9 58edeb6 ba898b9 0dc2bb2 ba898b9 58edeb6 ba898b9 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
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("""
<style>
.stApp {
background-color: #FFFFFF;
font-family: 'Inter', 'Roboto', sans-serif;
}
.stButton>button {
background-color: #3498DB;
color: white;
border: none;
border-radius: 8px;
padding: 10px 20px;
transition: all 0.3s ease;
font-weight: 600;
}
.stButton>button:hover {
background-color: #2980B9;
transform: scale(1.05);
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}
/* Sleek file uploader */
.stFileUploader {
background-color: #F8F9FA;
border: 2px solid #3498DB;
border-radius: 10px;
padding: 20px;
text-align: center;
transition: all 0.3s ease;
}
.stFileUploader:hover {
border-color: #2980B9;
background-color: #EAF2F8;
}
</style>
""", unsafe_allow_html=True)
# Elegant title
st.markdown(
"<h1 style='text-align: center; color: #3498DB; margin-bottom: 30px;'>Tempus</h1>",
unsafe_allow_html=True
)
# File upload
uploaded_file = st.file_uploader(
"Upload Time Series Data",
type=['csv'],
help="CSV with timestamp and numeric columns"
)
if uploaded_file is not None:
# Read CSV
df = pd.read_csv(uploaded_file)
# Column selection
col1, col2 = st.columns(2)
with col1:
date_column = st.selectbox('Date Column', options=df.columns)
with col2:
value_column = st.selectbox(
'Value Column',
options=[col for col in df.columns if col != date_column]
)
# Advanced prediction settings
col3, col4 = st.columns(2)
with col3:
context_length = st.slider(
'Historical Context',
min_value=30,
max_value=500,
value=100,
help="Number of past data points to analyze"
)
with col4:
prediction_length = st.slider(
'Forecast Horizon',
min_value=1,
max_value=30, # Dibatasi maksimal 30
value=30, # Default 30
help="Number of future time steps to predict (max 30)"
)
# Forecast generation
if st.button('Generate Forecast'):
try:
# Initialize and run forecaster
forecaster = TimeSeriesForecaster()
# Preprocess data
context, prediction_length = forecaster.preprocess_data(
df,
date_column,
value_column,
context_length,
prediction_length
)
# Perform forecasting
forecasts = forecaster.forecast(context, prediction_length)
# Visualization
plt = forecaster.visualize_forecast(forecasts, forecaster.original_series)
st.pyplot(plt)
# Forecast details
forecast_np = forecasts[0].numpy()
forecast_mean = forecast_np.mean(axis=0)
forecast_lower = np.percentile(forecast_np, 10, axis=0)
forecast_upper = np.percentile(forecast_np, 90, axis=0)
st.subheader('Forecast Insights')
prediction_df = pd.DataFrame({
'Mean Forecast': forecast_mean,
'Lower Bound (10%)': forecast_lower,
'Upper Bound (90%)': forecast_upper
})
st.dataframe(prediction_df)
except Exception as e:
st.error(f"Forecast generation error: {str(e)}")
if __name__ == '__main__':
main() |