Creare un'app elenco di corrispondenze di gioco con Infer.NET e la programmazione probabilistica
Questa guida pratica descrive la programmazione probabilistica tramite Infer.NET. La programmazione probabilistica è un approccio di apprendimento automatico in cui modelli personalizzati vengono espressi come programmi. Permette di integrare informazioni specifiche di un dominio nei modelli e rendere il sistema di apprendimento automatico maggiormente interpretabile. Supporta anche l'inferenza online, ovvero il processo di apprendere man mano che arrivano nuovi dati. Infer.NET viene usato in diversi prodotti Microsoft, tra cui Azure, Xbox e Bing.
Che cos'è la programmazione probabilistica?
La programmazione probabilistica permette di creare modelli statistici di processi reali.
Prerequisiti
Ambiente di sviluppo locale,
Questa guida pratica presuppone la presenza di un computer che possa essere usato per lo sviluppo. L'esercitazione .NET Hello World in 10 minuti contiene le istruzioni per configurare l'ambiente di sviluppo locale in macOS, Windows o Linux.
Creazione dell'app
Aprire un nuovo prompt dei comandi ed eseguire i comandi seguenti:
dotnet new console -o myApp
cd myApp
Il comando dotnet
crea un'applicazione new
di tipo console
. Il parametro -o
crea una directory denominata myApp
in cui viene archiviata l'app, popolata con i file necessari. Il comando cd myApp
permette di passare alla directory dell'app appena creata.
Installare il pacchetto Infer.NET
Per usare Infer.NET, è necessario installare il pacchetto Microsoft.ML.Probabilistic.Compiler
. Al prompt dei comandi eseguire il comando seguente:
dotnet add package Microsoft.ML.Probabilistic.Compiler
Progettare il modello
L'esempio usa partite di ping pong o calcio giocate in ufficio. Sono disponibili i partecipanti e il risultato di ogni partita. Si vogliono dedurre le abilità del giocatore da questi dati. Presupporre che ogni giocatore abbia un'abilità latente normalmente distribuita e che le sue prestazioni in una partita specifica siano una versione accentuata di questa abilità. I dati vincolano le prestazioni del vincitore come migliori delle prestazioni del giocatore sconfitto. Si tratta di una versione semplificata del celebre modello TrueSkill, che supporta anche squadre, pareggi e altre estensioni. Una versione avanzata di questo modello viene usata per il matchmaking nei vendutissimi titoli Halo e Gears of War.
È necessario elencare le abilità del giocatore dedotte, insieme alla rispettiva varianza, ovvero la misura di incertezza riguardo alle abilità.
Dati di esempio dei risultati di gioco
Gioco | Vincitori | Sconfitti |
---|---|---|
1 | Giocatore 0 | Giocatore 1 |
2 | Giocatore 0 | Giocatore 3 |
3 | Giocatore 0 | Giocatore 4 |
4 | Giocatore 1 | Giocatore 2 |
5 | Giocatore 3 | Giocatore 1 |
6 | Giocatore 4 | Giocatore 2 |
Osservando più attentamente i dati di esempio, si noterà che i giocatori 3 e 4 hanno entrambi una vittoria e una sconfitta. Si osserveranno ora le classificazioni usando la programmazione probabilistica. Si noti anche la presenza di un giocatore 0, perché gli elenchi di corrispondenze sono in base zero per gli sviluppatori.
Scrivere codice
Dopo aver progettato il modello, è possibile esprimerlo come programma probabilistico tramite l'API di modellazione Infer.NET. Aprire Program.cs
nell'editor di testo preferito e sostituire tutto il contenuto con il codice seguente:
namespace myApp
{
using System;
using System.Linq;
using Microsoft.ML.Probabilistic;
using Microsoft.ML.Probabilistic.Distributions;
using Microsoft.ML.Probabilistic.Models;
class Program
{
static void Main(string[] args)
{
// The winner and loser in each of 6 samples games
var winnerData = new[] { 0, 0, 0, 1, 3, 4 };
var loserData = new[] { 1, 3, 4, 2, 1, 2 };
// Define the statistical model as a probabilistic program
var game = new Range(winnerData.Length);
var player = new Range(winnerData.Concat(loserData).Max() + 1);
var playerSkills = Variable.Array<double>(player);
playerSkills[player] = Variable.GaussianFromMeanAndVariance(6, 9).ForEach(player);
var winners = Variable.Array<int>(game);
var losers = Variable.Array<int>(game);
using (Variable.ForEach(game))
{
// The player performance is a noisy version of their skill
var winnerPerformance = Variable.GaussianFromMeanAndVariance(playerSkills[winners[game]], 1.0);
var loserPerformance = Variable.GaussianFromMeanAndVariance(playerSkills[losers[game]], 1.0);
// The winner performed better in this game
Variable.ConstrainTrue(winnerPerformance > loserPerformance);
}
// Attach the data to the model
winners.ObservedValue = winnerData;
losers.ObservedValue = loserData;
// Run inference
var inferenceEngine = new InferenceEngine();
var inferredSkills = inferenceEngine.Infer<Gaussian[]>(playerSkills);
// The inferred skills are uncertain, which is captured in their variance
var orderedPlayerSkills = inferredSkills
.Select((s, i) => new { Player = i, Skill = s })
.OrderByDescending(ps => ps.Skill.GetMean());
foreach (var playerSkill in orderedPlayerSkills)
{
Console.WriteLine($"Player {playerSkill.Player} skill: {playerSkill.Skill}");
}
}
}
}
Eseguire l'app
Al prompt dei comandi eseguire il comando seguente:
dotnet run
Risultati
I risultati saranno simili ai seguenti:
Compiling model...done.
Iterating:
.........|.........|.........|.........|.........| 50
Player 0 skill: Gaussian(9.517, 3.926)
Player 3 skill: Gaussian(6.834, 3.892)
Player 4 skill: Gaussian(6.054, 4.731)
Player 1 skill: Gaussian(4.955, 3.503)
Player 2 skill: Gaussian(2.639, 4.288)
Nei risultati si noti che in base al modello il giocatore 3 è in posizione leggermente superiore rispetto al giocatore 4. Il motivo è che la vittoria del giocatore 3 sul giocatore 1 è più significativa rispetto alla vittoria del giocatore 4 sul giocatore 2: notare infatti che il giocatore 1 batte il giocatore 2. Il giocatore 0 è il campione assoluto.
Per continuare ad apprendere
La progettazione di modelli statistici è una competenza di per sé. Il team di Microsoft Research Cambridge ha redatto un libro online gratuito, che offre una pratica introduzione all'articolo. Il capitolo 3 di questo libro descrive più dettagliatamente il modello TrueSkill. Dopo aver ideato un modello, è possibile trasformarlo in codice usando la vasta documentazione nel sito Web Infer.NET.
Passaggi successivi
Visitare il repository GitHub per Infer.NET per continuare ad acquisire familiarità e trovare altri esempi.