egtaonline / quiesce

A script to automatically "quiesce" an empirical game on egtaonline
https://egtaonline.github.io/quiesce/
Apache License 2.0
3 stars 9 forks source link

question on usage #1

Closed andrealbh closed 3 years ago

andrealbh commented 3 years ago

Hi, I am not very sure how to use this script. For example, if I just type "egta quiesce game:game:cdasim/data_game.json" after I clone this respo and "pip install --user -U egta" in terminal, it just said egta is not a command.

erikbrinkman commented 3 years ago

for the egta command to work, it needs to be on your path. If you type pip show egta you should see the location, and you should make sure that location is on your PATH

andrealbh commented 3 years ago

for the egta command to work, it needs to be on your path. If you type pip show egta you should see the location, and you should make sure that location is on your PATH

Hi, I tried to write export PATH=$PATH:egtalocation to .bash_profile and source it, but it still said egta is not a command. Anything I did wrong?

erikbrinkman commented 3 years ago

That seems reasonable, but it seems that you don't have it configured properly. My guess is that egtalocation is wrong. pip install --user should generally installs all binaries in the same location, but what that location is depends on a lot of factors.

I'm not sure why I asked you to use pip show egta because that points to the wrong location. On *nix systems pip seems to install them to ~/.local/bin so maybe see if there's an egta there. If you're using windows or something, I'm not sure I can be of any help.

andrealbh commented 3 years ago

That seems reasonable, but it seems that you don't have it configured properly. My guess is that egtalocation is wrong. pip install --user should generally installs all binaries in the same location, but what that location is depends on a lot of factors.

I'm not sure why I asked you to use pip show egta because that points to the wrong location. On *nix systems pip seems to install them to ~/.local/bin so maybe see if there's an egta there. If you're using windows or something, I'm not sure I can be of any help.

Hi, I am testing it in Mac OS, does it matter? I can find egta/efta-0.2.1.dist-info/egtaonline/egtaonlineapi-0.8.7.dist-info/gameanalysis in the folder where other packages installed via pip are. Any other information can i provide to fix it as I am reading your PhD thesis and really think your work is interesting and desire to learn from it

erikbrinkman commented 3 years ago

On macos it seems to install to /Users/$USER/Library/Python/$PYTHON_VERSION/bin/ so try looking there and adding that relevant thing to your path. That's of course if you're using mac system python. If you installed a newer version with anaconda or something than I'm really not sure where to look. You could always try searching your mac for a file called egta and see what comes up.

andrealbh commented 3 years ago

On macos it seems to install to /Users/$USER/Library/Python/$PYTHON_VERSION/bin/ so try looking there and adding that relevant thing to your path. That's of course if you're using mac system python. If you installed a newer version with anaconda or something than I'm really not sure where to look. You could always try searching your mac for a file called egta and see what comes up.

I set up a ubuntu virtual machine and redo these steps. I think the second and third examples are not successfully tested. The details of the second example is:

egta quiesce 'sim:game:cdasim/small_game.json,command:python3 cdasim/sim.py 1 --single' Traceback (most recent call last): File "cdasim/sim.py", line 390, in main() File "cdasim/sim.py", line 382, in main outp(execute(spec)) File "cdasim/sim.py", line 302, in execute strats['max_value'] = float(strats['max_value']) KeyError: 'max_value' 2020-09-28 16:31:40,860 quiesce Traceback (most recent call last): File "/home/buhong/.local/lib/python3.7/site-packages/egta/main.py", line 112, in amain await args.method.run(args) File "/home/buhong/.local/lib/python3.7/site-packages/egta/main.py", line 65, in run return await eq_methods.choices[self].run(args) File "/home/buhong/.local/lib/python3.7/site-packages/egta/script/innerloop.py", line 93, in run style=args.style, executor=executor) File "/home/buhong/.local/lib/python3.7/site-packages/egta/innerloop.py", line 202, in inner_loop add_restriction(r) for r in restrictions]) File "/home/buhong/.local/lib/python3.7/site-packages/egta/innerloop.py", line 95, in add_restriction return await add_deviations(rest, rest.astype(float), init_role_dev) File "/home/buhong/.local/lib/python3.7/site-packages/egta/innerloop.py", line 118, in add_deviations data = await agame.get_deviation_game(mix > 0, role_index) File "/home/buhong/.local/lib/python3.7/site-packages/egta/schedgame.py", line 80, in get_deviation_game game = await self._get_game(np.concatenate([rprofs, dprofs])) File "/home/buhong/.local/lib/python3.7/site-packages/egta/schedgame.py", line 47, in _get_game lpays = await asyncio.gather(*futures) File "/home/buhong/.local/lib/python3.7/site-packages/egta/simsched.py", line 91, in sample_payoffs raise self._reader.exception() File "/home/buhong/.local/lib/python3.7/site-packages/egta/simsched.py", line 106, in _read raise RuntimeError('process died unexpectedly') RuntimeError: process died unexpectedly

