初めに
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