通过一次读取多个线来创建马尔可夫链

时间:2017-07-11 22:39:48

标签: python pandas dictionary bayesian markov-chains

我想从给定的数据生成Markov Chain

我想要解决的是PG的第一个字符串是M vs. S type。很明显,字符串A-G-T-T-C-A-G-T-G-T-A显然是M type(一般观察),但我想准备一个马尔可夫模型来测试这个问题。

不是直接提供transition probability matrix for M vs. S,而是我必须随时计算。因此,我必须为所有列的每个观察序列(按块)制作markov chain

问题1:与基于文本相同行生成链的大多数情况不同,我必须根据文本的两个不同行生成MC

block    PG    M1  M2  M3  M4  S1  S2  S3  S4
15       A|T   A   A   C   G   T   T   C   T
15       G|C   G   G   G   C   C   C   G   A
15       T|A   T   C   T   T   A   A   C   A
15       T|C   T   T   T   A   C   C   G   C
15       C|G   C   A   C   A   G   G   T   G
15       A|C   A   A   A   C   C   C   G   C
15       G|T   G   C   G   C   T   T   G   T
17       T|G   T   T   A   T   G   C   G   C
17       G|A   G   G   G   C   A   A   A   C
17       T|C   C   T   T   C   C   C   G   T
17       A|T   A   A   A   C   T   T   T   A

假设我想创建一个first order markov chain来解决PG的第一个字符串是否为M type vs. S type

我准备first order markov chain为:

Note: the opening states and closing states in each chain are repeated it self.


block    PG        M1    M2    M3    M4    S1    S2    S3    S4
15       AgA|TgT   AgA   AgA   CgC   GgG   TgT   TgT   CgC   TgT # opening state (repeated itself)
15       GgA|CgT   GgA   GgA   GgC   CgG   CgT   CgT   GgC   AgT
15       TgG|AgC   TgG   CgG   TgG   TgC   AgC   AgC   CgG   AgA
15       TgT|CgA   TgT   TgC   TgT   AgT   CgA   CgA   GgC   CgA
15       CgT|GgC   CgT   AgT   CgT   AgA   GgC   GgC   TgG   GgC
15       AgC|CgG   AgC   AgA   AgC   CgA   CgG   CgG   GgT   CgG
15       GgA|TgC   GgA   CgA   GgA   CgC   TgC   TgC   GgG   TgC
15       GgG|TgT   GgG   CgC   GgG   CgC   TgT   TgT   GgG   TgT
# this last one was closing state so repeating the transition for it's own state

# new opening transition state for another block 17
17       TgT|GgG   TgT   TgT   AgA   TgT   GgT   CgC   GgG   CgC
17       GgT|AgG   GgT   GgT   GgA   CgT   AgG   AgC   AgG   CgC
17       TgG|CgA   CgG   TgG   TgG   CgC   CgA   CgA   GgA   TgC
17       AgT|TgC   AgC   AgT   AgT   CgC   TgC   TgC   TgG   AgT
17       AgA|TgT   AgA   AgA   AgA   CgC   TgT   TgT   TgT   AgA
# the last line is closing state for another block 17

问题02:但是,如果我想second state markov chain,我会按原样重复打开和关闭状态,但现在不是从相邻行准备链,而是准备其他{{} 1}}使用第1行第3行,第2行第4行,第3行第5行。依此类推。

我尝试使用这里提供的几个马尔可夫模块https://pypi.python.org/pypi?:action=search&term=markov,但看起来没有一个对我想做的事情有用(或者我可能无法弄清楚)。我认为它很容易准备我自己的功能。

任何人都可以分享一些想法或帮助解决这个问题吗?

2 个答案:

答案 0 :(得分:1)

我还没有充分了解这些库,以确保其中一个不会更有帮助,但第二个状态不需要处理多行查找的尴尬。

一旦有了一阶Markov链,那个表中的相邻线就会告诉你原始矩阵中的3行信息。您需要做的就是用一组类似的for循环解析它。

例如,查看第一个订单的“PG”列的前3行,我们得到:

AgA
GgA
TgG

前两行告诉您AgA是以A开头的起始行,第二行是G。这为您提供了第一个二阶开始:GgAgA。然后第2行和第3行会告诉您原始表中的第1-3行,因此您可以使用它们将第二个订单表的第二行放在一起:TgGgA。完成此过程后,您应该能够构建第二个订单表而不会过多地更改第一个订单代码(如果需要,甚至可以更高的订单)。

希望有所帮助!

修改:第一顺序链

首先将第一个订单链放在一起,您可能希望使用一些for循环,将结果存储在列表中,或者更高效的数据类(如集合)。现在,我将使用列表,因为它们使用简单明了。

首先,如果您正在使用数百万行,请注意您存储的每一件事。注意找到正确的数据结构,不包括任何额外的信息(如每个字符之间的“g”)是必不可少的。但就目前而言,基本结构会是什么样的?

好吧,你想循环遍历行和列,同时确切地知道我们需要多远才能从多行中获取信息。要做到这一点,我们应该首先找出这些跳过距离,然后进入二维for循环。这是该计划的草图:

dataString = *given data*
colNames = []
row = 0
col = 0
totalLines = *number of lines*
startChar = *number of characters before first M column*
skipDist = *number of characters between columns*
n = startChar
while (dataString[n] != “\n”):  # get all of the column names
    if dataString[n] == “M” or dataString[n] == “S”:
        colNames += dataString[n:n+2]