Traceback (most recent call last): File "/home/buhong/.local/bin/egta", line 8, in sys.exit(main()) File "/home/buhong/.local/lib/python3.7/site-packages/egta/main.py", line 130, in main loop.run_until_complete(task) File "/usr/local/lib/python3.7/asyncio/base_events.py", line 568, in run_until_complete return future.result() File "/home/buhong/.local/lib/python3.7/site-packages/egta/main.py", line 122, in amain raise ex File "/home/buhong/.local/lib/python3.7/site-packages/egta/main.py", line 112, in amain await args.method.run(args) File "/home/buhong/.local/lib/python3.7/site-packages/egta/main.py", line 65, in run return await eq_methods.choices[self].run(args) File "/home/buhong/.local/lib/python3.7/site-packages/egta/script/innerloop.py", line 93, in run style=args.style, executor=executor) File "/home/buhong/.local/lib/python3.7/site-packages/egta/innerloop.py", line 202, in inner_loop add_restriction(r) for r in restrictions]) File "/home/buhong/.local/lib/python3.7/site-packages/egta/innerloop.py", line 95, in add_restriction return await add_deviations(rest, rest.astype(float), init_role_dev) File "/home/buhong/.local/lib/python3.7/site-packages/egta/innerloop.py", line 118, in add_deviations data = await agame.get_deviation_game(mix > 0, role_index) File "/home/buhong/.local/lib/python3.7/site-packages/egta/schedgame.py", line 80, in get_deviation_game game = await self._get_game(np.concatenate([rprofs, dprofs])) File "/home/buhong/.local/lib/python3.7/site-packages/egta/schedgame.py", line 47, in _get_game lpays = await asyncio.gather(*futures) File "/home/buhong/.local/lib/python3.7/site-packages/egta/simsched.py", line 91, in sample_payoffs raise self._reader.exception() File "/home/buhong/.local/lib/python3.7/site-packages/egta/simsched.py", line 106, in _read raise RuntimeError('process died unexpectedly') RuntimeError: process died unexpectedly

What can I do to fix it?

andrealbh commented 3 years ago

Can I also have the details of the data structure of data_game.json? I show a slice of the json file below "profiles": [ { "sellers": [ [ "S_0.4", 2, [ 0.08397286559237978, 0.08159205807425107, 0.1350550648849494, 0.07434475126725398, 0.0, 0.0, 0.05771245984067652, 0.1536411818847856, 0.303974005859878, 0.0 ] ], [ "S_0.6", 2, [ 0.09320690684618287, 0.290689660537104, 0.0, 0.13728702522403238, 0.12174601967817839, 0.0, 0.15778671826598173, 0.0, 0.0, 0.22455964475653223 ] ] ],

I believe the S_0.4 here is the type and strategy of the agent and the int 2 after S_0.4 is the number of agents adopting this strategy? But my questions are: 1) what is the meaning of the following list containing 10 float figures? And what is the meaning of each figure and the length 10?

2) the item of key "profiles" contains so many seller-buyer pairs, is each seller-buyer pair a observation of the simulation?

Thank you very much.

erikbrinkman commented 3 years ago

The third example worked for me by default. The second example seems to not work because of an api change I imagine I made. Instead of taking the game configuration from the game json, it need to be passed in separately. Running this to pass in the appropriate configuration then works mostly:

egta quiesce 'sim:game:cdasim/small_game.json,command:python3 cdasim/sim
.py 1 --single,conf:'<(jq .configuration cdasim/small_game.json)

But still results in a cancelled error for me. My guess is the cancelled error stems from changes in the way asyncio works now versus when I wrote it, and I don't think I really have the bandwidth to dive in and figure out the issue as the "simulation scheduler" is pretty hacky in trying to use the stdout and in pipes for interprocess communication. If you want to achieve something like that, I think it makes more sense to just write the simulation in python an call the simsched operator directly without the process communication.

As for the game data itself, you are correct in the strategy and number of agents. The fact that there are 10 floats indicates that this is a "Sample Game" i.e. a game with several samples of the payoff for that profile. Often in simulation games, we don't know the expected value of the payoff, but rather just have samples, or a way of sampling them from a complex distribution. In this case, the 10 floats represent 10 different payoff values. To treat this as a standard game you'd just take the mean of those values, but depending on what you're doing, other statistics such as the variance, or using the payoffs to bootstrap statistics is also useful.

andrealbh commented 3 years ago

Sorry but I still have some questions on the game data. Is it the simulation result of a multi-step trading game of maybe a cda? Is each seller/buyer pair denotes the result of a trading node?

I am trying to make my question clear because I am considering can I generate a json file to replicate your work. That's why I want to understand the json file structure.

In the game data, the basic format is Profile: seller [seller strategy [10 floats]], buyer [buyer strategy[10 floats]],and there are n such a seller-buyer pairs. Is the number of seller-buyer pairs, i.e. n, represents the number of trading nodes of the game, i.e. the length of the game? And does the 10 floats represent the 10 simulations were done? And why the agents using same strategy share the same 10payoff values? Do they do the same action at each node?

Thank you very much if there are any instructions on generate the data.json file.

erikbrinkman commented 3 years ago

