Fare previsioni con i modelli di Markov

Fare previsioni con i modelli di Markov

Condividi con i tuoi amici...

Le catene di Markov sono un tipo di modello statistico che permette di fare previsioni sul futuro sulla base di ciò che sappiamo del presente.

Ma è davvero possibile fare previsioni accurate del domani senza considerare l’intero passato?

Possiamo davvero essere sicuri che il futuro dipenderà solo dal presente, ignorando ciò che è accaduto in passato? Quali sono le implicazioni di questo presupposto? E se il passato influisse sul futuro in modo imprevedibile?

Le ipotesi su cui si basano i modelli previsionali di Markov semplificano notevolmente un sistema complesso che tiene conto di tutto il passato. Ad esempio, si assume che il futuro dipenda solo dallo stato presente e non da altri fattori come la storia del sistema o l’influenza di eventi esterni.

Il modello di Markov è un modello semplice che può essere facilmente compreso e utilizzato anche da coloro che non hanno una forte formazione matematica o statistica. Grazie alla sua semplicità, il modello può essere elaborato e utilizzato in tempo reale, il che lo rende utile in situazioni in cui è necessario prendere decisioni rapide.

A volte, ciò che è accaduto in passato può creare rumore e rendere difficile fare previsioni accurate. Utilizzando un modello di Markov, si può ridurre il rumore ignorando la maggior parte della storia del sistema e concentrarsi solo sullo stato attuale. I modelli di Markov possono essere utilizzati anche quando non si dispone di informazioni complete sulle variabili del sistema. In altre parole, si possono fare previsioni sulla base delle informazioni disponibili, senza dover prevedere tutte le possibili variabili e le loro interazioni.

Quali sono i limiti?

I modelli di Markov presuppongono che il presente contenga tutte le informazioni necessarie per fare previsioni accurate sul futuro, ma questo non è sempre il caso. Ad esempio, se ci sono informazioni importanti che non siamo in grado di rilevare o di misurare, il modello di Markov potrebbe non essere in grado di fare previsioni precise.

In sintesi, sebbene le catene di Markov siano uno strumento utile per fare previsioni, è importante tener conto dei loro limiti e delle ipotesi semplificative su cui si basano per evitare di trarre conclusioni errate o poco affidabili.

Quando i sistemi di AI impiegano i modelli di Markov

Gli algoritmi di intelligenza artificiale spesso utilizzano i Modelli di Markov per prevedere la prossima azione o lo stato futuro sulla base dell’osservazione degli eventi passati. Ad esempio, il riconoscimento del linguaggio naturale e la traduzione automatica utilizzano spesso i modelli di Markov per prevedere la parola o la frase successiva in base al contesto attuale.

Inoltre, i Modelli di Markov sono utilizzati anche in altre aree dell’intelligenza artificiale, come il riconoscimento dei pattern e il controllo del processo decisionale. Nella modellizzazione del riconoscimento dei pattern, i modelli di Markov possono essere utilizzati per prevedere la prossima transizione in un insieme di dati in base alle precedenti transizioni. Nella modellizzazione del controllo del processo decisionale, i modelli di Markov possono essere utilizzati per prevedere le azioni future di un agente intelligente in base al suo stato attuale.

Le catene di Markov: un po’ di matematica

Questi modelli rappresentano matematicamente il processo stocastico costituito dalla catene di Markov

Una catena di Markov è appunto un processo stocastico che descrive come un sistema cambia di stato nel tempo. In una catena di Markov, il sistema attraversa una sequenza di stati discreti, dove ogni stato dipende solo dallo stato precedente e non da tutti gli stati precedenti. Questa proprietà di dipendenza dallo stato precedente è chiamata proprietà di Markov.

In una catena di Markov, la probabilità di transizione da uno stato a un altro è descritta dalla matrice di transizione, dove ogni elemento Pi,j rappresenta la probabilità di transizione dallo stato i allo stato j. La matrice di transizione soddisfa la condizione di somma unitaria, ovvero che la somma delle probabilità di transizione da uno stato a tutti gli altri stati sia uguale a 1.

Una catena di Markov può essere utilizzata per modellizzare una vasta gamma di fenomeni dinamici, come il traffico stradale, le scelte di acquisto dei consumatori, le fluttuazioni di prezzo delle azioni, il comportamento del sistema meteorologico, ecc. Questi modelli possono essere utilizzati per prevedere il comportamento futuro del sistema sulla base dello stato corrente, e per analizzare l’effetto di diverse politiche o decisioni sul comportamento del sistema.

Un modello di Markov può essere rappresentato matematicamente da una sequenza di stati S1, S2, S3, …, Sn in cui ogni stato è associato ad una probabilità di transizione Pi,j che descrive la probabilità di passare dallo stato Si allo stato Sj.

