In [1]:
%matplotlib inline
import axelrod as axl
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import sympy as sym
import itertools
import csv
import os
import glob
from mpl_toolkits.axes_grid1 import make_axes_locatable
from pandas.util.testing import assert_frame_equal
import math
import imp
players = imp.load_source('players', '../src/players.py')
generate_cache = imp.load_source('players', '../src/generate_cache.py')
theoretic = imp.load_source('theoretic', '../src/theoretic.py')
abbreviations = imp.load_source('abbreviations', '../src/abbreviations.py')
assert axl.__version__ == '2.9.0'
assert pd.__version__ == '0.19.2'
assert matplotlib.__version__ == '2.0.0'
assert sns.__version__ == '0.7.1'
assert np.__version__ == '1.12.1'
assert sym.__version__ == '1.0'
Here are all the strategies used in this experiment:
In [2]:
from abbreviations import abbreviations
def abbreviate(player_name, abbreviations=abbreviations):
"""
Return the abbreviated name of a play if one has been given
"""
if isinstance(player_name, axl.Player):
player_name = str(player_name)
return abbreviations.get(player_name, player_name)
assert abbreviate("Tit For Tat") == "TfT"
assert abbreviate("Random: 0.5") == "Random"
assert abbreviate(axl.TitForTat()) == "TfT"
In [3]:
from players import selected_players
players_of_interest = set([p for p in selected_players()
if ("length" not in p.classifier["makes_use_of"]) and
("Incorrect" not in abbreviate(p))])
assert len(players_of_interest) == 164
These players have been omitted from the analysis (even though their data was collected). This is because they use the match length or were entered in to the original data sweep by error (the FSM strategies do not use the correct initial state).
In [4]:
set(map(str, selected_players())) - set(map(str, players_of_interest))
Out[4]:
In [5]:
with open("../data/reference_keys.csv", "r") as f:
reader = csv.reader(f)
reference_keys = {player: eval(keys) for player, keys in reader}
assert reference_keys['ALLCorALLD'] == ['axelrodproject']
assert reference_keys['Cooperator'] == ['Axelrod1984', 'Mittal2009', 'Press2012']
In [6]:
with open("../tex/list_of_players.tex", "w") as f:
for player in sorted(players_of_interest, key=str):
latex_name = "{}".format(player).replace("_", "\_")
f.write("\item {}".format(latex_name))
abbreviation = abbreviate(player)
if abbreviation != player.name:
f.write("(\\textbf{{{}}})".format(abbreviation))
if player.classifier["stochastic"]:
f.write(" - \\textit{Stochastic}")
else:
f.write(" - \\textit{Deterministic}")
try:
mem = int(player.classifier["memory_depth"])
except OverflowError:
mem = "\(\infty\)"
if player.name == "Grudger":
mem = 1 # Overwrite incorrect classification
f.write(" - \\textit{{Memory depth}}: {}".format(mem))
try:
f.write(". \cite{{{}}}\n".format(", ".join(sorted(reference_keys[str(player)]))))
except KeyError:
f.write(".\n")
Here are some summary information about the strategies
In [7]:
def clean_mem(n):
try:
return int(n)
except OverflowError:
return -1
player_info = pd.DataFrame([[abbreviate(p), p.classifier["stochastic"], clean_mem(p.classifier['memory_depth'])]
for p in players_of_interest],
columns=["Player", "Stochastic", "Memory Depth"])
In [8]:
temp_df = pd.DataFrame(player_info.groupby("Stochastic")["Player"].count()).reset_index().rename(columns={"Player": "Count"})
for bool in [True, False]:
filename = "../tex/num_stochastic.tex" if bool else "../tex/num_deterministic.tex"
with open(filename, "w") as f:
num = temp_df[temp_df["Stochastic"] == bool]["Count"].iloc[0]
print(num, bool)
f.write(str(num))
with open("../tex/num_strategies.tex", "w") as f:
num = len(players_of_interest)
f.write(str(num))
print(num)
with open("../tex/num_strategies_axelrod.tex", "w") as f:
num = len(axl.strategies)
f.write(str(num))
print(num)
In [9]:
mem_df = pd.DataFrame(player_info.groupby("Memory Depth")["Player"].count()).transpose()
mem_df.rename(index={"Player": "Count"}, inplace=True)
cols = mem_df.columns.tolist()
mem_df = mem_df[cols[1:] + [cols[0]]]
mem_df
Out[9]:
In [10]:
def clean_latex(string):
"""Replace some special carachters"""
string = string.replace("textbackslashpi", "pi")
string = string.replace("textbackslashphi", "phi")
string = string.replace("\\$", "$")
string = string.replace("\\$", "$")
string = string.replace("\\textasciicircum", "^")
string = string.replace("\_", "_")
string = string.replace("2_2_2", "2\_2\_2")
string = string.replace("1_1_1", "1\_1\_1")
for i in range(1, 4):
string = string.replace("TF{}".format(i), "\\textbf{{TF{}}}".format(i))
return string
with open("../tex/memory_depth_count.tex", "w") as f:
string = clean_latex(mem_df.to_latex()).replace("-1", "\(\infty\)")
f.write(string)
In [11]:
cached_outcomes = pd.read_csv("../data/outcomes.csv", header=None,
names=["Player 1", "Player 2", "Score 1", "Score 2", "Iteration"])
cached_outcomes["Player 1"] = cached_outcomes["Player 1"].apply(lambda x: abbreviate(x))
cached_outcomes["Player 2"] = cached_outcomes["Player 2"].apply(lambda x: abbreviate(x))
cached_outcomes = cached_outcomes[cached_outcomes["Player 1"].isin(player_info["Player"]) &
cached_outcomes["Player 2"].isin(player_info["Player"])]
assert len(cached_outcomes.index) == 1169001
In [12]:
cached_outcomes.head()
Out[12]:
In [13]:
is_stochastic = dict(zip(player_info["Player"], player_info["Stochastic"]))
In [14]:
temp_df = pd.DataFrame(cached_outcomes.groupby(["Player 1", "Player 2"]).count()).reset_index()
temp_df["Outcome count"] = temp_df["Score 1"]
temp_df.drop(["Score 1", "Score 2", "Iteration"], axis=1, inplace=True)
In [15]:
temp_df["Stochastic"] = ((temp_df["Player 1"].map(lambda p: is_stochastic[p]) |
temp_df["Player 2"].map(lambda p: is_stochastic[p])) &
(temp_df["Outcome count"] > 1))
In [16]:
temp_df.head()
Out[16]:
Here we create a number of plots comparing the theoretic fixation probability with the observed fixation probability for a number of initial starting populations.
In [17]:
validation = pd.read_csv("../data/fixation_validation.csv", index_col=False)
In [18]:
validation.tail()
Out[18]:
In [19]:
markers = itertools.cycle(('X', '+', 'o'))
marker_size = 50
fontsize=16
for names, df in validation.groupby(["Player 1", "Player 2"]):
df.sort_values("N", inplace=True)
repetitions = df["Repetitions"].iloc[0]
assert all(df["Repetitions"] == repetitions)
# Get names instead of repr (to drop some parameters)
names = [abbreviate(name) for name in names]
title = "{} and {} over {} repetitions".format(*names, repetitions)
filename = "{}_v_{}".format(*names)
for substr in [": ", ".", ":", " "]:
filename = filename.replace(substr, "_")
plt.figure()
labels = ["1", "N / 2", "N - 1"]
index_sets = [df["i"] == 1, df["i"] == df["N"] / 2, df["i"] == df["N"] - 1]
for label, index in zip(labels, index_sets):
d = df[index]
plt.plot(d["N"], d["Theoretic"], label="")
plt.scatter(d["N"], d["Simulated"], marker=next(markers),
label="$x_{{{}}}$".format(label), s=marker_size)
plt.xticks(d["N"])
plt.title(title, fontsize=fontsize)
plt.ylim(0, 1.1)
plt.ylabel("{} fixation probability".format(names[0]))
plt.xlabel("$N$")
plt.legend(fontsize=15)
plt.savefig("../img/{}.pdf".format(filename))