The data comes from a simple cda simulation that you can see in the code cdasim/sim.py. The game data is based off of another project called gameanalysis. That project has a better description of the game data as well as python utilities to read it, write it, and find equilibria in role-symmetric games. This tool uses that project for most of the backend computation.

The agents in the game don't represent nodes in a game, they represent policies essentially. In this specific game there are two roles, a buyer or a seller. You can think of those as discrete classes of agents with different abilities. Within a role, there are strategies (or policies) that describe how that agent behaves at a node in the game, in rl terms, the distribution over actions conditioned on state, observation, etc. In this setup, if two agents adopt the same strategy / policy, they have the same expected payoff, even if in simulation they may get a different (potentially correlated) sample.

The number of items in that list is a function of the number of discrete strategies being played. Say in the cda example there were 10 buys playing strategy b1 and 10 sellers playing strategy b2, then there'd just be two profiles in that list [seller, s1, ...], [buyer, b1, ...].

The length of 10 is just the number of samples, e.g. the number of games that were played. If you look at game analysis there are two different types of games, a payoff game that will just have a float there as we only store the expected payoff, and a sample payoff game that will have all samples. As I mentioned earlier, for convenience, even in a sample payoff game, we'll usually take the mean of the payoffs for different agents playing the same strategy, as that mean is an unbiased estimate of the expected payoff for choosing that strategy in that profile.

andrealbh commented 3 years ago

The data comes from a simple cda simulation that you can see in the code cdasim/sim.py. The game data is based off of another project called gameanalysis. That project has a better description of the game data as well as python utilities to read it, write it, and find equilibria in role-symmetric games. This tool uses that project for most of the backend computation.

The agents in the game don't represent nodes in a game, they represent policies essentially. In this specific game there are two roles, a buyer or a seller. You can think of those as discrete classes of agents with different abilities. Within a role, there are strategies (or policies) that describe how that agent behaves at a node in the game, in rl terms, the distribution over actions conditioned on state, observation, etc. In this setup, if two agents adopt the same strategy / policy, they have the same expected payoff, even if in simulation they may get a different (potentially correlated) sample.

The number of items in that list is a function of the number of discrete strategies being played. Say in the cda example there were 10 buys playing strategy b1 and 10 sellers playing strategy b2, then there'd just be two profiles in that list [seller, s1, ...], [buyer, b1, ...].

The length of 10 is just the number of samples, e.g. the number of games that were played. If you look at game analysis there are two different types of games, a payoff game that will just have a float there as we only store the expected payoff, and a sample payoff game that will have all samples. As I mentioned earlier, for convenience, even in a sample payoff game, we'll usually take the mean of the payoffs for different agents playing the same strategy, as that mean is an unbiased estimate of the expected payoff for choosing that strategy in that profile.

Thank you for your explanation. I am trying to do it. However I tried to re-format the output of my own simulator to a qualified json file and run the command like example 1, but it said the profile cannot have entirely nan payoff. I have checked the all payoffs stored in the json file are float. I am really uncertain why it failed. Much appreciate if you are willing to help to examine the josn file. I uploaded to the my forked quiesce repo and named test_data.json

And also i tried to modify data_game.json file. In it, the item of key 'profiles' is a list with 1225 length. If I split it and reduce it to for example, 1000 length, the test also failed with error message profile cannot have entirely nan payoff. Why this happens?

erikbrinkman commented 3 years ago

You have a typo in the file, it should be called profiles not profile. You can use the gameanalysis cli to inspect how it loads the game, and trying to preserve it, i.e. convert it into itself and you see it's not picking up any data. I've updated the packages there and added some logging to help make this more obvious.

andrealbh commented 3 years ago

You have a typo in the file, it should be called profiles not profile. You can use the gameanalysis cli to inspect how it loads the game, and trying to preserve it, i.e. convert it into itself and you see it's not picking up any data. I've updated the packages there and added some logging to help make this more obvious.

Thank you for your help. My last question is that is there any thumb rule about the relationship between the number of agents, strategies and profiles? As I explained, if I reduce the number of profiles of data_game.json, the programme will fail.

erikbrinkman commented 3 years ago

The kind of games that this software is meant to handle is called "role symmetric". A game has of a set of R roles. The player in each role can be thought of as identical in the same was as a standard symmetric game, conditioned on the behavior of agents in other roles. Like a symmetric game, each role has a number of agents nᵣ, and a set of sᵣ strategies that agents in that role can play. In this setup the total number of profiles is ∏ᵣ(nᵣ + sᵣ - 1 choose nᵣ). Note that this notation is fairly general, a standard symmetric game can be represented with a single role, a standard asymmetric game has one role per player.

For the egta / quiesce routine to work with provided data, the game needs to be fully specified as without prior knowledge any profile may have support in an equilibrium. That's why there's a version that allows you to pass in a simulator. That way, the script will only sample payoffs of the profiles it thinks it needs to explore in the search for equilibria, rather than having to simulate them all up front, because, as you've seen, for any true game there are quite a lot profiles.

Also, if you're interested in this, I highly suggest you look into the more recent research of my group, as they've done more work beyond this, while I have moved on to other research areas, e.g. this paper.

andrealbh commented 3 years ago

Thank you for the help very much. Good luck with your research.