La probabilità di transizione soddisfa la seguente proprietà di Markov:

P(Sn+1 = j | S1 = i1, S2 = i2, …, Sn = in) = P(Sn+1= j | Sn = in) = Pin,j

Questo significa che la probabilità di transizione dallo stato in allo stato j dipende solo dallo stato corrente in e non dagli stati precedenti i1, i2, …, in-1.

Si ricorda che in generale l’espressione P(A|B) indica un probabilità condizionata: la probabilità che si verifichi l’evento A a condizione che si sia già verificato l’evento B.

Il modello di Markov assume che le probabilità di transizione siano stazionarie, ovvero che non dipendano dal tempo o dallo stato precedente. Questo significa che la probabilità di transizione dallo stato i allo stato j rimane costante nel tempo.

Per utilizzare il modello di Markov per prevedere lo stato futuro, è necessario definire la distribuzione iniziale degli stati, ovvero la probabilità che il processo inizi in uno stato specifico.

In sintesi, un modello di Markov è definito:

dalla sequenza degli stati,

dalle probabilità di transizione tra gli stati e

dalla distribuzione iniziale degli stati.

Queste informazioni vengono utilizzate per prevedere la probabilità di transizione tra gli stati futuri, sulla base dello stato corrente.

Un esempio: le previsioni del tempo

Supponiamo di voler creare un algoritmo per prevedere il tempo in una determinata città. Utilizzeremo una catena di Markov per descrivere come il tempo cambia di stato nel tempo. Supponiamo che ci siano tre possibili stati del tempo: “soleggiato”, “nuvoloso” e “piovoso”.

Possiamo rappresentare questi tre stati con un vettore di stato: S = [s1, s2, s3], dove s1 rappresenta lo stato “soleggiato”, s2 rappresenta lo stato “nuvoloso” e s3 rappresenta lo stato “piovoso”.

La matrice di transizione P descrive la probabilità di transizione da uno stato a un altro. Supponiamo che le probabilità di transizione siano le seguenti:

[[0.7, 0.2, 0.1], [0.4, 0.4, 0.2], [0.2, 0.3, 0.5]]

Questo significa che la probabilità di passare dallo stato “soleggiato” al “soleggiato” al prossimo passo di tempo è del 70%, mentre la probabilità di passare dallo stato “soleggiato” al “nuvoloso” è del 20% e la probabilità di passare dallo stato “soleggiato” al “piovoso” è del 10%. E così via per gli altri stati.

Moltiplicando il vettore di stato iniziale per la matrice P si ottiene un vettore che mostra le tre probabilità di transizione tra lo stato iniziale e i tre possibili stati futuri.

[1, 0, 0] x [[0.7, 0.2, 0.1], [0.4, 0.4, 0.2], [0.2, 0.3, 0.5]] = [0.7, 0.2, 0.1]

Ricordiamo che la moltiplicazione tra un vettore riga di dimensione 3 e una matrice 3×3 si esegue nel seguente modo:

