Spaces:
Sleeping
Sleeping
File size: 8,038 Bytes
61fe7a7 4bda154 afe3cf8 4bda154 afe3cf8 831e2db afe3cf8 4bda154 c4c84cb 4bda154 c4c84cb 4bda154 c4c84cb 4bda154 c4c84cb 4bda154 61fe7a7 4bda154 |
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 |
import streamlit as st
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import mean_squared_error
from datetime import timedelta
import torch
import torch.nn as nn
from PIL import Image
from pathlib import Path
# --- Configuration de la page ---
# Doit être la première commande Streamlit du script
st.set_page_config(
page_title="Prédiction Boursière GRU",
page_icon="📈",
layout="wide"
)
script = Path(__file__)
script_dir = script.parent
# --- Définition des modèles et fonctions (partie non visible dans l'UI) ---
# === Définition de l'architecture du modèle GRU ===
class GRUModel(nn.Module):
def __init__(self, input_size=1, hidden_layer_size=50, num_layers=2, output_size=1):
super().__init__()
self.hidden_layer_size = hidden_layer_size
self.gru = nn.GRU(input_size, hidden_layer_size, num_layers, batch_first=True)
self.fc = nn.Linear(hidden_layer_size, output_size)
def forward(self, input_seq):
gru_out, _ = self.gru(input_seq)
predictions = self.fc(gru_out[:, -1])
return predictions
# === Fonctions de chargement et de traitement (avec cache pour la performance) ===
@st.cache_data
def load_data(csv_path= script_dir/"action_amd.csv"):
"""Charge les données depuis le fichier CSV et les formate correctement."""
try:
df = pd.read_csv(csv_path)
except FileNotFoundError:
st.error(f"Erreur : Le fichier '{csv_path}' est introuvable. "
"Assurez-vous qu'il se trouve dans le même dossier que votre script.")
st.stop()
if 'Date' not in df.columns or 'Close' not in df.columns:
st.error("Le fichier CSV doit contenir les colonnes 'Date' et 'Close'.")
st.stop()
df_filtered = df[['Date', 'Close']].copy()
df_filtered['Date'] = pd.to_datetime(df_filtered['Date'])
df_renamed = df_filtered.rename(columns={'Date': 'ds', 'Close': 'y'})
return df_renamed.sort_values(by='ds')
@st.cache_resource
def load_gru_model(path, model_class):
"""Charge le modèle GRU pré-entraîné."""
model = model_class()
model.load_state_dict(torch.load(path, map_location=torch.device('cpu')))
model.eval()
return model
def predict_gru(model, df, forecast_days, window_size=20):
"""Effectue des prédictions sur les N prochains jours."""
data_values = df['y'].values
predictions = []
input_seq_np = data_values[-window_size:]
for _ in range(forecast_days):
input_seq_torch = torch.from_numpy(input_seq_np).float().view(1, window_size, 1)
with torch.no_grad():
pred = model(input_seq_torch).item()
predictions.append(pred)
input_seq_np = np.append(input_seq_np[1:], pred)
last_date = df['ds'].max()
future_dates = []
current_date = last_date
while len(future_dates) < forecast_days:
current_date += timedelta(days=1)
if current_date.weekday() < 5:
future_dates.append(current_date)
return pd.DataFrame({'ds': future_dates, 'yhat': predictions})
def calculate_rmse(y_true, y_pred):
return np.sqrt(mean_squared_error(y_true, y_pred))
# --- Définition des pages de l'application ---
def page_accueil():
"""Affiche la page d'accueil."""
st.title("Projet de Prédiction de Séries Temporelles avec GRU")
st.markdown("---")
col1, col2 = st.columns([1, 3])
with col1:
try:
logo_keyce = Image.open(script_dir/"Keyce_Logo.jpg")
st.image(logo_keyce, width=150)
except FileNotFoundError:
st.warning("Logo Keyce Keyce_Logo.jpg non trouvé.")
with col2:
st.header("KEYCE INFORMATIQUE - Master II IA")
st.subheader("Session Normale de Réseaux de Neurones Récurrents (RNN)")
st.markdown("---")
st.header("Présentation de l'étudiant")
st.markdown("### **Nom :** TATSA TCHINDA Colince")
st.info("Utilisez le menu de navigation à gauche pour accéder à la page de prédiction.")
def page_prediction():
"""Affiche la page de prédiction et ses résultats."""
st.title("📈 Prédiction du Cours de l'Action AMD")
# --- Étape 1: Chargement des données ---
st.header("Étape 1 : Chargement et Visualisation des Données")
with st.spinner("Chargement des données historiques..."):
data = load_data()
st.success("Données chargées avec succès !")
fig, ax = plt.subplots(figsize=(12, 5))
ax.plot(data['ds'], data['y'], label="Historique", color='black')
ax.set_xlabel("Date")
ax.set_ylabel("Prix de clôture ($)")
ax.set_title("Cours historique de l'action AMD")
ax.grid(True)
ax.legend()
st.pyplot(fig)
# --- Étape 2: Chargement du modèle ---
st.header("Étape 2 : Chargement du Modèle GRU")
with st.spinner("Chargement du modèle pré-entraîné..."):
try:
gru_model = load_gru_model(script_dir/"model_gru.pth", GRUModel)
st.success("Modèle GRU chargé avec succès !")
except FileNotFoundError:
st.error("Erreur : Le fichier 'model_gru.pth' est introuvable.")
st.stop()
# --- Étape 3: Prédictions ---
st.header("Étape 3 : Génération des Prédictions")
WINDOW_SIZE = 20
FORECAST_DAYS = 21
with st.spinner(f"Calcul des prédictions pour les {FORECAST_DAYS} prochains jours..."):
gru_forecast = predict_gru(gru_model, data, FORECAST_DAYS, window_size=WINDOW_SIZE)
st.subheader("Prédictions du modèle GRU vs Historique récent")
fig, ax = plt.subplots(figsize=(12, 5))
ax.plot(data['ds'].tail(100), data['y'].tail(100), label="Historique récent", color='black')
ax.plot(gru_forecast['ds'], gru_forecast['yhat'], label=f"Prédiction GRU ({FORECAST_DAYS} jours)", color='orange', linestyle='--')
ax.set_xlabel("Date")
ax.set_ylabel("Prix de clôture ($)")
ax.set_title("Prédictions GRU vs Historique")
ax.grid(True)
ax.legend()
st.pyplot(fig)
# --- Étape 4: Évaluation et Résultats ---
st.header("Étape 4 : Évaluation et Résultats")
st.subheader("Performance du Modèle (Backtesting)")
true_values = data['y'].values[-WINDOW_SIZE:]
# ... (Le reste de votre logique de backtesting est correct)
input_for_backtest_np = data['y'].values[-(WINDOW_SIZE * 2):-WINDOW_SIZE]
backtest_preds = []
input_seq_for_backtest = input_for_backtest_np.copy()
for _ in range(WINDOW_SIZE):
input_tensor = torch.from_numpy(input_seq_for_backtest[-WINDOW_SIZE:]).float().view(1, WINDOW_SIZE, 1)
with torch.no_grad():
pred = gru_model(input_tensor).item()
backtest_preds.append(pred)
input_seq_for_backtest = np.append(input_seq_for_backtest, pred)
gru_rmse = calculate_rmse(true_values, backtest_preds)
st.metric(label="RMSE (Backtest sur 20 jours)", value=f"{gru_rmse:.4f}")
st.info("Le RMSE évalue l'écart moyen entre les valeurs prédites et les valeurs réelles sur la période de test.")
st.subheader("Tableau des Prédictions")
styled_df = gru_forecast.style.format({'yhat': '{:.2f}'})
st.dataframe(styled_df, use_container_width=True)
csv = gru_forecast.to_csv(index=False).encode('utf-8')
st.download_button(
label="📥 Télécharger les prédictions (.csv)",
data=csv,
file_name="predictions_gru_amd.csv",
mime="text/csv",
)
# --- Barre latérale et Navigation ---
st.sidebar.header("Navigation")
try:
logo_theme = Image.open(script_dir/"Theme_Logo.jpg")
st.sidebar.image(logo_theme, use_container_width=True)
except FileNotFoundError:
st.sidebar.warning("Logo thème Theme_Logo.jpg non trouvé.")
page = st.sidebar.selectbox(
"Choisissez une page",
["Accueil", "Prédiction"]
)
# --- Affichage de la page sélectionnée ---
if page == "Accueil":
page_accueil()
elif page == "Prédiction":
page_prediction() |