2017-10-10 18 views
0

Imagine j'ai une série de 4 états possibles markoviens (A, B, C, D):matrice de transition de Markov Generating dans le python

X = [A, B, B, C, B, A, D, D, A, B, A, D, ....] 

Comment générer une matrice de transformation de Markov utilisant Python? La matrice doit être 4 par 4, montrant la probabilité de passer de chaque état aux 3 autres états. J'ai regardé de nombreux exemples en ligne mais dans chacun d'entre eux, la matrice est donnée, pas calculée sur la base de données. J'ai aussi regardé dans hmmlearn mais nulle part j'ai lu sur la façon de le faire cracher la matrice de transition. Y a-t-il une bibliothèque que je peux utiliser à cette fin?

Voici un code R pour la chose exacte que je suis en train de le faire en Python: https://stats.stackexchange.com/questions/26722/calculate-transition-matrix-markov-in-r

+0

En Python brut, vous devez utiliser une liste de listes. Ce genre de chose est plus naturellement fait dans 'numpy' ou' pandas'. Si vous souhaitez utiliser l'un de ces outils, vous pouvez peut-être ajouter le tag approprié. Dans tous les cas, quelle est l'entrée de votre problème? Une liste finie d'états? –

Répondre

4

Cela pourrait vous donner quelques idées:

transitions = ['A', 'B', 'B', 'C', 'B', 'A', 'D', 'D', 'A', 'B', 'A', 'D'] 

def rank(c): 
    return ord(c) - ord('A') 

T = [rank(c) for c in transitions] 

#create matrix of zeros 

M = [[0]*4 for _ in range(4)] 

for (i,j) in zip(T,T[1:]): 
    M[i][j] += 1 

#now convert to probabilities: 
for row in M: 
    n = sum(row) 
    if n > 0: 
     row[:] = [f/sum(row) for f in row] 

#print M: 

for row in M: 
    print(row) 

sortie:

[0.0, 0.5, 0.0, 0.5] 
[0.5, 0.25, 0.25, 0.0] 
[0.0, 1.0, 0.0, 0.0] 
[0.5, 0.0, 0.0, 0.5] 

Sur Editer Voici une fonction qui implémente les idées ci-dessus:

#the following code takes a list such as 
#[1,1,2,6,8,5,5,7,8,8,1,1,4,5,5,0,0,0,1,1,4,4,5,1,3,3,4,5,4,1,1] 
#with states labeled as successive integers starting with 0 
#and returns a transition matrix, M, 
#where M[i][j] is the probability of transitioning from i to j 

def transition_matrix(transitions): 
    n = 1+ max(transitions) #number of states 

    M = [[0]*n for _ in range(n)] 

    for (i,j) in zip(transitions,transitions[1:]): 
     M[i][j] += 1 

    #now convert to probabilities: 
    for row in M: 
     s = sum(row) 
     if s > 0: 
      row[:] = [f/s for f in row] 
    return M 

#test: 

t = [1,1,2,6,8,5,5,7,8,8,1,1,4,5,5,0,0,0,1,1,4,4,5,1,3,3,4,5,4,1,1] 
m = transition_matrix(t) 
for row in m: print(' '.join('{0:.2f}'.format(x) for x in row)) 

Sortie:

0.67 0.33 0.00 0.00 0.00 0.00 0.00 0.00 0.00 
0.00 0.50 0.12 0.12 0.25 0.00 0.00 0.00 0.00 
0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 
0.00 0.00 0.00 0.50 0.50 0.00 0.00 0.00 0.00 
0.00 0.20 0.00 0.00 0.20 0.60 0.00 0.00 0.00 
0.17 0.17 0.00 0.00 0.17 0.33 0.00 0.17 0.00 
0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 
0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 
0.00 0.33 0.00 0.00 0.00 0.33 0.00 0.00 0.33 
+0

Merci, John. La seule chose est que la matrice de transition résultant de votre code n'est pas exactement la matrice de transition de Markov. Votre code divise les cellules de ligne par n = 11. Y at-il de toute façon, vous pouvez facilement corriger le code pour donner la table dans la capture d'écran que j'ai ajouté à la section ** "mise à jour" ** de la question? – st19297

+1

@ st19297 Je viens de remplacer le 'n' global par un' n' spécifique à la ligne (rendant les entrées probabilistes conditionnelles). Comme je n'aime pas diviser par 0, le code ci-dessus laisse inchangée une rangée de zéros. Il est impossible d'estimer les probabilités de transition à partir d'un état donné lorsqu'aucune transition de cet état n'a été observée. –