RMImron commited on
Commit
aa11f10
·
verified ·
1 Parent(s): 0f442ec

Upload 5 files

Browse files
app.py ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app.py
2
+ import gradio as gr
3
+ import pandas as pd
4
+ import matplotlib.pyplot as plt
5
+ import seaborn as sns
6
+ import io
7
+ from PIL import Image
8
+ from src.prediction import predict_range
9
+
10
+ def gradio_predict(start_month: str, end_month: str):
11
+ try:
12
+ df_pred = predict_range(start_month, end_month)
13
+ df_pred['input_month'] = pd.to_datetime(df_pred['input_month'])
14
+
15
+ # Label bulan dalam Bahasa Indonesia
16
+ bulan_indonesia = [
17
+ 'Januari', 'Februari', 'Maret', 'April', 'Mei', 'Juni',
18
+ 'Juli', 'Agustus', 'September', 'Oktober', 'November', 'Desember'
19
+ ]
20
+ df_pred['bulan_label'] = df_pred['input_month'].dt.month.apply(lambda x: bulan_indonesia[x-1]) + \
21
+ ' ' + df_pred['input_month'].dt.year.astype(str)
22
+
23
+ # Setup visualisasi
24
+ plt.figure(figsize=(15, 8))
25
+ sns.set_style("whitegrid")
26
+
27
+ # Warna berdasarkan nilai
28
+ cmap = plt.cm.Blues
29
+ norm = plt.Normalize(df_pred['prediksi_rr'].min(), df_pred['prediksi_rr'].max())
30
+ colors = cmap(norm(df_pred['prediksi_rr'].values))
31
+
32
+ # Garis utama
33
+ sns.lineplot(data=df_pred, x='bulan_label', y='prediksi_rr', color='darkcyan', linewidth=2, marker='o')
34
+
35
+ # Titik-titik & label nilai
36
+ for i, row in df_pred.iterrows():
37
+ plt.scatter(row['bulan_label'], row['prediksi_rr'], color=colors[i], s=120, edgecolor='black', zorder=5)
38
+ plt.text(
39
+ row['bulan_label'], row['prediksi_rr'] + 4,
40
+ f"{row['prediksi_rr']:.1f} mm", ha='center', va='bottom',
41
+ fontsize=9, color='black', bbox=dict(boxstyle="round,pad=0.2", fc="white", ec="gray", alpha=0.7)
42
+ )
43
+
44
+ # Titik ekstrem (max dan min)
45
+ max_idx = df_pred['prediksi_rr'].idxmax()
46
+ min_idx = df_pred['prediksi_rr'].idxmin()
47
+ plt.scatter(df_pred.loc[max_idx, 'bulan_label'], df_pred.loc[max_idx, 'prediksi_rr'],
48
+ color='red', s=150, label='Tertinggi', zorder=6)
49
+ plt.scatter(df_pred.loc[min_idx, 'bulan_label'], df_pred.loc[min_idx, 'prediksi_rr'],
50
+ color='blue', s=150, label='Terendah', zorder=6)
51
+
52
+ # Garis rata-rata
53
+ mean_val = df_pred['prediksi_rr'].mean()
54
+ plt.axhline(mean_val, color='orange', linestyle='--', linewidth=1.2, label=f'Rata-rata: {mean_val:.1f} mm')
55
+ plt.text(
56
+ x=len(df_pred) - 3, y=mean_val + 6,
57
+ s=f'{mean_val:.1f} mm', color='orange', fontsize=10, style='italic'
58
+ )
59
+
60
+ # Pengaturan plot
61
+ plt.title('Prediksi Curah Hujan Bulanan\nWilayah: Kota Bandung', fontsize=18, weight='bold')
62
+ plt.xlabel('Bulan', fontsize=12)
63
+ plt.ylabel('Curah Hujan (mm)', fontsize=12)
64
+ plt.xticks(rotation=45)
65
+ plt.legend()
66
+ plt.grid(True, linestyle='--', alpha=0.5)
67
+ plt.tight_layout()
68
+
69
+ # Simpan plot ke buffer
70
+ buf = io.BytesIO()
71
+ plt.savefig(buf, format='png', dpi=300)
72
+ plt.close()
73
+ buf.seek(0)
74
+ img = Image.open(buf)
75
+
76
+ # Format hasil tabel
77
+ df_pred['input_month'] = df_pred['input_month'].dt.strftime('%Y-%m')
78
+ result_str = df_pred[['input_month', 'prediksi_rr']].rename(
79
+ columns={'input_month': 'Bulan', 'prediksi_rr': 'Prediksi RR (mm)'}
80
+ ).to_string(index=False)
81
+
82
+ return result_str, img
83
+
84
+ except Exception as e:
85
+ return f"Terjadi kesalahan: {str(e)}", None
86
+
87
+ # Gradio interface
88
+ interface = gr.Interface(
89
+ fn=gradio_predict,
90
+ inputs=[
91
+ gr.Textbox(label="Bulan Awal (format: YYYY-MM)", placeholder="contoh: 2023-01"),
92
+ gr.Textbox(label="Bulan Akhir (format: YYYY-MM)", placeholder="contoh: 2023-12")
93
+ ],
94
+ outputs=[
95
+ gr.Textbox(label="Tabel Hasil Prediksi"),
96
+ gr.Image(label="Visualisasi Curah Hujan")
97
+ ],
98
+ title="Prediksi Curah Hujan Bulanan",
99
+ description="Masukkan rentang bulan untuk memprediksi curah hujan di Bandung menggunakan model Random Forest."
100
+ )
101
+
102
+ interface.launch(debug=True)
model/ModelFinal_random_forest_rainfall_.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5d16fe864cfb4187597cfcfb153696db1c40b9eef42785af0d4e8b49cb4758f8
3
+ size 3723425
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ gradio
2
+ matplotlib
3
+ pandas
4
+ seaborn
5
+ scikit-learn
6
+ joblib
7
+ python-dateutil
src/model.py ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ # src/model.py
2
+ import joblib
3
+ import os
4
+
5
+ # Fungsi untuk memuat model
6
+ def load_model():
7
+ model_path = os.path.join(os.path.dirname(__file__), '..', 'model', 'ModelFinal_random_forest_rainfall_.pkl')
8
+ return joblib.load(model_path)
src/prediction.py ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # src/prediction.py
2
+ from datetime import datetime
3
+ from dateutil.relativedelta import relativedelta
4
+ import pandas as pd
5
+ from src.model import load_model
6
+
7
+ # Load model sekali di awal
8
+ model = load_model()
9
+
10
+ # PREDIKSI 1 BULAN
11
+ def prediksi_curah_hujan(bulan_input: str):
12
+ """
13
+ Fungsi untuk memprediksi curah hujan berdasarkan bulan input.
14
+ Tidak ada preprocessing, asumsikan data sudah siap.
15
+ """
16
+ # Langsung pakai fitur yang diinginkan
17
+ features = [
18
+ 'month_cos',
19
+ 'RR_lag12',
20
+ 'season_dry',
21
+ 'season_rainy',
22
+ 'RR_above_monthly_median',
23
+ 'RR_monthly_median_loo',
24
+ 'RR_monthly_std_loo',
25
+ ]
26
+
27
+ # Anggap df_row sudah berisi data yang siap dipakai untuk prediksi
28
+ X = df_row[features]
29
+ prediksi = model.predict(X)
30
+ return prediksi[0]
31
+
32
+ # PREDIKSI BANYAK BULAN
33
+ def predict_range(start: str, end: str) -> pd.DataFrame:
34
+ """
35
+ Fungsi untuk melakukan prediksi curah hujan dalam rentang bulan.
36
+ Tanpa preprocessing, data langsung digunakan.
37
+ """
38
+ start_date = datetime.strptime(start, "%Y-%m")
39
+ end_date = datetime.strptime(end, "%Y-%m")
40
+ if start_date > end_date:
41
+ raise ValueError("Bulan awal tidak boleh lebih besar dari bulan akhir")
42
+
43
+ dates = []
44
+ current = start_date
45
+ while current <= end_date:
46
+ dates.append(current.strftime("%Y-%m"))
47
+ current += relativedelta(months=1)
48
+
49
+ # Di sini kita anggap data sudah siap tanpa perlu preprocessing
50
+ # Siapkan data secara langsung
51
+ processed_rows = []
52
+ for bulan_input in dates:
53
+ try:
54
+ row = prepare_data(bulan_input) # Anggap kita sudah punya data yang siap dipakai
55
+ processed_rows.append(row)
56
+ except Exception as e:
57
+ print(f"[SKIP] {bulan_input} gagal diproses: {e}")
58
+
59
+ if not processed_rows:
60
+ raise ValueError("Tidak ada bulan yang berhasil diproses.")
61
+
62
+ df_all = pd.concat(processed_rows, ignore_index=True)
63
+
64
+ features = [
65
+ 'month_cos',
66
+ 'RR_lag12',
67
+ 'season_dry',
68
+ 'season_rainy',
69
+ 'RR_above_monthly_median',
70
+ 'RR_monthly_median_loo',
71
+ 'RR_monthly_std_loo',
72
+ ]
73
+
74
+ X = df_all[features]
75
+ y_pred = model.predict(X)
76
+
77
+ df_result = pd.DataFrame({
78
+ 'input_month': df_all['YearMonth'].dt.strftime('%Y-%m'),
79
+ 'prediksi_rr': y_pred
80
+ })
81
+
82
+ return df_result