使用特定大小的转移矩阵和给定的种子生成马尔可夫链模拟,使用 mchmm 库

generating a Markov chain simulation using a transition matrix of specific size and with a given seed, using the mchmm library

我正在尝试使用用 scipy 和 numpy 编码的 mchmm 库,使用特定序列作为开始来生成马尔可夫模拟。我不确定我是否正确使用它,因为该库在我不熟悉的马尔可夫上下文中也有 Viterbi 和 Baum-Welch 算法。

为了说明,我将继续举个例子。

data = 'AABCABCBAAAACBCBACBABCABCBACBACBABABCBACBBCBBCBCBCBACBABABCBCBAAACABABCBBCBCBCBCBCBAABCBBCBCBCCCBABCBCBBABCBABCABCCABABCBABC'
a = mc.MarkovChain().from_data(data)

我想要一个基于 3 状态转移矩阵的马尔可夫模拟,从上面序列中的最后 3 个字符开始 ("ABC")

start_sequence = data[-3:]
tfm3 = a.n_order_matrix(a.observed_p_matrix, order=3) #this is because  I want an order 3 transition matrix
ids, states = a.simulate(n=10, tf=tfm3, start=start_sequence)

这个returns:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/tmp/ipykernel_2552615/2308700615.py in <module>
----> 1 ids, states = a.simulate(n=10, tf=tfm3, start=start_sequence)

~/anaconda3/lib/python3.8/site-packages/mchmm/_mc.py in simulate(self, n, tf, states, start, ret, seed)
    304             _start = np.random.randint(0, len(states))
    305         elif isinstance(start, str):
--> 306             _start = np.argwhere(states == start).item()
    307 
    308         # simulated sequence init

ValueError: can only convert an array of size 1 to a Python scalar

我期望得到一个由 10 个字符组成的序列,从字符串 'ABC' (data[-3:]) 开始,因为我想限制马尔可夫模拟以它隐含的概率开始特定序列,并遵循 3 阶马尔可夫。

有什么反馈吗?

MarkovChain实例a中的状态是'A''B''C'。当 simulate 方法被赋予 state 的字符串时,它期望它是状态之一的名称,即 'A''B''C'.您收到该错误是因为 data[-3:] 不是其中一个州。

例如,下面我在 simulate() 的调用中使用 start='A',它会生成一个包含 10 个状态的序列,从 'A':

开始
In [26]: data = 'AABCABCBAAAACBCBACBABCABCBACBACBABABCBACBBCBBCBCBCBACBABABCBCBA
    ...: AACABABCBBCBCBCBCBCBAABCBBCBCBCCCBABCBCBBABCBABCABCCABABCBABC'

In [27]: a = mc.MarkovChain().from_data(data)

In [28]: tfm3 = a.n_order_matrix(a.observed_p_matrix, order=3)

In [29]: ids, states = a.simulate(n=10, tf=tfm3, start='A')

In [30]: states
Out[30]: array(['A', 'C', 'A', 'C', 'C', 'C', 'A', 'A', 'C', 'B'], dtype='<U1')

如果您尝试创建一个马尔可夫链,其中状态是三个符号的序列(以添加包含前两个状态的“历史”),您可以为 .from_data() 创建一个新输入,其中包含data 的长度为 3 的重叠子序列(也称为 3-grams)。例如,

In [65]: data3 = [data[k:k+3] for k in range(len(data)-2)]

In [66]: data3[:4]
Out[66]: ['AAB', 'ABC', 'BCA', 'CAB']

In [67]: data3[-8:]
Out[67]: ['CAB', 'ABA', 'BAB', 'ABC', 'BCB', 'CBA', 'BAB', 'ABC']

In [68]: a = mc.MarkovChain().from_data(data3)

看看这个马尔可夫链的状态:

In [69]: a.states
Out[69]: 
array(['AAA', 'AAB', 'AAC', 'ABA', 'ABC', 'ACA', 'ACB', 'BAA', 'BAB',
       'BAC', 'BBA', 'BBC', 'BCA', 'BCB', 'BCC', 'CAB', 'CBA', 'CBB',
       'CBC', 'CCA', 'CCB', 'CCC'], dtype='<U3')

模拟 10 个转换,从 data3 中的最后一个状态开始:

In [70]: ids, states = a.simulate(n=10, start=data3[-1])

In [71]: states
Out[71]: 
array(['ABC', 'BCA', 'CAB', 'ABC', 'BCB', 'CBC', 'BCB', 'CBA', 'BAA',
       'AAB'], dtype='<U3')

压缩状态以仅包含最后一个字符,因此它以原始 data 输入的形式返回:

In [72]: ''.join([state[-1] for state in states])
Out[72]: 'CABCBCBAAB'