locked
Correlated TrueSkill RRS feed

  • Question

  • Hello,

    I'm trying to implement a simple modification of TrueSkill which estimates the full skills covariance matrix. Sadly, I'm getting a CompilationFailedException with an error about VectorGaussian.SampleFromMeanAndVariance.  Here's the short version of what I've tried:

                var prior = Variable.New<VectorGaussian>();
                var skills = Variable.Random<Vector, VectorGaussian>(prior);
                var performances = Variable.VectorGaussianFromMeanAndVariance(skills, PositiveDefiniteMatrix.IdentityScaledBy(2, 17));
                var schedule = Variable.New<Matrix>();
                var diff = Variable.MatrixTimesVector(schedule, performances);
    
                var range = new Range(1);
                var diffs = Variable.ArrayFromVector(diff, range);
                using (ForEachBlock rangeBlock = Variable.ForEach(range))
                {
                    Variable.ConstrainPositive(diffs[rangeBlock.Index]);
                }
    
                prior.ObservedValue = VectorGaussian.FromMeanAndVariance(Vector.FromArray(25, 25), PositiveDefiniteMatrix.IdentityScaledBy(2, 70));
                schedule.ObservedValue = new Matrix(new double[,] { { 1, -1 } });
    
                var engine = new InferenceEngine();
                var estimate = engine.Infer(skills);

    I wonder if anyone knows what I might be doing wrong here.

    Thanks,

    Allen

    Monday, May 19, 2014 10:39 PM

Answers

  • I recently tried to implement a full covariance TrueSkill. Note that this is not well tested, so if you spot any bugs, please let me know (-:

    /// <summary>
    /// TrueSkill with a multivariate Gaussian skill prior.
    /// </summary>
    internal class MultiTrueSkill
    {
    	#region Locals
    
    	/// <summary>
    	/// Gets or sets the mean of the player skill.
    	/// </summary>
    	private Variable<Vector> SkillMean { get; set; }
    
    	/// <summary>
    	/// Gets or sets the variance of the player skill.
    	/// </summary>
    	private Variable<PositiveDefiniteMatrix> SkillVariance { get; set; }
    
    	/// <summary>
    	/// Gets or sets the variance of the performance noise for each game.
    	/// </summary>
    	private Variable<double> PerformanceNoiseVariance { get; set; }
    
    	/// <summary>
    	/// Gets or sets the number of games played.
    	/// </summary>
    	private Variable<int> GameCount { get; set; }
    
    	/// <summary>
    	/// Gets or sets the winner and loser in each game.
    	/// </summary>
    	private VariableArray<Vector> Games { get; set; }
    
    	/// <summary>
    	/// Gets or sets the skills of the players.
    	/// </summary>
    	private Variable<Vector> PlayerSkills { get; set; }
    
    	/// <summary>
    	/// Gets or sets the uncertain player skills obtained after training.
    	/// </summary>
    	public VectorGaussian InferredPlayerSkills { get; set; }
    
    	#endregion
    
    	/// <summary>
    	/// Creates the Infer.NET model.
    	/// </summary>
    	/// <returns>The variables to infer.</returns>
    	protected override IVariable[] CreateModel()
    	{
    		// Define the number of games
    		this.GameCount = Variable.Observed(default(int)).Named("GameCount");
    		var game = new Range(this.GameCount).Named("game");
    		game.AddAttribute(new Sequential());
    
    		// Define the number of players
    		this.SkillMean = Variable.Observed(default(Vector)).Named("SkillMean");
    		this.SkillVariance = Variable.Observed(default(PositiveDefiniteMatrix)).Named("SkillVariance");
    
    		// Define the skill of each player
    		this.PlayerSkills = Variable.VectorGaussianFromMeanAndVariance(this.SkillMean, this.SkillVariance).Named("PlayerSkills");
    
    		// Define the observed game outcomes
    		this.Games = Variable.Observed(default(Vector[]), game).Named("Games");
    		this.PerformanceNoiseVariance = Variable.Observed(default(double)).Named("PerformanceNoiseVariance");
    
    		using (Variable.ForEach(game))
    		{
    			var gameOutcome = Variable.InnerProduct(this.PlayerSkills, this.Games[game]).Named("GameOutcome");
    			var noisyGameOutcome = Variable.GaussianFromMeanAndVariance(gameOutcome, this.PerformanceNoiseVariance).Named("NoisyGameOutcome");
    			Variable.ConstrainPositive(noisyGameOutcome);
    		}
    
    		return new IVariable[] { this.PlayerSkills };
    	}
    }

    Bear in mind that in order to make this work you need to set the observed value of Games to something like:

    var games = new Vector[instances.Count];
    for (int i = 0; i < instances.Count; ++i)
    {
        games[i] = Vector.Zero(playerCount);
        games[i][instances[i].Winner] = 1;
        games[i][instances[i].Loser] = -1;
    }
    • Marked as answer by achuang Thursday, May 29, 2014 11:03 PM
    Monday, May 19, 2014 11:16 PM