Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add state to action analysis. #870

Merged
merged 4 commits into from
Feb 23, 2017
Merged

Add state to action analysis. #870

merged 4 commits into from
Feb 23, 2017

Conversation

drvinceknight
Copy link
Member

Add two functions to interaction_utils:

  • interaction_utils.compute_state_to_action_distribution: computes
    list of counter objects of mapping a (state, action) to a count.
  • interaction_utils.compute_normalised_state_to_action_distribution: computes
    list of counter objects of mapping a (state, action) to a normalised
    count (for a given state).

There have then been incorporated in axelrod.result_set and in particular in
the result_set.summarise() output. Which now includes the average
rates for each strategy in a tournament. So for memory 1 strategies this
means we can measure their parameters and for non memory 1 strategies we
can infer what the parameters correspond to the data.

Add two functions to interaction_utils:

- `interaction_utils.compute_state_to_action_distribution`: computes
  list of counter objects of mapping a `(state, action)` to a count.
- `interaction_utils.compute_normalised_state_to_action_distribution`: computes
  list of counter objects of mapping a `(state, action)` to a normalised
  count (for a given state).

There have then been incorporated in `axelrod.result_set` and in particular in
the `result_set.summarise()` output. Which now includes the average
rates for each strategy in a tournament. So for memory 1 strategies this
means we can measure their parameters and for non memory 1 strategies we
can infer what the parameters correspond to the data.
def compute_state_to_action_distribution(interactions):
"""
Returns the count of each state to action
for a set of interactions.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this needs a little more explanation as to what the function does. It wasn't clear to me until I looked at how it's being used in the result set. Perhaps an example would be useful?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah good shout. I'll clear that up and find the others. I think I got lazy :)

"""
Returns the normalised count of each state to action
for a set of interactions.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here. A little more explanation of what this is doing might be in order.

@drvinceknight
Copy link
Member Author

Let me know if you think it needs more than those last two commits :) Just jumping in the plane, will pick this up later :D

Implying that from a state of (C, D) (the first player having played C and
the second playing D) the player in question then played C.

The following counter object, implies that the player in question was in
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pedantic: "The following Counter object implies that"

return None

distributions = [Counter([(state, outcome[j]) for state, outcome in zip(interactions,
interactions[1:])])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make the spacing here more aesthetically pleasing?


((C, D), C)

Implying that from a state of (C, D) (the first player having played C and
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pedantic: lowercase "impying"

Implying that from a state of (C, D) (the first player having played C and
the second playing D) the player in question then played C.

The following counter object, implies that the player in question was only
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

formatting

----------
normalised_state_to_C_distributions : List of Counter Object
List of Counter objects where the keys are the states and actions and
the values the normalized counts.. The
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

double period

normalized_distribution = []
for player in range(2):
counter = {}
for state in [('C', 'C'), ('C', 'D'), ('D', 'C'), ('D', 'D')]:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C, D as in Actions.C, Actions.D rather than 'C' and 'D'

"""
Returns
----------

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return var name / spacing

norm_counter = Counter()
for state in [(C, C), (C, D), (D, C), (D, D)]:
total = counter[(state, C)] + counter[(state, D)]
if total > 0:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if total == 0 then we add nothing to the list? just checking that is the intention rather than None or an empty dict.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If total == 0 we still add the empty norm_counter so the behaviour is consistant :)

The test cases catch this occurrence :)

@@ -22,11 +22,27 @@ class TestMatch(unittest.TestCase):
Counter({('D', 'C'): 2}),
Counter({('C', 'C'): 1, ('C', 'D'): 1}),
None]
state_to_action_distribution = [[Counter({(('C', 'D'), 'D'): 1}),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use C and D instead of 'C' and 'D'?

self.state_to_action_distribution):
self.assertEqual(dist,
iu.compute_state_to_action_distribution(inter))
inter = [(C, D), (D, C), (C, D), (D, C), (D, D), (C, C), (C, D)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mixing C and 'C'

@marcharper
Copy link
Member

Looks fine overall, I added some minor comments about docstrings and C versus 'C'

- 'C'/'D' -> C/D
- Adding type docstrings.
@drvinceknight
Copy link
Member Author

Looks fine overall, I added some minor comments about docstrings and C versus 'C'

I think I've caught all of them and answered your question above, happy to further improve it though if you think of anything else :) 👍

@marcharper marcharper merged commit 094e839 into master Feb 23, 2017
@drvinceknight drvinceknight deleted the mem1-rates branch March 17, 2017 13:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants