Reference: Model Code#

This page is a reference for the code used to generate the figures in the previous results page.

This is included largely for reproducibility so that others can generate similar results; it also provides more fine-grained insight into the model implementation.

Initialization#

# Run dependencies
%run ./model_python_lib_utils.ipynb
%run ./model_python_lib_event_counts.ipynb
%run ./model_python_lib_decision_functions.ipynb
%run ./python_lib_visualization.ipynb
%run ./model_wrapper.ipynb
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
File /var/folders/vc/0d4071bd7rbd6q1btkk05jcw0000gn/T/ipykernel_1901/3777295251.py:10, in <cell line: 10>()
      8 import pandas as pd
      9 from scipy import stats
---> 10 import seaborn as sns
     12 from utils import N_ROUNDS
     15 def groupby_f_data(f_data, colname, bins):

ModuleNotFoundError: No module named 'seaborn'
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
Input In [1], in <cell line: 5>()
      3 get_ipython().run_line_magic('run', './model_python_lib_event_counts.ipynb')
      4 get_ipython().run_line_magic('run', './model_python_lib_decision_functions.ipynb')
----> 5 get_ipython().run_line_magic('run', './python_lib_visualization.ipynb')
      6 get_ipython().run_line_magic('run', './model_wrapper.ipynb')

File /Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/IPython/core/interactiveshell.py:2305, in InteractiveShell.run_line_magic(self, magic_name, line, _stack_depth)
   2303     kwargs['local_ns'] = self.get_local_scope(stack_depth)
   2304 with self.builtin_trap:
-> 2305     result = fn(*args, **kwargs)
   2306 return result

File /Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/IPython/core/magics/execution.py:717, in ExecutionMagics.run(self, parameter_s, runner, file_finder)
    715     with preserve_keys(self.shell.user_ns, '__file__'):
    716         self.shell.user_ns['__file__'] = filename
--> 717         self.shell.safe_execfile_ipy(filename, raise_exceptions=True)
    718     return
    720 # Control the response to exit() calls made by the script being run

File /Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/IPython/core/interactiveshell.py:2811, in InteractiveShell.safe_execfile_ipy(self, fname, shell_futures, raise_exceptions)
   2809 result = self.run_cell(cell, silent=True, shell_futures=shell_futures)
   2810 if raise_exceptions:
-> 2811     result.raise_error()
   2812 elif not result.success:
   2813     break

File /Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/IPython/core/interactiveshell.py:251, in ExecutionResult.raise_error(self)
    249     raise self.error_before_exec
    250 if self.error_in_exec is not None:
--> 251     raise self.error_in_exec

    [... skipping hidden 1 frame]

File /var/folders/vc/0d4071bd7rbd6q1btkk05jcw0000gn/T/ipykernel_1901/3777295251.py:10, in <cell line: 10>()
      8 import pandas as pd
      9 from scipy import stats
---> 10 import seaborn as sns
     12 from utils import N_ROUNDS
     15 def groupby_f_data(f_data, colname, bins):

ModuleNotFoundError: No module named 'seaborn'

Model Benchmark: Human Performance#

