HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Numerics for a game theory calculation using expected utility

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
calculationnumericstheoryexpectedutilitygameforusing

Problem

I am trying to replicate Bruce B. de Mesquita's (BDM) results on political game theory for prediction. Based on where actors stand on issues, their capabilities, salience, BDM's method attempts to find the eventual decision point by simulating a game. He reportedly used this method with much success; and published his results in successive journals, the latest of which is (1). This is his so-called "expected utility method", there is a newer method (3) but there is less documentation on that, so I wanted to use EU model first.

Scholz et.al tried to replicate the findings and documented his work here (2). I took his work as basis, since a lot of BDM articles / books are behind paywalls. There are also the gentleman here (4), they took Scholz's work as the basis, added a machine learning method on top, and created a new product.

I wrote the code, however I am not sure I was successful at replicating results.

```
import pandas as pd
import numpy as np
import itertools

Q = 1.0 ; T = 1.0

class Game:

def __init__(self,df):
self.df = df
self.df_capability = df.Capability.to_dict()
self.df_position = df.Position.to_dict()
self.df_salience = df.Salience.to_dict()
self.max_pos = df.Position.max()
self.min_pos = df.Position.min()

def weighted_median(self):
self.df['w'] = self.df.Capability*self.df.Salience
self.df['w'] = self.df['w'] / self.df['w'].sum()
self.df['w'] = self.df['w'].cumsum()
return float(self.df[self.df['w']>=0.5].head(1).Position)

def mean(self):
return (self.df.Capabilityself.df.Positionself.df.Salience).sum() / \
(self.df.Capability*self.df.Salience).sum()

def Usi_i(self,i,j,ri=1.):
tmp1 = self.df_position[i]-self.df_position[j]
tmp2 = self.max_pos-self.min_pos
return 2. - 4.0 ( (0.5-0.5np.abs(float(tmp1)/tmp2) )**ri)

def Ufi_i(self,i,j,ri=1.):
tmp1 = self.df_position[i]-self.

Solution

First off, this:

Q = 1.0 ; T = 1.0


Should be expanded to this:

Q = 1.0
T = 1.0


And, if Q and T aren't constants, they should be renamed to q and t.

Secondly, you're missing whitespace in lots of places. For example, this:

def v(self,i,j,k):


Should be, again, expanded to this:

def v(self, i, j, k):


You should also have whitespace between mathematical operators as well, like this:

((1 + 2 * (2 - 6)) / 10) % 5


In addition to mathematical operators, you should also have whitespace between comparison operators as well, like this:

True != False and 50 <= (50 ** 2)


Adding whitespace in general where it's needed will help improve the overall readability of your code.

Your naming is, well, not the best. While this is scientific/mathematical code, I'd still recommend naming things better. For example, I have no idea what the function Ubi_i does, or what it's arguments, i, j, or ri do. Preferably, the names should be more descriptive of what purpose a variable/function/class serves.

A few bad names might include:

  • df



  • tmp1



  • tmp2



  • v



  • EU_i



  • l



  • res



  • eui



  • euj



On the topic of naming, Python has an official style guide, PEP8, and the style for naming is as follows.

  • Variables/function arguments should be in snake_case, but if their value is constant, it should be in UPPER_SNAKE_CASE.



  • Functions should be in snake_case.



  • Classes should be in PascalCase.



When creating classes in any version of Python 2.x, you need to have the class explicitly inherit from object, like this:

class MyClass(object):
    ...


If you're using any version of Python 3.x or higher, this isn't required, and you can just do this instead:

class MyClass:
    ...


You have a couple of places where you're mixing single, '', and double quotes, "". Usually, it's best to be consistent.

You should also add some docstrings to your functions/classes. Docstrings should provide a description of what the function/class does, and it's arguments, if it has any. Here's an example of a docstring.

def my_func( ... ):
    """
    Describe your function/class and it's
    arguments here.
    """
    ...


Finally, in your run.py file, all the code, (except for the imports), should be wrapped in an if __name__ == "__main__": block to ensure that it properly runs. See this Stackoverflow question for more details.

Code Snippets

Q = 1.0 ; T = 1.0
Q = 1.0
T = 1.0
def v(self,i,j,k):
def v(self, i, j, k):
((1 + 2 * (2 - 6)) / 10) % 5

Context

StackExchange Code Review Q#97262, answer score: 6

Revisions (0)

No revisions yet.