Vous êtes sur la page 1sur 14

Prédiction des Cours du

Bitcoin avec les Modèles de


Markov Cachés

Réalisé par : Hcini Mohamed


Khattat Mouna
Baabaa Nada

Sommaire :
I. Introduction
Contexte et motivation
Objectifs du projet
Aperçu des méthodes utilisées
II. Fondements théoriques
Présentation des modèles de Markov
Introduction aux chaînes de Markov cachées (HMM)
Applications des HMM dans la prédiction des séries temporelles
III. Collecte et prétraitement des données
Sources de données utilisées
Description des données
Nettoyage et prétraitement des données
IV. Modélisation avec HMM
Choix des paramètres du modèle
Formation du modèle HMM
Validation du modèle
V. Implémentation et méthodologie
Description des algorithmes utilisés (Viterbi, Forward-Backward)
Développement du système de prédiction
VI. Résultats
Évaluation de la performance du modèle
Analyse des prédictions par rapport aux données réelles
Limitations et pistes d'amélioration
VII. Conclusion
Résumé des résultats
Retour sur les objectifs du projet
Contributions et implications

I. Introduction
Contexte et Motivation
Le Bitcoin, la première crypto-monnaie décentralisée, a attiré l'attention mondiale en raison de sa
volatilité et de son potentiel de gain élevé. La prédiction des prix du Bitcoin est cruciale pour les
investisseurs et les traders, mais elle est également complexe en raison de la nature volatile du marché.
Dans ce rapport, nous abordons l'utilisation des modèles de Markov cachés (HMM) pour prédire les
mouvements futurs des prix du Bitcoin.
Objectifs du Projet
Ce projet vise à développer un modèle de prédiction des prix du Bitcoin basé sur les HMM. Notre
objectif principal est de créer un modèle robuste capable de capturer les tendances et les modèles dans
les données historiques des prix du Bitcoin et de générer des prédictions précises pour les futurs
mouvements de prix.
Aperçu des Méthodes Utilisées
Nous utiliserons des données historiques des prix du Bitcoin pour entraîner notre modèle HMM. Nous
explorerons les concepts théoriques des HMM et les techniques d'apprentissage automatique associées
pour construire un modèle de prédiction performant. Les algorithmes de Viterbi et de Forward-
Backward seront utilisés pour l'inférence des séquences d'états cachés et l'estimation des paramètres du
modèle.

II. Fondements Théoriques

Présentation des Modèles de Markov

Avant de passer à la description d'un modèle de Markov caché, voyons d'abord ce qu'est un modèle de
Markov.
Le modèle de Markov, aussi appelé Chaîne de Markov, est un modèle statistique composé d'états et de
transitions. Une transition matérialise la possibilité de passer d'un état à un autre.
Dans le modèle de Markov, les transitions sont unidirectionnelles : une transition de l'état A vers état B
ne permet pas d'aller de l'état B vers l'état A. Tous les états ont des transitions vers tous les autres états,
y compris vers eux-mêmes. Chaque transition est associée à sa probabilité d'être empruntée et cette
probabilité peut éventuellement être nulle.
Voici la représentation d'un modèle de Markov simple avec 2 états :
Introduction aux HMM
Les HMM sont une extension des chaînes de Markov dans lesquelles les états réels du système ne sont
pas observables directement. Au lieu de cela, nous observons une séquence d'événements générés par
les états cachés du système. Les HMM sont couramment utilisés pour modéliser des séquences de
données où les états cachés représentent des variables latentes.
Pour comprendre, reprenons le modèle de Markov représenté plus haut et transformons le en modèle
de Markov caché :

Applications des HMM dans la Prédiction des Séries Temporelles


Les HMM ont de nombreuses applications dans la prédiction des séries temporelles, y compris la
prédiction des prix des actifs financiers tels que le Bitcoin. En utilisant les HMM, nous pouvons
modéliser les tendances et les schémas récurrents dans les données de prix pour effectuer des
prédictions précises.
Les algorithmes !
Viterbi :

L'algorithme de Viterbi est une méthode dynamique de programmation utilisée pour


trouver la séquence d'états cachés la plus probable dans un modèle de Markov
caché (HMM), étant donné une séquence d'observations. C'est un algorithme
efficace qui permet de trouver la meilleure séquence d'états en utilisant une
approche itérative.
Séquence d'états la plus probable