# Read data
df = read_rps_data(os.path.join("data", DEFAULT_FILE))
df.head()
# Plot human win rates
f_a = groupby_f_data(df_agent, 'player_outcome', bins=10)
plot_win_rates(f_a[f_a['player_outcome']=='win']) # NB: add a filename argument to save the figure locally
<ipython-input-1-d28ed19b175e>:22: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  modified_f_data['bin'] = pd.cut(modified_f_data.loc[:, ('round_index')], bins, labels = labs)
<ipython-input-1-d28ed19b175e>:46: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  data['bot_strategy'] = data['bot_strategy'].replace([
<ipython-input-1-d28ed19b175e>:59: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  data['bin'] = data['bin'].replace(['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'], ['100', '200', '300', '400', '500', '600', '700', '800', '900', '1000'])
<AxesSubplot:xlabel='Trial round', ylabel='Mean win percentage'>
_images/ModelModel_code_6_2.png

Null Model: Tracking Opponent Move Baserates#

Run model

model1 = df_agent.copy()
model1['ev_rock'] = model1['ev_move_baserate_rock']
model1['ev_paper'] = model1['ev_move_baserate_paper']
model1['ev_scissors'] = model1['ev_move_baserate_scissors']

# Compute softmax distribution
m1_softmax = get_softmax_probabilities(
    model1,
    ['ev_rock', 'ev_paper', 'ev_scissors']
)

# Select agent move based on softmax computed above
model1 = pick_move(model1, m1_softmax)

# Evaluate outcome of agent move choices in simulation above
model1 = assign_agent_outcomes(model1)

Plot model results

# Plot agent win rates
f_b = groupby_f_data(model1, 'agent_outcome', bins=10)
plot_win_rates(f_b[f_b['agent_outcome']=='win']) # NB: add a filename argument to save the figure locally
<ipython-input-1-d28ed19b175e>:22: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  modified_f_data['bin'] = pd.cut(modified_f_data.loc[:, ('round_index')], bins, labels = labs)
<ipython-input-1-d28ed19b175e>:46: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  data['bot_strategy'] = data['bot_strategy'].replace([
<ipython-input-1-d28ed19b175e>:59: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  data['bin'] = data['bin'].replace(['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'], ['100', '200', '300', '400', '500', '600', '700', '800', '900', '1000'])
<AxesSubplot:xlabel='Trial round', ylabel='Mean win percentage'>
_images/ModelModel_code_11_2.png

Transition Model: Tracking Opponent Self-Transitions#

Run model

model2 = df_agent.copy()
model2['ev_rock'] = model2['ev_move_baserate_rock'] + model2['ev_transition_rock']
model2['ev_paper'] = model2['ev_move_baserate_paper'] + model2['ev_transition_paper']
model2['ev_scissors'] = model2['ev_move_baserate_scissors'] + model2['ev_transition_scissors']

# Compute softmax distribution
m2_softmax = get_softmax_probabilities(
    model2,
    ['ev_rock', 'ev_paper', 'ev_scissors']
)

# Select agent move based on softmax computed above
model2 = pick_move(model2, m2_softmax)

# Evaluate outcome of agent move choices in simulation above
model2 = assign_agent_outcomes(model2)
72.75148606300354

Plot model results

# Plot agent win rates
f_c = groupby_f_data(model2, 'agent_outcome', bins = 10)
plot_win_rates(f_c[f_c['agent_outcome']=='win']) # NB: add a filename argument to save the figure locally
<ipython-input-1-d28ed19b175e>:22: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  modified_f_data['bin'] = pd.cut(modified_f_data.loc[:, ('round_index')], bins, labels = labs)
<ipython-input-1-d28ed19b175e>:46: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  data['bot_strategy'] = data['bot_strategy'].replace([
<ipython-input-1-d28ed19b175e>:59: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  data['bin'] = data['bin'].replace(['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'], ['100', '200', '300', '400', '500', '600', '700', '800', '900', '1000'])
<AxesSubplot:xlabel='Trial round', ylabel='Mean win percentage'>
_images/ModelModel_code_16_2.png

Transition Model: Tracking Opponent Opponent-Transitions#

Run model

model3 = df_agent.copy()
model3['ev_rock'] = model3['ev_move_baserate_rock'] + model3['ev_cournot_transition_rock']
model3['ev_paper'] = model3['ev_move_baserate_paper'] + model3['ev_cournot_transition_paper']
model3['ev_scissors'] = model3['ev_move_baserate_scissors'] + model3['ev_cournot_transition_scissors']

# Compute softmax distribution
m3_softmax = get_softmax_probabilities(
    model3, 
    ['ev_rock', 'ev_paper', 'ev_scissors']
)

# Select agent move based on softmax computed above
model3 = pick_move(model3, m3_softmax)

# Evaluate outcome of agent move choices in simulation above
model3 = assign_agent_outcomes(model3)
72.12722420692444

Plot model results

# Plot agent win rates
f_d = groupby_f_data(model3, 'agent_outcome', bins=10)
plot_win_rates(f_d[f_d['agent_outcome']=='win'], img_name= 'model_botcournot_transition_only.png') # NB: add a filename argument to save the figure locally
<ipython-input-1-d28ed19b175e>:22: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  modified_f_data['bin'] = pd.cut(modified_f_data.loc[:, ('round_index')], bins, labels = labs)
<ipython-input-1-d28ed19b175e>:46: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  data['bot_strategy'] = data['bot_strategy'].replace([
<ipython-input-1-d28ed19b175e>:59: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  data['bin'] = data['bin'].replace(['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'], ['100', '200', '300', '400', '500', '600', '700', '800', '900', '1000'])
<AxesSubplot:xlabel='Trial round', ylabel='Mean win percentage'>
_images/ModelModel_code_21_2.png

Combined Transition Model: Tracking Opponent Self- and Opponent-Transitions#

Run model

model4 = df_agent.copy()
model4['ev_rock'] = model4['ev_move_baserate_rock'] + model4['ev_transition_rock'] + model4['ev_cournot_transition_rock']
model4['ev_paper'] = model4['ev_move_baserate_paper'] + model4['ev_transition_paper'] + model4['ev_cournot_transition_paper']
model4['ev_scissors'] = model4['ev_move_baserate_scissors'] + model4['ev_transition_scissors']+ model4['ev_cournot_transition_scissors']

# Compute softmax distribution
m4_softmax = get_softmax_probabilities(
    model4,
    ['ev_rock', 'ev_paper', 'ev_scissors']
)

# Select agent move based on softmax computed above
model4 = pick_move(model4, m4_softmax)

# Evaluate outcome of agent move choices in simulation above
model4 = assign_agent_outcomes(model4)
71.46850514411926

Plot model results

# Plot agent win rates
f_e = groupby_f_data(model4, 'agent_outcome', bins = 10)
plot_win_rates(f_e[f_e['agent_outcome']=='win']) # NB: add a filename argument to save the figure locally
<ipython-input-1-d28ed19b175e>:22: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  modified_f_data['bin'] = pd.cut(modified_f_data.loc[:, ('round_index')], bins, labels = labs)
<ipython-input-1-d28ed19b175e>:46: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  data['bot_strategy'] = data['bot_strategy'].replace([
<ipython-input-1-d28ed19b175e>:59: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  data['bin'] = data['bin'].replace(['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'], ['100', '200', '300', '400', '500', '600', '700', '800', '900', '1000'])
<AxesSubplot:xlabel='Trial round', ylabel='Mean win percentage'>
_images/ModelModel_code_26_2.png

Outcome-Transition Model: Tracking Opponent Transitions Across Outcomes#

Run model

model5 = df_agent.copy()
model5['ev_rock'] = model5['ev_outcome_transition_rock']
model5['ev_paper'] = model5['ev_outcome_transition_paper']
model5['ev_scissors'] = model5['ev_outcome_transition_scissors']

# Compute softmax distribution
m5_softmax = get_softmax_probabilities(
    model5,
    ['ev_rock', 'ev_paper', 'ev_scissors']
)

# Select agent move based on softmax computed above
model5 = pick_move(model5, m5_softmax)

# Evaluate outcome of agent move choices in simulation above
model5 = assign_agent_outcomes(model5)
71.46870303153992

Plot model results

# Plot agent win rates
f_f = groupby_f_data(model5, 'agent_outcome', bins=10)
plot_win_rates(f_f[f_f['agent_outcome']=='win']) # NB: add a filename argument to save the figure locally
<ipython-input-1-d28ed19b175e>:22: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  modified_f_data['bin'] = pd.cut(modified_f_data.loc[:, ('round_index')], bins, labels = labs)
<ipython-input-1-d28ed19b175e>:46: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  data['bot_strategy'] = data['bot_strategy'].replace([
<ipython-input-1-d28ed19b175e>:59: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  data['bin'] = data['bin'].replace(['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'], ['100', '200', '300', '400', '500', '600', '700', '800', '900', '1000'])
<AxesSubplot:xlabel='Trial round', ylabel='Mean win percentage'>
_images/ModelModel_code_31_2.png

Dual-Outcome-Transition Model: Tracking Opponent Transitions Across Outcomes and Prior Transitions#

Run model

model6 = df_agent.copy()
model6['ev_rock'] = model6['ev_outcome_dual_depend_rock']
model6['ev_paper'] = model6['ev_outcome_dual_depend_paper']
model6['ev_scissors'] = model6['ev_outcome_dual_depend_scissors']

# Compute softmax distribution
m6_softmax = get_softmax_probabilities(
    model6,
    ['ev_rock', 'ev_paper', 'ev_scissors']
)

# Select agent move based on softmax computed above
model6 = pick_move(model6, m6_softmax)

# Evaluate outcome of agent move choices in simulation above
model6 = assign_agent_outcomes(model6)
73.76682901382446

Plot model results

# Plot agent win rates
f_g = groupby_f_data(model6, 'agent_outcome', bins=10)
plot_win_rates(f_g[f_g['agent_outcome']=='win']) # NB: add a filename argument to save the figure locally
<ipython-input-1-d28ed19b175e>:22: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  modified_f_data['bin'] = pd.cut(modified_f_data.loc[:, ('round_index')], bins, labels = labs)
<ipython-input-1-d28ed19b175e>:46: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  data['bot_strategy'] = data['bot_strategy'].replace([
<ipython-input-1-d28ed19b175e>:59: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  data['bin'] = data['bin'].replace(['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'], ['100', '200', '300', '400', '500', '600', '700', '800', '900', '1000'])
<AxesSubplot:xlabel='Trial round', ylabel='Mean win percentage'>
_images/ModelModel_code_36_2.png