vincentiusyoshuac commited on
Commit
ba898b9
·
verified ·
1 Parent(s): 6dd079e

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +181 -0
app.py ADDED
@@ -0,0 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import numpy as np
4
+ import matplotlib.pyplot as plt
5
+ from amazon_chronos import ChronosModel, TimeSeriesDataSet
6
+ import tempfile
7
+ import os
8
+
9
+ class TimeSeriesForecaster:
10
+ def __init__(self):
11
+ self.model = None
12
+ self.dataset = None
13
+ self.original_series = None
14
+
15
+ def preprocess_data(self, df, date_column, value_column, context_length=30, prediction_length=7):
16
+ """
17
+ Persiapkan data time series dari DataFrame
18
+ """
19
+ # Pastikan data terurut berdasarkan tanggal
20
+ df = df.sort_values(by=date_column)
21
+
22
+ # Konversi kolom tanggal ke datetime
23
+ df[date_column] = pd.to_datetime(df[date_column])
24
+
25
+ # Set index ke tanggal
26
+ df.set_index(date_column, inplace=True)
27
+
28
+ # Ekstrak series numerik
29
+ time_series = df[value_column].values
30
+
31
+ # Buat dataset Chronos
32
+ self.original_series = time_series
33
+ self.dataset = TimeSeriesDataSet.from_series(
34
+ time_series,
35
+ context_length=context_length,
36
+ prediction_length=prediction_length
37
+ )
38
+
39
+ return self.dataset
40
+
41
+ def train_model(self, model_id='chronos-t5-small'):
42
+ """
43
+ Latih model Chronos
44
+ """
45
+ self.model = ChronosModel.from_pretrained(model_id)
46
+ self.model.fit(self.dataset)
47
+ return self.model
48
+
49
+ def forecast(self, n_samples=100):
50
+ """
51
+ Lakukan prediksi
52
+ """
53
+ if not self.model or not self.dataset:
54
+ raise ValueError("Model belum dilatih. Latih model terlebih dahulu.")
55
+
56
+ forecasts = self.model.predict(self.dataset, num_samples=n_samples)
57
+ return forecasts
58
+
59
+ def visualize_forecast(self, forecasts):
60
+ """
61
+ Buat visualisasi prediksi
62
+ """
63
+ plt.figure(figsize=(12, 6))
64
+
65
+ # Plot series asli
66
+ plt.plot(self.original_series, label='Data Historis', color='blue')
67
+
68
+ # Plot prediksi
69
+ forecast_mean = forecasts.mean(axis=0)
70
+ forecast_lower = np.percentile(forecasts, 10, axis=0)
71
+ forecast_upper = np.percentile(forecasts, 90, axis=0)
72
+
73
+ forecast_start = len(self.original_series)
74
+ plt.plot(
75
+ range(forecast_start, forecast_start + len(forecast_mean)),
76
+ forecast_mean,
77
+ label='Prediksi Rata-rata',
78
+ color='red'
79
+ )
80
+ plt.fill_between(
81
+ range(forecast_start, forecast_start + len(forecast_mean)),
82
+ forecast_lower,
83
+ forecast_upper,
84
+ alpha=0.3,
85
+ color='red'
86
+ )
87
+
88
+ plt.title('Peramalan Time Series dengan Amazon Chronos')
89
+ plt.xlabel('Indeks Waktu')
90
+ plt.ylabel('Nilai')
91
+ plt.legend()
92
+
93
+ return plt
94
+
95
+ def main():
96
+ st.title('🕰️ Time Series Forecasting dengan Amazon Chronos')
97
+
98
+ # Sidebar untuk upload dan konfigurasi
99
+ st.sidebar.header('Pengaturan Prediksi')
100
+
101
+ # Upload file CSV
102
+ uploaded_file = st.sidebar.file_uploader(
103
+ "Unggah File CSV",
104
+ type=['csv'],
105
+ help="Pastikan file CSV memiliki kolom tanggal dan nilai numerik"
106
+ )
107
+
108
+ # Pilihan kolom
109
+ if uploaded_file is not None:
110
+ # Baca CSV
111
+ df = pd.read_csv(uploaded_file)
112
+
113
+ # Pilih kolom
114
+ date_column = st.sidebar.selectbox(
115
+ 'Pilih Kolom Tanggal',
116
+ options=df.columns
117
+ )
118
+ value_column = st.sidebar.selectbox(
119
+ 'Pilih Kolom Nilai',
120
+ options=[col for col in df.columns if col != date_column]
121
+ )
122
+
123
+ # Parameter prediksi
124
+ context_length = st.sidebar.slider(
125
+ 'Panjang Konteks',
126
+ min_value=10,
127
+ max_value=100,
128
+ value=30
129
+ )
130
+ prediction_length = st.sidebar.slider(
131
+ 'Panjang Prediksi',
132
+ min_value=1,
133
+ max_value=30,
134
+ value=7
135
+ )
136
+
137
+ # Tombol proses
138
+ if st.sidebar.button('Lakukan Prediksi'):
139
+ try:
140
+ # Inisiasi forecaster
141
+ forecaster = TimeSeriesForecaster()
142
+
143
+ # Preprocessing
144
+ dataset = forecaster.preprocess_data(
145
+ df,
146
+ date_column,
147
+ value_column,
148
+ context_length,
149
+ prediction_length
150
+ )
151
+
152
+ # Latih model
153
+ model = forecaster.train_model()
154
+
155
+ # Lakukan prediksi
156
+ forecasts = forecaster.forecast()
157
+
158
+ # Tampilkan hasil
159
+ st.subheader('Visualisasi Prediksi')
160
+ plt = forecaster.visualize_forecast(forecasts)
161
+ st.pyplot(plt)
162
+
163
+ # Tampilkan detail prediksi
164
+ forecast_mean = forecasts.mean(axis=0)
165
+ forecast_lower = np.percentile(forecasts, 10, axis=0)
166
+ forecast_upper = np.percentile(forecasts, 90, axis=0)
167
+
168
+ prediction_df = pd.DataFrame({
169
+ 'Prediksi Rata-rata': forecast_mean,
170
+ 'Batas Bawah (10%)': forecast_lower,
171
+ 'Batas Atas (90%)': forecast_upper
172
+ })
173
+
174
+ st.subheader('Detail Prediksi')
175
+ st.dataframe(prediction_df)
176
+
177
+ except Exception as e:
178
+ st.error(f"Terjadi kesalahan: {str(e)}")
179
+
180
+ if __name__ == '__main__':
181
+ main()