Nous avons un HMM dont nous connaissons tous les paramètres (nombre d'états,
nombre d'observations, probabilités de départ, probabilités de transition et
probabilités d'émission) ainsi qu'une séquence d'observations de longeur T. Nous
nous demandons alors quelle était la séquence d'états génératrice. C'est la question
à laquelle nous souhaitons répondre dans le cadre de la reconnaissance vocale.
Cette question n'a pas qu'une seule réponse. Si le HMM étudié ne présente aucune
probabilité d'émission nulle, n'importe quelle séquence d'états de longeur T peut
générer n'importe quelle séquence d'observations de longeur T. Même avec
certaines probabilités d'émission nulles, il reste plusieurs réponses à cette question.
Puisqu'il y a plusieurs séquences d'états possibles pour une séquence d'observations
donnée, nous ne pouvons pas dire avec certitude laquelle a généré nos observations.
En revanche, puisque nous connaissons les paramètres du HMM, nous pouvons
dire quelle est la plus probable.
De façon naïve, nous pourrions encore écrire un algorithme qui parcourt toutes les
séquences d'états possibles en calculant la probabilité d'appartion de la séquence
d'observations, trouvant ainsi la séquence d'états qui a le plus probablement généré
notre séquence d'observations. Le problème est à nouveau la complexité : il y a
NT séquences d'états candidates (N états, T longeur de la séquence d'observations)
et donc une complexité en O(NT).
L'algorithme de Viterbi permet de trouver la solution avec une bien meilleure
complexité : O(N2T).

Étape 1 : Initialisation
L'algorithme commence par initialiser une matrice δ de taille T×N, où T est la longueur de la séquence
d'observations et N est le nombre d'états cachés du HMM. La valeur δ(t,i) représente la probabilité
maximale d'atteindre l'état i à l'instant t en suivant la meilleure séquence d'états jusqu'à cet instant.
Étape 2 : Calcul de la Probabilité Maximale
L'algorithme utilise une approche itérative pour calculer la probabilité maximale d'atteindre chaque
état à chaque instant. À chaque instant t, pour chaque état j, l'algorithme calcule δ(t+1,j), qui
représente la probabilité maximale d'atteindre l'état j à l'instant t+1 en suivant la meilleure séquence
d'états jusqu'à cet instant.

δ(t+1,j)=max1≤i≤N[δ(t,i)⋅aij]⋅bj(Ot+1)

Cette équation calcule la probabilité maximale d'atteindre l'état j à l'instant t+1 en considérant
toutes les transitions possibles de tous les états précédents vers l'état j, et en multipliant cette
probabilité par la probabilité d'observation Ot+1 à partir de l'état j.

Étape 3 : Reconstruction du Chemin Optimal


En parallèle, l'algorithme maintient une matrice Ψ pour conserver les indices des états précédents qui
ont contribué à la probabilité maximale à chaque étape. Cela permet de reconstruire la séquence d'états
cachés la plus probable à la fin de l'algorithme.

Ψ(t+1,j)=argmax1≤i≤N[δ(t,i)⋅aij]

Cette équation détermine l'indice i de l'état précédent qui maximise la probabilité d'atteindre l'état j à
l'instant t+1, ce qui permet de reconstruire la séquence d'états optimale à la fin de l'algorithme.

Étape 4 : Terminaison
Une fois que les probabilités maximales ont été calculées pour tous les instants et tous les états, ainsi
que les indices des états précédents qui ont contribué à ces probabilités, l'algorithme sélectionne le
dernier état avec la probabilité maximale comme point de départ pour reconstruire la séquence d'états
optimale.
Étape 5 : Reconstruire la Séquence d'États Optimale
En utilisant la matrice Ψ, l'algorithme reconstruit la séquence d'états cachés la plus probable en suivant
les indices des états précédents à partir de l'état final sélectionné à l'étape de terminaison jusqu'au
début de la séquence.
Conclusion
L'algorithme de Viterbi fournit une méthode efficace pour trouver la séquence d'états cachés la plus
probable dans un HMM, ce qui est utile dans de nombreux domaines tel que la finance pour modéliser
des séquences de données et effectuer des prédictions.
Implémentation :
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# Charger les données historiques des prix du Bitcoin depuis un fichier CSV
bitcoin_prices = pd.read_csv('historique_prix_bitcoin.csv')

# Supprimer les colonnes non pertinentes et convertir les prix en séries temporelles
bitcoin_prices = bitcoin_prices[['Date', 'Close']]
bitcoin_prices['Date'] = pd.to_datetime(bitcoin_prices['Date'])
bitcoin_prices.set_index('Date', inplace=True)

# Définir les états cachés du HMM (par exemple: bullish, bearish, stable)
states = ['bullish', 'bearish', 'stable']
# Générer des observations (peut être adapté selon votre besoin)
observations = bitcoin_prices['Close'].values

# Initialiser les probabilités de départ, les probabilités de transition et les probabilités d'émission
# Ces probabilités peuvent être initialisées ou estimées à partir des données historiques
start_probability = {'bullish': 0.3, 'bearish': 0.3, 'stable': 0.4}

