首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Python中生成马尔可夫转移矩阵

在Python中生成马尔可夫转移矩阵
EN

Stack Overflow用户
提问于 2017-10-10 09:12:27
回答 3查看 31.2K关注 0票数 22

假设我有一系列4种可能的马尔可夫状态(A,B,C,D):

代码语言:javascript
运行
复制
X = [A, B, B, C, B, A, D, D, A, B, A, D, ....]

如何使用Python生成马尔可夫变换矩阵?矩阵必须是4x4,表示从每个状态转移到其他3个状态的概率。我已经在网上看了很多例子,但在所有的例子中,矩阵都是给定的,而不是基于数据计算的。我也研究了hmmlearn,但我没有读到如何让它输出转换矩阵的内容。有没有可供我使用的库?

下面是我在Python中尝试做的事情的R代码:https://stats.stackexchange.com/questions/26722/calculate-transition-matrix-markov-in-r

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-10-10 09:51:06

这可能会给你一些想法:

代码语言:javascript
运行
复制
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)

输出:

代码语言:javascript
运行
复制
[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]

编辑上的这里是一个实现上述思想的函数:

代码语言:javascript
运行
复制
#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))

输出:

代码语言:javascript
运行
复制
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
票数 29
EN

Stack Overflow用户

发布于 2020-09-29 19:09:03

如果您想在pandas中完成所有这些工作,这里有一种适用于非数字数据的方法:

代码语言:javascript
运行
复制
import pandas as pd
transitions = ['A', 'B', 'B', 'C', 'B', 'A', 'D', 'D', 'A', 'B', 'A', 'D']

df = pd.DataFrame(transitions)

# create a new column with data shifted one space
df['shift'] = df[0].shift(-1)

# add a count column (for group by function)
df['count'] = 1

# groupby and then unstack, fill the zeros
trans_mat = df.groupby([0, 'shift']).count().unstack().fillna(0)

# normalise by occurences and save values to get transition matrix
trans_mat = trans_mat.div(trans_mat.sum(axis=1), axis=0).values

它比纯python方法慢,但为了灵活性和避免创建自己的函数,它可能是值得的。

票数 6
EN

Stack Overflow用户

发布于 2021-07-06 18:11:45

下面的代码提供了另一个关于马尔可夫转移矩阵1阶的解决方案。您的数据可以是整数列表、字符串列表或字符串。负面的想法是,这个解决方案-most可能-需要时间和内存。

为了将马尔可夫转移矩阵训练成数据集,

  1. 创建了一个1阶(bigrams)
  2. generates 1000整数的马尔可夫转移矩阵。
  3. 训练马尔可夫转移矩阵

到现在为止,我们已经有了问题的解决方案。下面的代码尝试解决另一个问题。具体地,根据训练好的马尔可夫任务生成数据。

马尔可夫转移矩阵到累积量的算术

  • 变换概率(算术coding)

  • generating 30 data

代码语言:javascript
运行
复制
import pandas as pd

def transition_matrix_order1(data):
    alphabet = []
    for element in data:
        if element not in alphabet:
            alphabet.append(element)
    alphabet.sort()
    
    previous = data[0]
    matrix = pd.DataFrame(0.0, index=alphabet, columns=alphabet)
    
    for i in data[1:]:
        matrix[i][previous]    += 1.0
        previous = i
    
    total = matrix.sum()
    for element in alphabet:
        matrix[element] = matrix.div(total[element])[element]
    
    return matrix, alphabet



#create data using random integers========
import random
data = [random.randint(1,5) for i in range(1000)] #You can also put list of strings or a string as input data



#create markov transition matrix order 1 (bigram)
markov_matrix, alphabet = transition_matrix_order1(data)



#=the following code uses the probabilities in order to create new data.=



#transform probabilities of markov transition matrix to cumulative
for column in alphabet:
    for pos, index in enumerate(alphabet[1:]):
        markov_matrix[column][index] += markov_matrix[column][alphabet[pos]]




#generating 30 data
generated_data = []
feed = random.choice(alphabet)
generated_data.append(feed)
for i in range(30):
    random_value = random.uniform(0, 1)
    for i in alphabet:
        if markov_matrix[feed][i] >= random_value:
            generated_data.append(i)
            feed = i
            break



print(generated_data)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46657221

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档