【问题标题】:How to generate one hot encoding for DNA sequences?如何为 DNA 序列生成一种热编码?
【发布时间】:2016-03-19 17:47:25
【问题描述】:

我想为一组 DNA 序列生成一个热编码。例如,序列 ACGTCCA 可以以转置方式表示如下。但是下面的代码将以水平方式生成一种热编码,我更喜欢以垂直方式使用它。谁能帮帮我?

ACGTCCA 
1000001 - A
0100110 - C 
0010000 - G
0001000 - T

示例代码:

from sklearn.preprocessing import OneHotEncoder
import itertools

# two example sequences
seqs = ["ACGTCCA","CGGATTG"]


# split sequences to tokens
tokens_seqs = [seq.split("\\") for seq in seqs]

# convert list of of token-lists to one flat list of tokens
# and then create a dictionary that maps word to id of word,
# like {A: 1, B: 2} here
all_tokens = itertools.chain.from_iterable(tokens_seqs)
word_to_id = {token: idx for idx, token in enumerate(set(all_tokens))}

# convert token lists to token-id lists, e.g. [[1, 2], [2, 2]] here
token_ids = [[word_to_id[token] for token in tokens_seq] for tokens_seq in tokens_seqs]

# convert list of token-id lists to one-hot representation
vec = OneHotEncoder(n_values=len(word_to_id))
X = vec.fit_transform(token_ids)

print X.toarray()

但是,代码给了我输出:

[[ 0.  1.]
 [ 1.  0.]]

预期输出:

[[1. 0. 0. 0. 0. 0. 1. 0. 1. 0. 0. 1. 1. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]
[0. 0. 0. 1. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 1. 1. 0. 0. 0. 1. 0. 0. 0. 0. 1. 1. 0.]]

【问题讨论】:

    标签: python arrays scikit-learn itertools one-hot-encoding


    【解决方案1】:
    from keras.utils import to_categorical
    
    def one_hot_encoding(seq):
        mp = dict(zip('ACGT', range(4)))
        seq_2_number = [mp[nucleotide] for nucleotide in seq]
        return to_categorical(seq_2_number, num_classes=4, dtype='int32').flatten()
    

    【讨论】:

      【解决方案2】:
      def one_hot_encode(seq):
          mapping = dict(zip("ACGT", range(4)))    
          seq2 = [mapping[i] for i in seq]
          return np.eye(4)[seq2]
      
      one_hot_encode("AACGT")
      
      ## Output: 
      array([[1., 0., 0., 0.],
         [1., 0., 0., 0.],
         [0., 1., 0., 0.],
         [0., 0., 1., 0.],
         [0., 0., 0., 1.]])
      

      【讨论】:

        【解决方案3】:

        我建议以稍微手动的方式进行:

        import numpy as np
        
        seqs = ["ACGTCCA","CGGATTG"]
        
        CHARS = 'ACGT'
        CHARS_COUNT = len(CHARS)
        
        maxlen = max(map(len, seqs))
        res = np.zeros((len(seqs), CHARS_COUNT * maxlen), dtype=np.uint8)
        
        for si, seq in enumerate(seqs):
            seqlen = len(seq)
            arr = np.chararray((seqlen,), buffer=seq)
            for ii, char in enumerate(CHARS):
                res[si][ii*seqlen:(ii+1)*seqlen][arr == char] = 1
        
        print res
        

        这会给你想要的结果:

        [[1 0 0 0 0 0 1 0 1 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0]
         [0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 1 1 0]]
        

        【讨论】:

        • 谢谢。这完美地解决了单个碱基 A、T、C、G。我想知道是否可以在具有 16 种可能组合的二核苷酸上使用,如 AA、AT、AC、AG 等。如果它显示为 TGA,那么 TG 将给定值 1 和 GA 也给定值 1。
        • @Xiong89:我相信你可以让它工作,但如果我要为你编写所有代码,我可能会问每小时费率!我认为 di 案例所需的主要构建块是:arr = np.chararray((3, 2), buffer='asdfds') 然后np.all(np.chararray((2,), buffer='as') == arr, axis=1) - 这为您提供了[True, False, False] 的数组。也就是说,您需要将所有 16 个二字符组合构建为 chararrays,然后与它们匹配。试一试。 :)
        猜你喜欢
        • 2020-05-01
        • 2019-06-18
        • 2019-08-26
        • 2019-02-18
        • 1970-01-01
        • 2020-08-28
        • 2019-04-03
        • 2020-12-22
        • 2016-09-21
        相关资源
        最近更新 更多