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

Usage help: observed data #944

Open
fralik opened this issue Aug 16, 2022 · 2 comments
Open

Usage help: observed data #944

fralik opened this issue Aug 16, 2022 · 2 comments

Comments

@fralik
Copy link

fralik commented Aug 16, 2022

Hi!
I would like to model a process very similar to what is described Probabilistic Models of Cognition under the name of Tug of War.

There is a game involving two players. The outcome is always either a win or loss. Each player has some internal strength. Probability of winning player1 over player2 is given as P_ij = strength_i - strength_j.

I have historic data of outcomes for several players and would like to find out each player strength.

If I use PyMC, then the modelling goes like this:

model = pm.Model()
with model:
    strength = pm.Normal("strength", 0, 1, shape=num_players)
    diffs = strength[games.Player1] - strength[games.Player2]
    obs = pm.Bernoulli("wins", logit_p=diffs, observed=games.Player1Wins)
    trace = pm.sample()

where games is a table with 3 columns. Player1 - id of the first player. Player2 - id of the second player. Player1Wins - 1 if player one wins, 0 otherwise.

I tried to come up with that in WebPPL:

var model = function() {
  var strength = mem(function (person) {return gaussian(0, 1)})
  var winner = function (player1, player2) {
    strength(player1) > strength(player2) ? player1 : player2 }
  var beat = function(player1,player2){winner(player1,player2) == player1}

  mapData({data: [
    ['Player-2', 'Player-1'],
    ['Player-3', 'Player-1'],
    ['Player-3', 'Player-2'],
    ['Player-2', 'Player-1'],
    ['Player-3', 'Player-1'],
    ['Player-2', 'Player-1'],
    ['Player-4', 'Player-3'],
    ['Player-4', 'Player-3'],
  ]}, function (gameOutcome) {
    condition(beat(gameOutcome0], gameOutcome[1]))
  })

  return strength('Player-1')
}

var dist = Infer({method: 'MCMC', kernel: 'MH', samples: 100},
                 model)

print('Expected strength: ' + expectation(dist[0]))
viz(dist)

I have a couple of questions regarding this code:

  1. Does it seems right to provide observable data the way I did?
  2. I am unsure how to obtain strength of all players in one go. Names and number of players will be dynamic, I do not know it beforehand.
@fralik
Copy link
Author

fralik commented Aug 17, 2022

I think I found a way of providing the data that is more similar to PyMC:

var model = function() {
  var strength = mem(function (person) {return gaussian(0, 1)})
  var p_win = function(p1, p2) {
    strength(p1) - strength(p2)
  }
  var sigmoid = function(x) {
    return 1 / (1 + Math.exp(-1 * x))
  }
  
  mapData({data: [
    ['Player-1', 'Player-2', 0],
    ['Player-1', 'Player-3', 0],
    ['Player-2', 'Player-3', 0],
    ['Player-1', 'Player-2', 0],
    ['Player-3', 'Player-1', 1],
    ['Player-2', 'Player-1', 1],
    ['Player-4', 'Player-3', 1],
    ['Player-4', 'Player-3', 1],
  ]}, function (gameOutcome) {
    var logit = p_win(gameOutcome[0], gameOutcome[1])
    var firstWon = gameOutcome[2] == 1 ? true : false
    factor(Bernoulli({p: sigmoid(logit)}).score(firstWon))
  })

  return strength('Player-1')
}

var dist = Infer({method: 'MCMC', kernel: 'MH', samples: 8000}, model)

Still it is not clear to me how to obtain/work with strengths of all players.

@ngoodman
Copy link
Contributor

it may be helpful to use observe instead of factor plus score (though it does something very similar).

you can return the object of all strengths ({player1: strength('Player-1'), player2: ...}) and then eg use viz.marginals` to examine them. some of the examples in the learning as inference section of probmods should help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants