統計コンサルの議事メモ

統計や機械学習の話題を中心に、思うがままに

集団の繁栄に必要な子どもの数について考える

※今回の内容はDr.STONEという漫画のネタバレを含みます

唐突ですが、Dr.STONEという漫画が好きです。

物理や化学に詳しくないので内容を理解しながら読めているわけではないのですが、石化した世界で少しずつ文明のレベルが上がっていくのを見ていると、科学って地道だけど面白いなーと思ってしまいます。

しかし読んでいて一点気になるところがありました。 白夜たちが宇宙から地球に帰還した後、3組のカップルから石神村が誕生したことです。

もちろんそれぞれのカップルが非常にたくさんの子どもを産めば可能でしょう。しかし現代人が10人も20人も子どもを産めるのかというと少し難しいような気もします。 またカップルが3組しかありませんので、子どもが少なければあっと言う間に「全員が親戚同士」みたいなこととなり、新たなカップルを作れなくなりそうな気もします。そう考えると実際にどれだけ厳しい条件だったんだろうかと気になってしまいました。

というわけで今回は白夜たちが将来的に集団を繁栄させるために、どの程度の子どもをもうける必要があったかを考えてみたいと思います。

考え方

上記を考えるにあたり、以下のような条件でシミュレーションを実施します:

  • スタートは男性3人女性3人とする(第一世代)
  • 各世代において男女1人ずつでカップルとなる
  • 男女の数が異なる場合、余った人は子どもを残さない
  • カップルはそれぞれ np 人の子どもを産む
  • np は世代をまたぐ全てのカップルで共通とする
  • 生まれてくる子どもの性別は男女比 1:1 でランダムに決まる
  • カップルは一夫一妻制を取り、パートナー以外の異性との子どもは産まない
  • 世代をまたがってカップルを形成しない

シミュレーションしやすいよう厳しめの条件としています。ただしこのままでは近縁者とのカップルが出来てしまいますので、以下の条件を追加します:

  • 子どもの近交係数が一定の値以上となるカップルは形成しない

ここで近交係数とは集団遺伝学などで使われる用語で、近親交配の程度を表します。日本ではいとこ同士での結婚が法律上認められていますが、いとこ同士の子どもの近交係数が6.25%となります。第一世代の数が少ないため、ここを厳しくするとあっと言う間にカップルが出来なくなることが予想されます。

上記のシミュレーションを実行するためのプログラムは以下としました:

generate_population <- function(np, # カップルが産む子どもの数
                                n0 = 6, # 第一世代の人数
                                num_column = 6, # 結果格納用のテーブルの列数
                                G = 5, # シミュレートする世代数
                                random_seed = 42, # 乱数固定用
                                rel_lim = 0.90 # 血縁係数(近交係数とは異なる)
                                ) {

   
   set.seed(random_seed) # 子ども性別を決めるのに乱数を使うため
   pairs <- c() # カップルを記録する用のテーブル
  
   ### 個人ごとの記録(ID、世代、性別、近交係数、父、母)を格納するテーブル
   res_mat <- matrix(0, n0, num_column)
   colnames(res_mat) <- c("ID", "Gen", "Sex", "Inbred", "Father", "Mother")
  
   ### 第一世代の生成 
   res_mat[, "ID"] <- 1:n0
   res_mat[, "Gen"] <- 1
   res_mat[, "Sex"] <- rep(c(1, 0), 3)
   
   ### 以下、将来世代を生成
   for(g in 1:G) {
      
      ### 現在世代の血縁関係を評価する
      rel_mat <- create_rel_mat(res_mat)

      ### カップルを作るペアを決める
      tmp_pairs <- make_pairs(g, res_mat, rel_mat, rel_lim)
      pairs <- rbind(pairs, tmp_pairs)
      
      ### np人の子どもを生成する
      tmp_res_mat <- generate_progenies(tmp_pairs, res_mat, g, np, num_column)
      
      ### それぞれの近交係数を計算する(近交係数は両親間の血縁係数*1/2)
      tmp_res_mat <- calculate_inbred_coef(tmp_res_mat, rel_mat)
      res_mat <- rbind(res_mat, tmp_res_mat)
      
      # sprintf("The %d generation generated", g+1)
      print(g)
   }

   return(res_mat)
}

お試し

さて、関数の解説は後回しにしてまずは実行してみましょう。このプログラムを実行すると以下のような結果が得られます。

source("/YourDirectory/my_functions.r") # 関数を定義したファイル
res_mat <- generate_population(np = 3, G = 15)
> calc_num_pop(res_mat)
   Gen Population
1    1          6
2    2          9
3    3          6
4    4          9
5    5          9
6    6         12
7    7         15
8    8         18
9    9         24
10  10         33
11  11         30
12  12         39
13  13         54
14  14         60
15  15         60
16  16         87
plot(calc_num_pop(res_mat), type = "l", xlab = "Generation g", 
     ylab = "Population size")

f:id:ushi-goroshi:20210820133619p:plain

この表とグラフは先の条件でシミュレーションを実施したときの世代ごとの人数を集計しています。

第五世代まではなかなか人数が増えていきませんが、第六世代から徐々に人数を増やせていますね。カップルごとの子どもの数が3人というのは少し多いようにも思えますが、昭和24年ごろの第一次ベビーブームの合計特殊出生率が4.32ということらしいので*1、あり得ない数値ではないでしょう。むしろ死亡を一切考慮していないシミュレーションなので、もっと産んでいないと3人でも怪しくなりそうです。とはいえ、これなら石神村も問題なく誕生するでしょう、めでたしめでたし…

…と、言いたいところですが、結論づける前に近交係数を見てみましょう。

