Answered by:
Correlated trueskill with poisson(exp(skill difference)) factor?

Question
-
Each player has both offence and defence rating.
My prior X (Variable<Vector>) is a multivariate normal variable of 2* N variables, which is of the form (o1, o2, ... oN, d1, d2, .. dN) where N is the number of players, o1 is offence rating of player1, dN is defence rating of playerN.
Each match has 2 outcomes which is similar to basketball scores, which is assumed to be of Poisson (Exp (oA - dB)), and Poisson(Exp (oB - dA)).
So far, I have encountered such problems:
1. I need to build a factor to represent oA - dB, so I guess it is just a matrix M times X, where M is of the form
(1, 0, 0, ..., 0, -1, -1,..., -1)
(0, 1, 0, ..., 0, -1, -1,..., -1)
...
(0, 0, 0, ...1, 0, -1, -1,..., -1)
(0, 0, 0, ...0, 1, -1, -1,..., -1)
So that the result of multiplication is
(o1 - d1, o1 - d2, ... o1 - dN)
...
(oN - d1, oN - d2, ... oN - dN)
So my Matrix is
myMatrix =
let left = Array2D.init N N (fun i j -> if i = j then 1.0 else 0.0)
let right = Array2D.create N N -1.0
let ret = Array2D.init N (2 * N) (fun i j -> if j < N then left.[i,j] else right.[i, j-N])
new Matrix(ret)when I would like to apply the factor, I tried:
let B = Variable.MatrixTimesVector(myMatrix, X)
It doesn't work since myMatrix is not of type Variable<Matrix>
I also tried let B = Variable.Factor(Factor.Product, myMatrix, X), it doesn't work.
2. I am unable to apply Poisson (Exp (..) ) factor to B piecewisely. Do I have to convert the matrix variable B into VarrayArray and then apply the factor?I know I can convert a Variable<Vector> into VariableArray via Variable.ArrayFromVector, but not for a Matrix. Maybe I should convert the prior X into Variable<Vector> in the first place?
- Edited by colinfang Wednesday, October 8, 2014 12:39 PM
Wednesday, October 8, 2014 12:14 PM
Answers
-
You can do it like this:
var indexA = Variable.Observed(0); var indexB = Variable.Observed(1); Range r = new Range(4); var indicesAB = Variable.Array<double>(r); using (var fb = Variable.ForEach(r)) { var i = fb.Index; var isA = (i == indexA) & true; using (Variable.If(isA)) { indicesAB[i] = 1; } using (Variable.IfNot(isA)) { var isB = (i == indexB) & true; using (Variable.If(isB)) { indicesAB[i] = -1; } using (Variable.IfNot(isB)) { indicesAB[i] = 0; } } } var indicesABVector = Variable.Vector(indicesAB); InferenceEngine engine = new InferenceEngine(); Console.WriteLine(engine.Infer(indicesABVector));
The silly '& true' bits are to work-around a bug in the current version of Infer.NET.- Marked as answer by colinfang Thursday, October 9, 2014 10:17 PM
Thursday, October 9, 2014 5:28 PMOwner
All replies
-
To get oA-dB, use Variable.InnerProduct. Make a Vector containing a 1 at A, -1 at B, and rest zero. Matrix multiply doesn't help you here.Wednesday, October 8, 2014 12:32 PMOwner
-
This post might be useful.Wednesday, October 8, 2014 2:02 PM
-
scoreA.[rangeMatches] <- Variable.Poisson (Variable.Exp (Variable.InnerProduct(od, indicesABVector.[rangeMatches]) ))
scoreB.[rangeMatches] <- Variable.Poisson (Variable.Exp (Variable.InnerProduct(od, indicesBAVector.[rangeMatches]) ))
where od is the multivariate normal variable, indicesABVector is a VariableArray<Vector>, 1 at A and -1 at B, rest zero.
Currently I set the observedvalues of both manually,
let buildIndicesABVector game =
let indexA = nameIndex.[game.PlayerA]
let indexB = nameIndex.[game.PlayerB]
let ret = Array.zeroCreate (2 * numPlayers)
ret.[indexA] <- 1.0
ret.[indexB + numPlayers] <- -1.0
Vector.FromArray(ret)
let buildIndicesBAVector game =
let indexA = nameIndex.[game.PlayerA]
let indexB = nameIndex.[game.PlayerB]
let ret = Array.zeroCreate (2 * numPlayers)
ret.[indexB] <- 1.0
ret.[indexA + numPlayers] <- -1.0
Vector.FromArray(ret)
indicesABVector.ObservedValue <- matches |> Array.map buildIndicesABVector
indicesBAVector.ObservedValue <- matches |> Array.map buildIndicesBAVector
Suppose if I have VariableArray<int> indexA, VariableArray<int> indexB, which are to be observed. Is it possible to define indicesABVector from indexA and indexB? If it is possible, it seems better than the above approach.
- Edited by colinfang Thursday, October 9, 2014 3:53 PM
Thursday, October 9, 2014 3:47 PM -
You can do it like this:
var indexA = Variable.Observed(0); var indexB = Variable.Observed(1); Range r = new Range(4); var indicesAB = Variable.Array<double>(r); using (var fb = Variable.ForEach(r)) { var i = fb.Index; var isA = (i == indexA) & true; using (Variable.If(isA)) { indicesAB[i] = 1; } using (Variable.IfNot(isA)) { var isB = (i == indexB) & true; using (Variable.If(isB)) { indicesAB[i] = -1; } using (Variable.IfNot(isB)) { indicesAB[i] = 0; } } } var indicesABVector = Variable.Vector(indicesAB); InferenceEngine engine = new InferenceEngine(); Console.WriteLine(engine.Infer(indicesABVector));
The silly '& true' bits are to work-around a bug in the current version of Infer.NET.- Marked as answer by colinfang Thursday, October 9, 2014 10:17 PM
Thursday, October 9, 2014 5:28 PMOwner