CPP / app.py
AudreyMireille's picture
Update app.py
5046098 verified
import pandas as pd
import numpy as np
import tensorflow as tf
import random as rn
import yfinance as yf
import streamlit as st
import datetime as dt
import plotly.graph_objects as go
from plotly.subplots import make_subplots
from sklearn.preprocessing import MinMaxScaler
from streamlit_option_menu import option_menu
np.random.seed(1)
tf.random.set_seed(1)
rn.seed(1)
from keras.models import Sequential
from keras.layers import Dense, Dropout, LSTM
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
from millify import millify
import pandas_datareader as web
from cryptocmd import CmcScraper
from datetime import datetime, timedelta
# import utils
from utils import *
import time
st.set_page_config(layout="wide")
def load_data(dataset):
df=pd.read_csv(dataset)
return df
def main():
# récupération des données sur 10 ans
start = dt.datetime.today() - dt.timedelta(10 * 365)
end = dt.datetime.today()
a = start.strftime("%d-%m-%Y")
b = end.strftime("%d-%m-%Y")
with st.sidebar:
selected = option_menu("Menu",["Accueil","Visualisation", "Prédiction", "Documentation"],
icons =['house',"bar-chart-fill", 'gear', 'book'] , menu_icon ="border-width", default_index=0)
#whitespace = 15
#choice = st.tabs([s.center(whitespace,"\u2001") for s in menu])
if selected == "Accueil":
left, middle, right = st.columns((1,2,1))
with middle:
st.image('images/cryptos.jpeg',width=400)
st.markdown("----")
st.write(" ")
st.write(" ")
st.write(" ")
st.write(" ")
st.markdown("<h1 style='text-align:center;color: black;'>Bienvenue sur Crypto Predict(CP)!</h1>",unsafe_allow_html=True)
st.markdown("<h3 style='text-align:center;color: black;'>Crypto Predict(CP) est une application web alimentée par un modèle d'apprentissage automatique qui anticipe le cours de clôture à venir.</h1>",unsafe_allow_html=True)
left, middle, right = st.columns((1.5,1,1))
with middle:
Go = st.button("LET'S GO!")
if selected == "Visualisation":
st.title('Visualisation des données ')
csv = pd.read_csv("convertcsv.csv")
symbol = csv["symbol"].tolist()
# select box ticker
ticker_input = st.selectbox(
"Saisir ou choisir une crypto", symbol, index=symbol.index("BTC")
)
# initialisation du scraper avec les deux dates
scraper = CmcScraper(ticker_input, a, b)
# Pandas dataFrame for the same data
df = scraper.get_dataframe()
fig_viz = go.Figure()
fig_viz.add_trace(
go.Scatter(x=df["Date"], y=df["Close"])
)
fig_viz.update_layout(
legend=dict(orientation="h", yanchor="bottom", y=1, xanchor="left", x=0),
height=600,
title_text=f"Evolution du prix à la fermeture pour {ticker_input}",
template="gridon",
)
st.plotly_chart(fig_viz, use_container_width=True)
if selected == 'Prédiction':
st.title("Prédiction")
csv = pd.read_csv("convertcsv.csv")
symbol = csv["symbol"].tolist()
# select box ticker
ticker_input = st.selectbox(
"Saisir ou choisir une crypto", symbol, index=symbol.index("BTC")
)
# initialisation du scraper avec les deux dates
scraper = CmcScraper(ticker_input, a, b)
# Pandas dataFrame for the same data
df = scraper.get_dataframe()
if ticker_input:
# Enregistrement du temps de début
start_time = time.time()
st.write(f"Génération des prédictions pour : {ticker_input}...")
# tri du dataframe par dates croissantes vu que les données sont rendues par ordre décroissant
crypto_df = df.sort_values(["Date"], ascending=True, axis=0)
# création du dataframe pour les LSTM
crypto_df_lstm = pd.DataFrame(index=range(0, len(crypto_df)), columns=["Date", "Close"])
for i in range(0, len(crypto_df)):
crypto_df_lstm["Date"][i] = crypto_df["Date"][i]
crypto_df_lstm["Close"][i] = crypto_df["Close"][i]
# on fixe de la date comme index
crypto_df_lstm.index = crypto_df_lstm.Date
crypto_df_lstm.drop("Date", axis=1, inplace=True)
crypto_df_lstm = crypto_df_lstm.sort_index(ascending=True)
dataset = crypto_df_lstm.values
# division 70% (train) 20% (test)
train_index = int(0.70 * len(dataset))
# train set
train = dataset[:train_index]
# test set
valid = dataset[train_index:]
# mise à l'échelle des données
scaler = MinMaxScaler(feature_range=(0, 1))
scaled_data = scaler.fit_transform(dataset)
x_train, y_train = [], []
window = 30 # un mois
for i in range(window, len(train)):
# récupération des données par bloc d'un mois (30 jours)
x_train.append(scaled_data[i - window : i, 0])
# récupération de la prochaine valeur comme étiquette
y_train.append(scaled_data[i, 0])
x_train, y_train = np.array(x_train), np.array(y_train)
# mise sous la forme (nombre d'échantillons, fenêtre de temps, nombre de features)
x_train = np.reshape(x_train, (x_train.shape[0], x_train.shape[1], 1))
# construction du réseau LSTM par la méthode fonctionnelle
# le réseau n'est pas complexifié pour permettre une exécution rapide
model = Sequential()
model.add(LSTM(units=100, return_sequences=True, input_shape=(x_train.shape[1], 1)))
model.add(Dropout(0.2))
model.add(LSTM(units=100))
model.add(Dropout(0.2))
model.add(Dense(1))
model.compile(loss="mean_squared_error", optimizer="adam")
print("Entrainement du modèle")
model.fit(x_train, y_train, epochs=1, batch_size=32,validation_split=0.3)
# récupération de toutes les valeurs du test set (valid) et des window valeurs avant elles, ce qui explique le -window
inputs = crypto_df_lstm[len(crypto_df_lstm) - len(valid) - window :].values
inputs = inputs.reshape(-1, 1)
inputs = scaler.transform(inputs)
X_test = []
for i in range(window, inputs.shape[0]):
X_test.append(inputs[i - window : i, 0])
X_test = np.array(X_test)
# transformation du test set à un format approprié
X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1))
closing_price = model.predict(X_test)
closing_price = scaler.inverse_transform(closing_price)
# for plotting
train = crypto_df[:train_index]
valid = crypto_df[train_index:]
valid["Predictions"] = closing_price
fig_preds = go.Figure()
fig_preds.add_trace(
go.Scatter(x=train["Date"], y=train["Close"], name="Train Set")
)
fig_preds.add_trace(
go.Scatter(x=valid["Date"], y=valid["Close"], name="Test Set")
)
fig_preds.add_trace(
go.Scatter(x=valid["Date"], y=valid["Predictions"], name="Prédictions")
)
fig_preds.update_layout(
legend=dict(orientation="h", yanchor="bottom", y=1, xanchor="left", x=0),
height=600,
title_text=f"Valeurs actuelles VS Valeurs prédites pour {ticker_input}",
template="gridon",
)
st.plotly_chart(fig_preds, use_container_width=True)
# Prédiction au jour suivant
real_data = [inputs[len(inputs) - window : len(inputs + 1), 0]]
real_data = np.array(real_data)
real_data = np.reshape(real_data, (real_data.shape[0], real_data.shape[1], 1))
prediction = model.predict(real_data)
prediction = scaler.inverse_transform(prediction)
# calcul des métriques
perfs = performances(valid["Close"],valid["Predictions"])
end_time = time.time()
# Convertir la dernière en objet datetime
date_obj = dt.datetime.strptime(b, "%d-%m-%Y")
# Ajouter un jour
nouvelle_date = date_obj + dt.timedelta(days=1)
# Convertir la nouvelle date en format souhaité
nouvelle_date_str = nouvelle_date.strftime("%d-%m-%Y")
with st.container():
col_1, col_2, col_3,col_4 = st.columns(4)
col_1.metric(f"Préd. jour **{nouvelle_date_str}** :",f"{str(round(float(prediction), 2))}")
col_2.metric(f"R2 Score :", f"{perfs[0]} %")
col_3.metric(f"RMSE :",f"{perfs[1]}")
col_4.metric(f"Temps mis : ",f"{taken_time(start_time,end_time)}")
else:
st.write("Aucune crypto sélectionnée.")
if selected == 'Documentation':
st.title("Documentation")
st.markdown(
"Le Bitcoin (BTC) et l'Ethereum (ETH) étant les deux crypto-monnaies les plus célèbres, nous les avons utilisées comme base pour entrainer nos modèles. Les prédictions sont ensuite faites pour les autres crypto-actifs."
)
st.markdown("----")
st.markdown("## Notre équipe ")
st.markdown("1. DJEOGANG Audrey")
st.markdown("2. OWONA Edouard")
st.markdown("----")
st.markdown("## Notre boite à outils ")
st.markdown(
"**1. API/Web Scraper** : Le scraper CryptoCmd Python a extrait les données de CoinMarketCap."
)
st.markdown("**2. Préparation des données** : Pandas, Numpy")
st.markdown("**3. Visualisation des données** : Matplotlib, Seaborn")
st.markdown("**4. Modélisation des données** : Scikit: Learn, TensorFlow, Keras")
# st.markdown("Database: SQL")
st.markdown("**5. Application web** : Streamlit")
st.markdown("**6. Environnements de travail** : Jupyter Notebook/ Vs Code")
st.markdown("----")
st.markdown("## Algorithmes d'IA utilisé")
st.markdown("Nous avons utilisé les modèles ci-après durant l'expérimentation : ")
st.markdown("1. **Les KNN** : c'est un algorithme ML intéressant que l'on peut utiliser ici est kNN (k voisins les plus proches). Sur la base des variables indépendantes, kNN trouve la similitude entre les nouveaux points de données et les anciens points de données.")
st.markdown("2. **La regression linéaire** : ce modèle est un grand classique en ML et l'un des plus simples à mettre en oeuvre. Le modèle de régression linéaire renvoie une équation qui détermine la relation entre les variables indépendantes et la variable dépendante.")
st.markdown("3. **Le Random Forest** : un autre grand modèle basé sur les arbres de décision qui peut aider à capturer la variabilité dans le cours des valeurs de crypto-actifs.")
st.markdown("4. **Les LSTM** : ils sont largement utilisés pour les problèmes de prédiction de séquences , en l'occurence les séries chronologiques et se sont révélés extrêmement efficaces. La raison pour laquelle ils fonctionnent si bien est que LSTM est capable de stocker des informations passées importantes et d'oublier celles qui ne le sont pas. LSTM a trois portes.")
st.markdown("----")
st.markdown("## Les métriques d'évaluation")
st.markdown("1. **Le R2 du modèle (%)** : qui est le pourcentage de variabilité expliqué par le modèle;")
st.markdown("2. **Le Root Mean Squared Error (RMSE)** : il est une mesure de la précision d'un modèle qui calcule la racine carrée de la moyenne des carrés des écarts entre les valeurs prédites et les valeurs réelles. Un RMSE plus faible indique une meilleure précision du modèle..")
main()