> summary(res_mat[, "Inbred"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
 0.0000  0.2956  0.3209  0.3051  0.3377  0.4053

なんと近交係数が平均で30%、最大で40%にもなってしまっています。近交係数25%は親子間でのカップルというレベルなので、これは困ってしまいます。

シミュレーション

というわけでここからが本題です。シミュレーションでパラメータとして渡している rel_lim を変更することで、近交が高まるのを避けながら集団を繁栄させ、無事に石神村を誕生させることができるか見てみましょう。

まずは日本の法律で認められているいとこ同士まで許容する(近交係数6.25%、すなわち両親間の血縁係数12.5%のカップルまで認める)とどうなるでしょうか。

> res_mat <- generate_population(np = 3, G = 15, rel_lim = 0.125)
[1] 1
[1] 2
[1] 3
 make_pairs(g, res_mat, rel_mat, rel_lim) でエラー: 
   Couldn't make any couple!

なんと、途中でカップルを作ることができなくなってしまいます…。もしかして seed によるのかもしれませんので、いくつか試してみましょう。

> generate_population(np = 3, G = 15, rel_lim = 0.125, random_seed = 1)
[1] 1
[1] 2
[1] 3
 make_pairs(g, res_mat, rel_mat, rel_lim) でエラー: 
   Couldn't make any couple!
> generate_population(np = 3, G = 15, rel_lim = 0.125, random_seed = 2)
[1] 1
[1] 2
[1] 3
 make_pairs(g, res_mat, rel_mat, rel_lim) でエラー: 
   Couldn't make any couple!
> generate_population(np = 3, G = 15, rel_lim = 0.125, random_seed = 3)
[1] 1
[1] 2
[1] 3
 make_pairs(g, res_mat, rel_mat, rel_lim) でエラー: 
   Couldn't make any couple!

ダメなようです…。

ちなみにですが、近交の制限をなくしても(同世代内のどんな近縁者とのカップルも認めても)男女の偏りによって集団が存続しないこともあります。例えば以下のように、 rel_lim を1としても seed によっては途中で止まってしまいます。

> res_mat <- generate_population(np = 3, G = 15, rel_lim = 1.0, random_seed = 5)
[1] 1
[1] 2
[1] 3
[1] 4
[1] 5
 make_pairs(g, res_mat, rel_mat, rel_lim) でエラー: 
   Couldn't make any couple!

白夜たちはもともと厳しい条件に置かれていたことがわかりますね。

それでは逆に、近交係数の条件を保った場合に必要となる np を考えてみましょう。4人から順番に増やしてみます:

> res_mat <- generate_population(np = 4, G =15, rel_lim = 0.125)
[1] 1
[1] 2
[1] 3
 make_pairs(g, res_mat, rel_mat, rel_lim) でエラー: 
   Couldn't make any couple!

〜〜 以下省略 〜〜

> res_mat <- generate_population(np = 8, G =15, rel_lim = 0.125)
[1] 1
[1] 2
[1] 3
 make_pairs(g, res_mat, rel_mat, rel_lim) でエラー: 
   Couldn't make any couple!

9人まで増やすと計算がなかなか終わらなかったため打ち切ってしまいましたが、この条件(日本の法律に合わせたカップル)はかなり厳しいようです。そもそも子どもを9人産むというのも結構難しそうですしね。

近交係数の条件をもう少し緩め、12.5%まで認めることにしてみましょう。ちなみにこの12.5%というのはおじ・姪、おば・甥でのカップルに相当します。

> res_mat <- generate_population(np = 4, G = 15, rel_lim = 0.250)
[1] 1
[1] 2
[1] 3
[1] 4
[1] 5
 make_pairs(g, res_mat, rel_mat, rel_lim) でエラー: 
   Couldn't make any couple!

4人ではダメ。5人では?

> res_mat <- generate_population(np = 5, G = 15, rel_lim = 0.25)
[1] 1
[1] 2
[1] 3
[1] 4
[1] 5
[1] 6
[1] 7

今度は計算が終わりませんでした…。一晩待ったのですが…。

しかし第八世代まで進むことは確認したので、これなら可能性がありそうです。つまり、

  • 全てのカップルが5人の子どもを産み続ける
  • 多少の近交を許容する(近縁の人間ともカップルを形成する)

ことで石神村を無事に誕生させることができそうです。やったね白夜! *2

このときの近交係数がどうなっているかも確認しておきましょう。

### 第七世代までで止める
res_mat <- generate_population(np = 5, G = 7, rel_lim = 0.25)
> calc_inb(res_mat)
  Gen Inbred_Coef
1   1   0.0000000
2   2   0.0000000
3   3   0.0000000
4   4   0.0625000
5   5   0.0937500
6   6   0.1132812
7   7   0.1250000
8   8   0.1191406

近交係数の平均は第七世代で12.5%と上限に達していますが、第八世代ではわずかに減少しています。

> calc_num_pop(res_mat)
  Gen Population
1   1          6
2   2         15
3   3         25
4   4         50
5   5        115
6   6        245
7   7        505
8   8       1195

また、世代ごとの人数を見ると第八世代で大幅に増えているので、これ以降は近交を高めることのないカップルを安定して作れることが期待できます。

もう少しプログラムをうまくかければこの辺りを追えるかもしれないのですが、実装力の無さが恨めしい…。

終わりに

というわけで、地球に降り立った6人を始祖として集団を繁栄させることが本当にできるのかを検証してみたわけですが、結果としては「厳しい条件ながらも不可能ではなさそう」ということが見えてきました。

次回はこの検証に用いた関数の具体的な解説をしたいと思います。

*1:https://www8.cao.go.jp/shoushi/shoushika/meeting/taikou_4th/k_1/pdf/ref1.pdf

*2:漫画では白夜以外のメンバーが割とすぐに亡くなっている様子なので、実際には5人というのも難しいでしょうけど