transition_probability = {
'bullish': {'bullish': 0.7, 'bearish': 0.2, 'stable': 0.1},
'bearish': {'bullish': 0.3, 'bearish': 0.5, 'stable': 0.2},
'stable': {'bullish': 0.3, 'bearish': 0.3, 'stable': 0.4}
}

# Supposons que les probabilités d'émission sont uniformes pour simplifier


emission_probability = {
'bullish': {price: 1/len(observations) for price in observations},
'bearish': {price: 1/len(observations) for price in observations},
'stable': {price: 1/len(observations) for price in observations}
}

# Implémentation de l'algorithme de Viterbi


def viterbi(obs, states, start_p, trans_p, emit_p):
V = [{}]
path = {}
for y in states:
V[0][y] = start_p[y] * emit_p[y][obs[0]]
path[y] = [y]
for t in range(1, len(obs)):
V.append({})
newpath = {}
for cur_state in states:
(prob, state) = max(
[(V[t-1][prev_state] * trans_p[prev_state][cur_state] * emit_p[cur_state][obs[t]], prev_state) for prev_state in states])
V[t][cur_state] = prob
newpath[cur_state] = path[state] + [cur_state]
path = newpath
(prob, state) = max((V[len(obs) - 1][final_state], final_state) for final_state in states)
return prob, path[state]

# Exemple d'utilisation de l'algorithme de Viterbi avec les données historiques des prix du Bitcoin
prob, path = viterbi(observations, states, start_probability, transition_probability, emission_probability)

# Plot des prix du Bitcoin


plt.figure(figsize=(12, 6))
plt.plot(bitcoin_prices.index, bitcoin_prices['Close'], label='Prix du Bitcoin', color='blue')

# Plot du chemin caché prédit par l'algorithme de Viterbi


for i in range(len(path)-1):
start_date = bitcoin_prices.index[i]
end_date = bitcoin_prices.index[i+1]
state = path[i]
color = 'green' if state == 'bullish' else ('red' if state == 'bearish' else 'orange')
plt.axvspan(start_date, end_date, color=color, alpha=0.3)

plt.title('Prix du Bitcoin avec le Chemin Caché (Viterbi)')


plt.xlabel('Date')
plt.ylabel('Prix de Clôture')
plt.legend()
plt.grid(True)
plt.show()
forward-algorithm
Probabilité d'une séquence d'observations

Nous avons un HMM dont nous connaissons tous les paramètres (nombre d'états,
nombre d'observations, probabilités de départ, probabilités de transition et
probabilités d'émission) ainsi qu'une séquence d'observations de longeur T. Nous
nous demandons alors quelle est la probabilité d'apparition de cette séquence. Dans
le cas d'un HMM "entraîné" à reconnaître "quelque chose" (la langue d'un texte, par
exemple), c'est cette question que nous nous posons pour déterminer si "autre
chose" est du même type ou non.

Cette question a une réponse unique. En effet, la probabilité de voir apparaître la


séquence d'observations se trouve en additionnant les probabilités de la voir
apparaître pour chacune des séquences d'états possibles.