[a,b,c] x [[[p11, p12, p13], [p21, p22, p23], [p31, p32, p33]] =

= [a x p11+b x p21 + c x p31, a x p12+b x p22 + c x p32, a x p13+b x p23+ c x p33 ]

Traduciamo l’esempio in un codice Python

Ecco un codice Python che genera la previsione:

import numpy as np

# Definizione della matrice di transizione del modello di Markov
P = np.array([[0.7, 0.2, 0.1], [0.4, 0.4, 0.2], [0.2, 0.3, 0.5]])

# Definizione del vettore di stato iniziale
s = np.array([1, 0, 0]) # corrisponde allo stato "soleggiato"

# Simulazione delle previsioni per 5 passi di tempo
n = 5
for i in range(n):
    print("Passo di tempo", i+1, ":")
    print("Stato attuale:", s)
    s = np.dot(s, P) # calcolo del nuovo stato utilizzando la matrice di transizione
    print("Probabilità predetta per il prossimo stato:")
    print("Soleggiato:", s[0])
    print("Nuvoloso:", s[1])
    print("Piovoso:", s[2])
    print("\n")

In questo esempio, abbiamo definito una matrice di transizione P: [[0.7, 0.2, 0.1], [0.4, 0.4, 0.2], [0.2, 0.3, 0.5]] che rappresenta la probabilità di transizione tra i tre possibili stati del tempo. Abbiamo inoltre definito un vettore di stato iniziale s: [1, 0, 0] che rappresenta lo stato attuale del sistema (in questo caso, abbiamo scelto lo stato “soleggiato” come stato iniziale).

Nel ciclo for, abbiamo simulato le previsioni per 5 passi di tempo. Ad ogni passo di tempo, abbiamo calcolato il nuovo vettore di stato utilizzando la matrice di transizione P e il vettore di stato attuale s. Successivamente, abbiamo stampato il vettore di stato attuale e la distribuzione di probabilità prevista per il prossimo stato del tempo.

I giorni successivi

L’istruzione s = np.dot(s, P) esegue la moltiplicazione tra un vettore di stato s e una matrice di transizione P. Questa operazione ha lo scopo di calcolare la distribuzione di probabilità dei vari stati della catena di Markov al passo successivo.

In particolare, il vettore s in generale rappresenta la distribuzione di probabilità dei vari stati al passo attuale, mentre la matrice P rappresenta la distribuzione di probabilità dei vari stati al passo successivo, data la distribuzione di probabilità al passo attuale. La moltiplicazione tra il vettore di stato s e la matrice di transizione P produce un nuovo vettore di stato che rappresenta la distribuzione di probabilità dei vari stati al passo successivo.

Ad esempio, se abbiamo un vettore di stato s che rappresenta la distribuzione di probabilità dei vari stati al passo attuale, come [0.4, 0.2, 0.4], e una matrice di transizione P, come

[[0.7, 0.2, 0.1], [0.4, 0.4, 0.2], [0.2, 0.3, 0.5]]

la moltiplicazione tra il vettore s e la matrice P produrrà un nuovo vettore di stato che rappresenta la distribuzione di probabilità dei vari stati al passo successivo. Il nuovo vettore di stato sarà calcolato come segue:

s’ = s x P = [0.4, 0.2, 0.4] x [[0.7, 0.2, 0.1], [0.4, 0.4, 0.2], [0.2, 0.3, 0.5]] = [0.58, 0.29, 0.13]

Il nuovo vettore s’ rappresenta la distribuzione di probabilità dei vari stati al passo successivo, dove lo stato “soleggiato” ha una probabilità del 58%, lo stato “nuvoloso” ha una probabilità del 29% e lo stato “piovoso” ha una probabilità del 13%.

Prevedere il traffico urbano

Per utilizzare il modello di Markov per prevedere il traffico stradale, dobbiamo definire un insieme di possibili stati del sistema e una matrice di transizione che rappresenta la probabilità di transizione tra gli stati. Ad esempio, potremmo definire tre stati possibili per il traffico stradale: “nessun traffico”, “traffico moderato” e “traffico intenso“.

Ogni stato rappresenta un livello diverso di congestione del traffico. La matrice di transizione rappresenta la probabilità di transizione tra gli stati a ogni passo di tempo, in base alle condizioni del traffico correnti e passate.

Una volta definiti gli stati e la matrice di transizione, possiamo utilizzare il modello di Markov per prevedere il traffico stradale futuro. Ad esempio, possiamo utilizzare la seguente procedura:

  • Definire gli stati possibili del traffico: “nessun traffico”, “traffico moderato” e “traffico intenso”.
  • Raccogliere i dati storici del traffico stradale, ad esempio la densità del traffico in diverse ore del giorno o in diverse condizioni atmosferiche. Utilizzando questi dati, possiamo calcolare la matrice di transizione del modello di Markov.
  • Definire il vettore di stato iniziale, ovvero lo stato corrente del traffico.
  • Utilizzare la matrice di transizione e il vettore di stato iniziale per fare previsioni sul traffico stradale futuro.
  • Verificare e valutare la precisione delle previsioni effettuate, utilizzando i dati storici o le osservazioni future.

In questo modo, possiamo utilizzare il modello di Markov per prevedere il traffico stradale futuro in base alle condizioni correnti e passate. Naturalmente, la precisione delle previsioni dipenderà dalla qualità dei dati storici utilizzati e dalla capacità del modello di Markov di catturare le dinamiche complesse del traffico stradale.

Incorporare nel modello altri fattori

L’orario e le condizioni atmosferiche possono influenzare il traffico stradale e quindi la matrice di transizione del modello di Markov. Ad esempio, potremmo aspettarci che il traffico stradale sia più intenso durante le ore di punta, come ad esempio durante l’ora di pranzo o la fine della giornata lavorativa. Inoltre, le condizioni atmosferiche come la pioggia o la neve possono aumentare la congestione del traffico e quindi influenzare la probabilità di transizione tra gli stati.

Per incorporare questi fattori nel modello di Markov, potremmo considerare le ore del giorno e le condizioni atmosferiche come variabili di ingresso aggiuntive. Possiamo utilizzare questi dati per modificare la matrice di transizione in modo dinamico in base alle condizioni correnti. Ad esempio, potremmo utilizzare una matrice di transizione differente durante le ore di punta rispetto alle ore non di punta, o una matrice di transizione differente in caso di condizioni atmosferiche avverse rispetto a quelle normali.

Inoltre, potremmo utilizzare tecniche di apprendimento automatico per identificare le relazioni tra i fattori di ingresso (come l’orario e le condizioni atmosferiche) e il traffico stradale, e utilizzare queste relazioni per modificare la matrice di transizione in modo più preciso e dinamico. In questo modo, il modello di Markov potrebbe adattarsi meglio alle condizioni del traffico stradale corrente e produrre previsioni più accurate.

Impieghiamo il modello di regressione multilineare per correggere la matrice di transizione

Il modello di regressione multilineare è stato spiegato in questo articolo

Ecco un esempio di codice Python che corregge la matrice P:

import numpy as np
from sklearn.linear_model import LinearRegression

# Definizione degli stati possibili del traffico
states = ["nessun traffico", "traffico moderato", "traffico intenso"]
n_states = len(states)

# Definizione della matrice di transizione iniziale
P = np.array([[0.7, 0.2, 0.1], [0.4, 0.4, 0.2], [0.2, 0.3, 0.5]])

# Definizione dei dati storici del traffico (ora, condizioni atmosferiche, densità del traffico, stato successivo)
data = np.array([
    [8, "soleggiato", 0.2, 1],
    [9, "soleggiato", 0.3, 1],
    [10, "nuvoloso", 0.5, 2],
    [11, "pioggia", 0.8, 3],
    [12, "pioggia", 0.9, 3],
    [13, "pioggia", 0.8, 3],
    [14, "nuvoloso", 0.6, 2],
    [15, "soleggiato", 0.4, 1],
    [16, "soleggiato", 0.3, 1],
    [17, "soleggiato", 0.2, 1],
    [18, "nuvoloso", 0.5, 2],
    [19, "pioggia", 0.7, 3],
    [20, "pioggia", 0.8, 3],
    [21, "nuvoloso", 0.6, 2],
    [22, "soleggiato", 0.3, 1],
    [23, "soleggiato", 0.2, 1],
    [0, "nuvoloso", 0.4, 2],
    [1, "pioggia", 0.7, 3],
    [2, "pioggia", 0.9, 3],
    [3, "pioggia", 0.8, 3],
    [4, "nuvoloso", 0.6, 2],
    [5, "soleggiato", 0.3, 1],
    [6, "soleggiato", 0.2, 1],
    [7, "soleggiato", 0.3, 1],
])

# Estrazione delle variabili di ingresso (ora, condizioni atmosferiche, densità del traffico)
X = np.zeros((len(data), 4))
for i, row in enumerate(data):
    X[i, 0] = row[0] # ora
    X[i, 1] = 1 if row[1] == "soleggiato" else 0 # condizioni atmosferiche: soleggiato
    X[i, 2] = 1 if row[1] == "nuvoloso" else 0 # condizioni atmosferiche: nuvoloso
    X[i, 3] = 1 if row[1] == "pioggia" else 0 # condizioni atmosferiche: pioggia

# Estrazione delle variabili di output (stato

y = data[:, 3]
#Addestramento del modello di regressione lineare

model = LinearRegression()
model.fit(X, y)
#Calcolo della matrice di transizione corretta

P_corrected = np.zeros((n_states, n_states))
for i in range(n_states):
for j in range(n_states):
# Estrazione delle variabili di ingresso corrispondenti alla transizione i -> j
input_data = []
for k, row in enumerate(data[:-1]):
if row[3] == i and data[k+1][3] == j:
input_data.append(X[k])


    # Calcolo della probabilità corretta di transizione i -> j tramite il modello di regressione lineare
    if len(input_data) > 0:
        input_data = np.array(input_data)
        prob = model.predict(input_data).mean()
    else:
        prob = P[i, j]
    
    P_corrected[i, j] = prob

#Stampa della matrice di transizione corretta

print("Matrice di transizione corretta:")
print(P_corrected)

In questo codice, abbiamo prima definito la matrice di transizione iniziale P e l’insieme di stati possibili stati. Poi, abbiamo definito un insieme di dati storici del traffico che include l’ora del giorno, le condizioni atmosferiche e la densità del traffico, nonché lo stato successivo del traffico. Successivamente, abbiamo estratto le variabili di ingresso e di output dai dati storici e addestrato un modello di regressione lineare utilizzando l’ora del giorno, le condizioni atmosferiche e la densità del traffico come variabili di ingresso e lo stato successivo del traffico come variabile di output.

Infine, abbiamo utilizzato il modello di regressione lineare per calcolare la matrice di transizione corretta P_corrected in base ai dati storici del traffico. In particolare, abbiamo utilizzato il modello per predire la probabilità di transizione tra gli stati in base all’ora del giorno, alle condizioni atmosferiche e alla densità del traffico correnti. Se non è stato possibile trovare dati storici relativi a una transizione specifica, abbiamo utilizzato la matrice di transizione iniziale P per quella transizione. Infine, abbiamo stampato la matrice di transizione corretta a video.