この記事では、Alex MesoudiのRで書かれたチュートリアルをpythonに翻訳する。
下記の記事では同調バイアスのモデルが紹介されている。
形質の特徴や、誰が形質を持っているのかとは無関係に、集団において多数派を占めている形質が継承される傾向のことを同調バイアスという。。
エージェントベースシミュレーション
まずは、必要なライブラリをインストールする。
python
import pandas as pd
import numpy as np
import random
import math
import matplotlib.pyplot as plt
!pip install japanize-matplotlib
import japanize_matplotlib
コードは次のようになる。
python
def conformist_transmission(N, p_0, D, t_max, r_max):
output = pd.DataFrame(np.tile(np.nan, (t_max, r_max)))
output.columns = ["run_" + str(i) for i in range(r_max)]
for r in range(r_max):
agent = pd.DataFrame(random.choices(["A", "B"], k=N, weights=[p_0, 1 - p_0]), columns=["trait"])
output.iloc[0, r] = sum(agent["trait"] == "A") / N
for t in range(1, t_max):
demonstrators = pd.DataFrame([random.choices(agent["trait"], k=N),random.choices(agent["trait"], k=N),random.choices(agent["trait"], k=N)], index=["dem1", "dem2", "dem3"]).T
numAs = pd.DataFrame(demonstrators.T == "A").sum().values
agent["trait"][numAs == 3] = "A"
agent["trait"][numAs == 0] = "B"
prob = np.random.rand(N)
agent["trait"][np.logical_and(numAs == 2,prob < (2/3 + D/3))] = "A"
agent["trait"][np.logical_and(numAs == 2,prob >= (2/3 + D/3))] = "B"
agent["trait"][np.logical_and(numAs == 1,prob < (1/3 - D/3))] = "A"
agent["trait"][np.logical_and(numAs == 1,prob >= (1/3 - D/3))] = "B"
output.iloc[t, r] = sum(agent["trait"] == "A") / N
plt.figure(figsize=(10, 5), dpi=100)
plt.plot(output, label = "trait 1")
plt.title(f'N = {N}, D = {D}, p_0 = {p_0}')
plt.xlabel('世代数')
plt.ylabel("形質Aを持つエージェントの割合")
plt.xlim([0, t_max])
plt.ylim([0, 1])
plt.legend()
plt.show()
return output
次に、実際にシミュレーションしてみる。
python
data_model5 = conformist_transmission(N = 1000, p_0 = 0.5, D = 1, t_max = 50, r_max = 10)
多数派を占めた形質が人口を占めていくことが分かる。
数値シミュレーション
p′=p+Dp(1−p)(2p−1)
数値シミュレーションの場合、次のようになる。
python
def conformity_recursion(D, t_max, p_0):
p = np.zeros(t_max)
p[0] = p_0
for i in range(1, t_max):
p[i] = p[i-1] + D*p[i-1]*(1-p[i-1])*(2*p[i-1] - 1)
plt.figure(figsize=(10, 5), dpi=100)
plt.plot(p)
plt.title(f's = {s}')
plt.xlabel('世代数')
plt.ylabel("形質Aを持つエージェントの割合")
plt.xlim([0, 150])
plt.ylim([0, 1])
plt.show()
conformity_recursion(D = 0.1, t_max = 150, p_0 = 0.51)