De façon naïve, nous pourrions écrire un algorithme qui parcourt toutes les
séquences d'états possibles en calculant la probabilité d'apparition de la séquence
d'observations, puis additionnerait tous les résultats pour trouver la réponse à la
question. Le problème de cet algorithme est qu'il y a NT séquences d'états
candidates (N états, T longeur de la séquence d'observations), ce qui donnerait une
complexité en O(NT). Autant dire incalculable car T est souvent très grand.

Heureusement, le forward-algorithm permet de trouver la solution avec une bien


meilleure complexité : O(N2T).

/////////////////////////////////////////////NNNNAAAAAAAAAAAADDDDAaaaaaaaa/////

L'algorithme de Forward (ou algorithme de forward) est un algorithme utilisé dans


les modèles de Markov cachés (HMM) pour calculer la probabilité d'observation
d'une séquence donnée, étant donné les paramètres du modèle. Voici une
explication de l'algorithme de Forward :

Étape 1 : Initialisation

L'algorithme commence par initialiser une matrice α de taille T×N, où T est la


longueur de la séquence d'observations et N est le nombre d'états cachés du HMM.
La valeur α(t,i) représente la probabilité d'observation partielle jusqu'à l'instant t en
étant dans l'état i.
Étape 2 : Calcul de la Probabilité d'Observation Partielle

L'algorithme utilise une approche itérative pour calculer la probabilité d'observation


partielle à chaque instant. À chaque instant t, pour chaque état j, l'algorithme
calcule α(t+1,j), qui représente la probabilité d'observation partielle jusqu'à l'instant
t+1 en étant dans l'état j.

α(t+1,j)=∑iα(t,i)⋅aij⋅bj(Ot+1)

Cette équation calcule la probabilité d'observation partielle à l'instant t+1 en


considérant toutes les transitions possibles de tous les états précédents vers l'état j,
et en multipliant cette probabilité par la probabilité d'observation Ot+1 à partir de
l'état j.

Étape 3 : Calcul de la Probabilité d'Observation Totale

Une fois que les probabilités d'observation partielle ont été calculées pour tous les
instants, l'algorithme calcule la probabilité d'observation totale en sommant les
probabilités d'observation partielle à l'instant final.

P(O|λ)=∑iα(T,i)

Cette équation donne la probabilité totale d'observation de la séquence donnée étant


donné les paramètres du modèle.

L'algorithme de Forward permet donc de calculer efficacement la probabilité


d'observation d'une séquence donnée dans un modèle de Markov caché, ce qui est
utile dans de nombreux domaines, y compris la reconnaissance de la parole, la
bioinformatique et d'autres applications de modélisation de séquences.

Voici une implémentation simple de l'algorithme de Forward en Python :

import numpy as np

def forward_algorithm(observations, states, start_prob, transition_prob, emission_prob):

T = len(observations)

N = len(states)
# Initialisation de la matrice alpha

alpha = np.zeros((T, N))

# Initialisation de la première colonne de la matrice alpha

for i in range(N):

alpha[0][i] = start_prob[i] * emission_prob[i][observations[0]]

# Calcul des valeurs de la matrice alpha pour les instants suivants

for t in range(1, T):

for j in range(N):

alpha[t][j] = sum(alpha[t-1][i] * transition_prob[i][j] * emission_prob[j][observations[t]] for i in range(N))

# Calcul de la probabilité totale d'observation

prob_observation = sum(alpha[T-1])

return prob_observation, alpha

# Exemple d'utilisation

observations = [1, 0, 1] # Exemple de séquence d'observations

states = [0, 1] # Exemple d'états possibles

start_prob = [0.5, 0.5] # Probabilités de départ

transition_prob = [[0.7, 0.3], [0.4, 0.6]] # Probabilités de transition

emission_prob = [[0.9, 0.1], [0.2, 0.8]] # Probabilités d'émission

# Calcul de la probabilité d'observation et de la matrice alpha

prob_observation, alpha_matrix = forward_algorithm(observations, states, start_prob, transition_prob, emission_prob)

print("Probabilité d'observation totale :", prob_observation)

print("Matrice alpha :\n", alpha_matrix)

```
Cette implémentation de l'algorithme de Forward calcule la probabilité totale
d'observation d'une séquence donnée et génère également la matrice alpha, qui
contient les probabilités d'observation partielle à chaque instant pour chaque état
caché.

Baum-Welch

Maximiser la probabilité d'une séquence d'observations

Nous avons un HMM, dont nous connaissons le nombre d'états N et le nombre


d'observations M, et une séquence d'observations de longeur T. Nous nous
demandons alors quelles sont les matrices S, A et B (respectivement probabilités de
départs, de transitions et d'émissions) qui maximisent la probabilité d'apparition de
notre séquence d'observations. C'est à cette question qu'il nous faut répondre
lorsque nous souhaitons entraîner un HMM à reconnaître "quelque chose".

Cette question a une réponse unique. Il existe bien 3 matrices S, A et B pour


lesquelles la probabilité d'apparition de notre séquence d'observations est
maximale. Malheureusement, si la résolution mathématique de ce problème est déjà
difficile, il n'existe aucun algorithme permettant de le résoudre (à ce jour du
moins). Il existe, par contre, un algorithme permettant d'approcher la solution.

Cet algorithme, appelé algorithme de Baum-Welch, présente cependant le défaut


de ne pas toujours converger vers la même solution, voire même de ne pas
converger du tout sous certaines conditions. Ces problèmes surviennent surtout
losque nous n'avons aucune idée des probabilités du HMM que nous recherchons
(pas même approximative) et que nous commençons donc avec un HMM
quasiment équiprobable (ce qui signifie que les probabilités de départ et de
transition sont toutes égales à ~1/N et les probabilités d'émission à ~1/M).
"Quasiment" équiprobable justement pour minimiser le risque d'échec de
l'algorithme, qui ne converge presque jamais en cas d'équiprobabilité parfaite.

L'idée de l'algorithme est la suivante :


1) Nous initialisons le HMM avec des probabilités presque équivalantes ou des
approximations de ce à quoi nous nous attendons ;
2) Nous réévaluons le HMM par rapport à la séquence d'observations sur
laquelle nous voulons l'entraîner ;
3) Nous calculons la probabilité d'apparition de la séquence d'observations avec
le "nouveau" HMM ;
4) Si la probabilité d'apparition augmente, nous recommencons en 2.
L'algorithme tourne donc jusqu'à ce que la réévaluation fasse baisser la probabilité
d'apparition.

Vous aimerez peut-être aussi