----Script Random Forest-----
from sklearn.ensemble import RandomForestRegressor
import pandas as pd

# Load dataset
file_path = "data baru.xlsx"
df = pd.read_excel(file_path)


# Mengganti '-' dan '8888' dengan NaN
df.replace({'-': pd.NA, 8888: pd.NA}, inplace=True)
print(df)


# Konversi kolom numerik ke tipe data float
df = df.apply(pd.to_numeric, errors='ignore')

# Interpolasi NaN dan 8888 pada semua kolom numerik menggunakan metode linear
df.interpolate(method='linear', inplace=True)


# Definisikan Fitur dan Target
# 3. Pisahkan Fitur (X) dan Target (y)
target_column = "RR"  # Ganti dengan nama kolom target
X = df.drop(columns=[target_column])  # Semua kolom kecuali target
y = df[target_column].values  # Kolom target


# Train Model Random Forest
rf = RandomForestRegressor(n_estimators=100)
rf.fit(X, y)

# Lihat Kepentingan Fitur
importances = rf.feature_importances_
print("Feature Importance:", importances)



----Script GRU-----



import numpy as np
import pandas as pd
import tensorflow as tf
import random
from tensorflow import keras
from tensorflow.keras import layers
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
import os

# Set Seed untuk Reproducibility
random.seed(42)
np.random.seed(42)
tf.random.set_seed(42)


# Pastikan operasi deterministik di TensorFlow
os.environ['TF_DETERMINISTIC_OPS'] = '1'
os.environ['TF_CUDNN_DETERMINISTIC'] = '1'

# Matikan Multi-threading untuk memastikan hasil tetap sama
tf.config.threading.set_inter_op_parallelism_threads(1)
tf.config.threading.set_intra_op_parallelism_threads(1)

# (Opsional) Paksa TensorFlow menggunakan CPU untuk hasil lebih deterministik
os.environ["CUDA_VISIBLE_DEVICES"] = "-1"

# 1. Load Dataset dari Excel
file_path = "2015-2024.xlsx"
df = pd.read_excel(file_path)


# 2. Interpolasi Data Hilang
df.replace(['-', 8888], np.nan, inplace=True)  # Ubah "-" dan 8888 menjadi NaN
df.interpolate(method='linear', inplace=True)  # Interpolasi nilai yang hilang
df.fillna(method='bfill', inplace=True)  # Backfill jika masih ada NaN

# 3. Pisahkan Fitur (X) dan Target (y)
target_column = "RR"  # Ganti dengan nama kolom target
X = df.drop(columns=[target_column])  # Semua kolom kecuali target
y = df[target_column].values  # Kolom target


# 📌 4. Split Data Dulu (80% Training, 20% Testing)
X_train_raw, X_test_raw, y_train_raw, y_test_raw = train_test_split(X, y, test_size=0.2, shuffle=False, random_state=42)

# 📌 5. Normalisasi Data Secara Terpisah
scaler_X = MinMaxScaler()
scaler_y = MinMaxScaler()

X_train_scaled = scaler_X.fit_transform(X_train_raw)
X_test_scaled = scaler_X.transform(X_test_raw)

y_train_scaled = scaler_y.fit_transform(y_train_raw.reshape(-1, 1))
y_test_scaled = scaler_y.transform(y_test_raw.reshape(-1, 1))

# 📌 6. Fungsi Windowing (30 Hari Input → 1 Hari Output)
def create_time_series(data_X, data_y, time_steps=30):
    Xs, ys = [], []
    for i in range(len(data_X) - time_steps):
        Xs.append(data_X[i:i + time_steps])  # 30 hari sebagai input
        ys.append(data_y[i + time_steps])  # 1 hari sebagai output
    return np.array(Xs), np.array(ys)

import matplotlib.pyplot as plt

# Parameter windowing
window_size = 30  # 30 hari input
output_size = 1   # 1 hari output

# Ambil 3 contoh window pertama dari dataset (pastikan df tersedia)
num_windows = 3
windows = [df.iloc[i:i+window_size+output_size] for i in range(num_windows)]

# Plot Visualisasi Windowing
plt.figure(figsize=(12, 6))

for i, window in enumerate(windows):
    input_days = window.iloc[:window_size]  # 30 hari terakhir (input)
    output_days = window.iloc[window_size:]  # 1 hari ke depan (output)

    # Plot Input Data (30 hari terakhir)
    plt.plot(input_days.index, input_days['RR'], label=f"Window {i+1} - Input (30 Hari)", linestyle='solid')

    # Plot Output Data (Prediksi 1 hari ke depan)
    plt.plot(output_days.index, output_days['RR'], label=f"Window {i+1} - Output (1 Hari)", linestyle='dashed')

plt.xlabel("Index")
plt.ylabel("Curah Hujan (Normalized)")
plt.title("Visualisasi Windowing (30 Hari Input → 1 Hari Prediksi)")
plt.legend()
plt.grid(True)

# Menampilkan plot
plt.show()

# 📌 7. Lakukan Windowing Setelah Split & Normalisasi
X_train, y_train = create_time_series(X_train_scaled, y_train_scaled, time_steps=30)
X_test, y_test = create_time_series(X_test_scaled, y_test_scaled, time_steps=30)

# 📌 8. Fungsi untuk Membangun Model GRU
def build_gru_model():
    model = keras.Sequential()
    model.add(layers.GRU(128, activation="tanh", return_sequences=True, input_shape=(X_train.shape[1], X_train.shape[2])))
    model.add(layers.GRU(32, activation="tanh", return_sequences=False))
    model.add(layers.Dropout(0.2))
    model.add(layers.Dense(1))  # Output Layer (Curah Hujan)

    optimizer = keras.optimizers.Adam(learning_rate=0.001)
    model.compile(loss='mean_squared_error', optimizer=optimizer)
    return model


# 📌 9. Training Model dengan Hyperparameter yang Ditetapkan
model = build_gru_model()

print("\n🔄 Training Model...")
history = model.fit(X_train, y_train, epochs=50, batch_size=64, validation_data=(X_test, y_test), shuffle=False, verbose=1)

# 📌 10. Prediksi Model
y_pred = model.predict(X_test)

# 📌 11. Denormalisasi Prediksi
y_pred_denorm = scaler_y.inverse_transform(y_pred)
y_test_denorm = scaler_y.inverse_transform(y_test)

# 📌 12. Hitung Evaluasi (RMSE, MAPE, MAE, R²)
rmse_denorm = np.sqrt(mean_squared_error(y_test_denorm, y_pred_denorm))
mae_denorm = mean_absolute_error(y_test_denorm, y_pred_denorm)



print( Evaluasi Model setelah Denormalisasi:")
print(RMSE: {rmse_denorm:.4f}")
print(MAE: {mae_denorm:.4f}")


import matplotlib.pyplot as plt

# Plot hasil prediksi vs nilai aktual
plt.figure(figsize=(10, 5))
plt.plot(y_test_denorm.flatten(), label="Actual", linestyle='solid', color='blue')
plt.plot(y_pred_denorm.flatten(), label="Predicted", linestyle='dashed', color='red')

# Menambahkan label dan judul
plt.xlabel("Sample Index")
plt.ylabel("Curah Hujan (mm)")
plt.title("Perbandingan Hasil Prediksi vs Nilai Aktual")
plt.legend()
plt.grid(True)

# Menampilkan plot
plt.show()