lineLength = n
numCols = len(colNames)
mcOrder1 = [[] for i in range(numCols)]

# now loop over the columns, storing the new data as you go
for row in range(totalLines)
    for col in range(numCols):
        currentChar = row*lineLength+startChar+skipDist*col
        nextLineChar = currentChar + lineLength
        mcOrder1[col] += [dataString[currentChar] + dataString[nextLineChar]]

虽然这段代码中确实存在一些漏洞,但我希望它能给你一些直觉,告诉你如果你想自己编写函数,而不是使用外部库,你应该做些什么。一旦填充了mcOrder1列表,您还应该能够构建这些循环的反向版本,以将mcOrder1转换为大字符串并再次执行。或者,您可以将dataString分解为具有一个辅助函数的列表,然后更有效地处理该MUCH,并对将来的列表(或您使用的任何数据结构)执行相同的操作。

我希望这有用 - 请告诉我是否有任何令您感到困惑的事情,或者任何代码都不清楚。祝你好运!

答案 1 :(得分:1)

帮助程序功能

from numpy.core.defchararray import add as sadd, split as ssplit

def mchain(s, n=1, sep=None):
    s = np.asanyarray(s, dtype=str)
    if sep == None:
        _s = np.append(s, np.tile(s[-1], n))
        s_ = np.append(np.tile(s[0], n), s)
        return sadd(sadd(_s, 'g'), s_)
    else:
        s = np.array(ssplit(s, sep, 1).tolist())
        _s = np.vstack([s, np.tile(s[[-1]], (n, 1))])
        s_ = np.vstack([np.tile(s[[0]], (n, 1)), s])
        _s_ = sadd(sadd(_s, 'g'), s_)
        return sadd(sadd(_s_[:, 0], sep), _s_[:, 1])

def proc(d, n=1):
    ch = {k: mchain(d[k], n) for k in d if k not in ['PG', 'block']}
    ch['PG'] = mchain(d.PG, n, '|')
    ch['block'] = d.name
    return pd.DataFrame(ch).reindex_axis(d.columns, 1)

第一顺序

df.groupby('block', group_keys=False).apply(proc, n=1)

   block       PG   M1   M2   M3   M4   S1   S2   S3   S4
0     15  AgA|TgT  AgA  AgA  CgC  GgG  TgT  TgT  CgC  TgT
1     15  GgA|CgT  GgA  GgA  GgC  CgG  CgT  CgT  GgC  AgT
2     15  TgG|AgC  TgG  CgG  TgG  TgC  AgC  AgC  CgG  AgA
3     15  TgT|CgA  TgT  TgC  TgT  AgT  CgA  CgA  GgC  CgA
4     15  CgT|GgC  CgT  AgT  CgT  AgA  GgC  GgC  TgG  GgC
5     15  AgC|CgG  AgC  AgA  AgC  CgA  CgG  CgG  GgT  CgG
6     15  GgA|TgC  GgA  CgA  GgA  CgC  TgC  TgC  GgG  TgC
7     15  GgG|TgT  GgG  CgC  GgG  CgC  TgT  TgT  GgG  TgT
0     17  TgT|GgG  TgT  TgT  AgA  TgT  GgG  CgC  GgG  CgC
1     17  GgT|AgG  GgT  GgT  GgA  CgT  AgG  AgC  AgG  CgC
2     17  TgG|CgA  CgG  TgG  TgG  CgC  CgA  CgA  GgA  TgC
3     17  AgT|TgC  AgC  AgT  AgT  CgC  TgC  TgC  TgG  AgT
4     17  AgA|TgT  AgA  AgA  AgA  CgC  TgT  TgT  TgT  AgA

第二顺序

df.groupby('block', group_keys=False).apply(proc, n=2)

   block       PG   M1   M2   M3   M4   S1   S2   S3   S4
0     15  AgA|TgT  AgA  AgA  CgC  GgG  TgT  TgT  CgC  TgT
1     15  GgA|CgT  GgA  GgA  GgC  CgG  CgT  CgT  GgC  AgT
2     15  TgA|AgT  TgA  CgA  TgC  TgG  AgT  AgT  CgC  AgT
3     15  TgG|CgC  TgG  TgG  TgG  AgC  CgC  CgC  GgG  CgA
4     15  CgT|GgA  CgT  AgC  CgT  AgT  GgA  GgA  TgC  GgA
5     15  AgT|CgC  AgT  AgT  AgT  CgA  CgC  CgC  GgG  CgC
6     15  GgC|TgG  GgC  CgA  GgC  CgA  TgG  TgG  GgT  TgG
7     15  GgA|TgC  GgA  CgA  GgA  CgC  TgC  TgC  GgG  TgC
8     15  GgG|TgT  GgG  CgC  GgG  CgC  TgT  TgT  GgG  TgT
0     17  TgT|GgG  TgT  TgT  AgA  TgT  GgG  CgC  GgG  CgC
1     17  GgT|AgG  GgT  GgT  GgA  CgT  AgG  AgC  AgG  CgC
2     17  TgT|CgG  CgT  TgT  TgA  CgT  CgG  CgC  GgG  TgC
3     17  AgG|TgA  AgG  AgG  AgG  CgC  TgA  TgA  TgA  AgC
4     17  AgT|TgC  AgC  AgT  AgT  CgC  TgC  TgC  TgG  AgT
5     17  AgA|TgT  AgA  AgA  AgA  CgC  TgT  TgT  TgT  AgA