0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Covid-19を分析して、特徴的な配列を検索した。

Posted at

初めに

Covid-19の遺伝子配列を分析して、特徴的な配列を検索してみました。
人を含め生物の遺伝子には特徴的な配列があり、それは繰り返し出現します。
しかし、それらの配列は変異や欠失などによって完全に一致しないことがあります。
なので、不一致を許しながら可能な限り似ている配列を検索しました。

注意

この記事は以下の注意点があります。
・何かしらの医学的・生物的な結果をもたらすものではありません。
・私の知識不足により誤っている場合があります。
・Covid-19の全配列ではなく前半部を対象としております。

データの準備

NCBIから直接コピーした文字列を、テキストファイルとして保存しました。
そこから、加工し60文字ずつ区切りました。
(この処理は私が保存したファイル形式が煩雑だった為必要になったものです。)

import pandas
df = pd.read_csv('covid_dna.txt', sep=' ', header=None)
df = df.set_index(0)
df['row_concat'] = df[1]+df[2]+df[3]+df[4]+df[5]+df[6]

text = ""
for i in range(1, len(df)):
    if i == 100:
        break
    t = df.iloc[i, 6]
    text = text + t

text = text.upper()

len(text)
>5940
text[:20]
>'GTTCTCTAAACGAACTTTAA'

n = 99
dna = [text[i:i+n] for i in range(0, len(text), n)]

len(dna)
>60
dna[:2]
>['GTTCTCTAAACGAACTTTAAAATCTGTGTGGCTGTCACTCGGCTGCATGCTTAGTGCACTCACGCAGTATAATTAATAACTAATTACTGTCGTTGACAG',
 'GACACGAGTAACTCGTCTATCTTCTGCAGGCTGCTTACGGTTTCGTCCGTGTTGCAGCCGATCATCAGCACATCTAGGTTTCGTCCGGGTGTGACCGAA']

ライブラリとパラメータ

ライブラリとパラメータのインポートを行いました。

import random
import math
k = 8
t = 60
N = 100

Gibs Sampling

def _randomkmers(dna,k,t):
    randomkmer = []
    for i in range(t):
        z = random.choice(range(0,len(dna[i])-k+1))
        randomkmer.append(dna[i][z:z+k])
    return randomkmer

def _consensus(motifs):
    k = len(motifs[0])
    count = _count(motifs)
    consensus = ""
    for j in range(k):
        M = 0
        frequentSymbol = ""
        for symbol in "ACGT":
            if count[symbol][j] > M:
                M = count[symbol][j]
                frequentSymbol = symbol
        consensus += frequentSymbol
    return consensus

def hamming_distance(p, q):
    count = 0
    L = len(p)
    for i in range(L):
        if p[i] != q[i]:
            count += 1
    return count

def _profile(motifs):
    profile = {}
    t = len(motifs)
    k = len(motifs[0])
    countMotifs = _count(motifs)
    for symbol in "ACGT":
        profile[symbol] = []
    for x in countMotifs:
        for y in countMotifs[x]:
            z = y / float(t)*2
            profile[x].append(z)
    return profile

def _count(motifs):
    count = {}
    k = len(motifs[0])
    for symbol in "ACGT":
        count[symbol] = [] #Genero una lista para cada nucleotido en el set count
        for j in range(k):
            count[symbol].append(1) #a cada uno le pongo un 0
    t = len(motifs)
    for i in range(t):
        for j in range(k):
            symbol = motifs[i][j] #para el simbolo de esa posicion del motivo
            count[symbol][j] += 1 #sumarle un 1 al set count en ese lugar
    return count

def _motifs(profile,dna,k):

    motifs = []
    def maxProb(pattern,profile):
        num = []
        for i in range(len(pattern)):
            proflist = profile[pattern[i]][i]
            num.append(proflist)
        product = mathprod(num)
        return product
    for x in range(len(dna)):      #for i in range t
        prob = 0
        maxpattern = ''
        for i in range(len(dna[x])-k+1):
            pattern = dna[x][i:i+k]  #kmer text
            if maxProb(pattern,profile) > prob:
                prob = maxProb(pattern,profile)
                maxpattern = pattern
        motifs.append(maxpattern)
    return motifs

def _score(motifs):
    score = 0
    consensus = _consensus(motifs)
    for i in range(len(motifs)):
        score += hamming_distance(consensus,motifs[i])
    return score

def profile_most_probable_kmer(text, k, profile):
    mostProbVal = -1
    mostProbKmer = ''

    for i in range(0, 1 + len(text) - k):
        kmer = text[i:i+k]
        probKmerVal = _pr(kmer, profile)
        if probKmerVal > mostProbVal:
            mostProbVal = probKmerVal
            mostProbKmer = kmer

    return mostProbKmer

def _pr(text, profile):
    P = 1

    for i in range(len(text)):
        P = P * profile[text[i]][i]

    return P

def mostprobprof(Text,k,profile):
    prob = 0
    maxpattern = ''
    def maxProb(pattern,profile):
        num = []
        for i in range(len(pattern)):
            proflist = profile[pattern[i]][i]
            num.append(proflist)
        product = mathprod(num)
        return product
    for i in range(len(Text)-k+1):
        pattern = Text[i:i+k]
        if prob < maxProb(pattern,profile):
            prob = maxProb(pattern,profile)
            maxpattern = pattern
    return maxpattern

def mathprod(num):
    r = 1
    for i in num:
        r *= i
    return r

#FUNCIONS

def GibbsSampler(dna,k,t,N):
    motifs = _randomkmers(dna, k, t)
    bestMotifs = motifs
    for i in range(N):
        i = random.choice(range(t))
        del motifs[i]
        profile = _profile(motifs)
        motifs.insert(i,mostprobprof(dna[i],k,profile))
        if _score(motifs) < _score(bestMotifs):
            bestMotifs = motifs
    return bestMotifs

#print(GibbsSampler(dna,k,t,N))

bestScore = 1000
for start in range(20):
    bMotifs = GibbsSampler(dna,k,t,N)
    if _score(bMotifs) < bestScore:
        bestScore = _score(bMotifs)
        bestMotifs = bMotifs

print('\n'.join(bestMotifs))
>CTTTAAAA
TGTTGCAG
AGATGGAG
...(省略)...
TGTAGAAG
TTATGATG
TAAAGAAA
TTACAAAG
TTATAAAT
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?