遺伝的浮動のシミュレーション(python)
この記事はすこし専門的な内容になっており、『生物学に特化した短編小説とエッセイ』とは別のマガジンに組み込まれています。
遺伝学とプログラミングに興味がある方はぜひ試してみてください。
・遺伝的浮動の簡単な説明
集団遺伝学は生物の集団内で、遺伝子の構成・頻度がどのように変化にするかを調べる学問です。
その中でも重要な概念として、遺伝的浮動というものがあります。
遺伝的浮動(genetic drift)は対立遺伝子の頻度(割合)の世代ごとの『無作為な』変化のことを言います。
ある生物の集団を仮定します。その生物の集団の中にも遺伝型が異なる個体が存在しています。例えば、毛の色が黒の個体とブロンドの個体、といった具合です。
それらは世代ごとに割合を変えていきます。つまり五世代前は毛が黒い個体が3割くらいだったのに、今の世代は5割になっている、などいつも同じ割合ではありません。
その変化自体を遺伝的浮動(genetic drift)と言います。
これは自然選択(natural selection)は異なるものです。
例えば、上の例で、ブロンドの個体が10割になったとしても、それは生存に有利だったからとは考えにくいですよね?
生存の有利不利にかかわらず、どちらかの形質に集団内の遺伝型が固定することがありますが、それは遺伝的浮動の力で起こります。遺伝的浮動はすなわち『無作為な』変化です。
遺伝的浮動は自然選択の適者生存の原理とは異なります。別に環境に関係なく、集団内の遺伝型が決まるという事です。
適者生存の考えはダーウィンの進化論=自然選択説ですね。それに対して遺伝的浮動から導かれた有名な説があります。それは中立説と言います。進化の原動力のほとんどは自然選択ではなく、偶然だとする説です。
この中立説と自然選択説はどちらが正しいのか大きな論争を呼びました。
ちなみに中立説と自然選択説の中のどちらの進化も生物の中で起こっています。ですが、自然選択説のような進化はあまり多くはないようです。
また、適者生存的な進化が起こるような選択圧は『正の選択』『Darwinian selection』『positive selection』、逆に変化したら困るような箇所が保存されるという選択圧は『負の選択圧』『purifying selection』『negative selection』と言います。
・数学的には
とても正直にいって、僕は数学が苦手なんです。
なのでわりにテキトーに説明していきます。
遺伝的浮動は数学的には二項分布であらわすことができます。
用語は聞きなれないかもしれないのですが、多分皆さん高校の数学の時間にやっていると思います。
組み合わせの確率の話です。
例えば、生物の個体を赤と白のボールだとしましょう。
赤が2個、白が8個、計10個のボールが箱に入っています。
これは染色体の数が計10個の生物の集団だと考えてください。
次の世代の子孫を生むという事は、この箱の中に入っている10個の染色体から無作為にボールを選ぶ行為とほとんど同じです。
で、次の世代の集団数(あるいは染色体の数)が変わらないとすると(つまり前の世代と同じ数になるように引くと)、次世代の赤色のボールの割合が変わらない(前の世代と同じように2個である)確率Pは次のように求められます。
P=10C2・{(2/10)^2}・{(1-2/10)^(10-2)}
重複を気にせずにランダムにはこの中から10個取り出した時が次世代の遺伝型の頻度である、という事です。
……わかりづらいですね。一番下におすすめの書籍を書いておきます※。
各世代で頻度が変わりますので、シミュレーションの際はその都度計算する必要があります(といっても、forループ回して、つぎの回に前の回の結果を渡すだけですが)。
で、シミュレーションする際は二項分布に従う乱数を発生させて、どのような挙動になるのか調べていきます。
・遺伝的浮動のコード
では、遺伝的浮動の基本的な仕組みを知るためのコードを共有いたします。
考えるのを簡単にするために、二倍体の生物で両性生殖を想定しています。
コードはpython3.7で実行し確認しました。
import numpy as np
import matplotlib.pyplot as plt
def test_binomial(individual,i,generation_num):
l=[]
for count in range(generation_num):
chromosome = 2*individual
Pt = i / chromosome
i = np.random.binomial(chromosome,p=Pt)
l.append(i)
return l
individual = 10
i = 10
generation_num = 100
l3=[]
for count in range(10):
l2 = test_binomial(individual,i,generation_num)
l3.append(l2)
l3
fig=plt.figure()
ax=fig.add_subplot(1,1,1)
for i in range(10):
ax.plot(l3[i])
ax.set_xlim(0,50)
plt.show()
個体数10個体(二倍体なので染色体は20個)、変異したアレルを含む染色体は10個、世代数は100としています。
もっと詳しく書いているサイトもありますが、ひとまずこんなところで。
また、小説とエッセイもよろしくお願いいたします。
ではまた。
筆者脚注
※『進化で読み解く バイオインフォマティクス入門』長田直樹著がおすすめです。
この記事が気に入ったらサポートをしてみませんか?