本作指南會教導您使用 Infer.NET 進行概率程序設計。 概率程式設計是一種機器學習方法,其中自定義模型會以計算機程式表示。 它允許在模型中納入領域知識,並讓機器學習系統更容易解譯。 它也支援線上推斷——隨著新數據到達時進行學習的過程。 Infer.NET 用於 Azure、Xbox 和 Bing Microsoft的各種產品。
什麼是概率程序設計?
概率程序設計可讓您建立真實世界進程的統計模型。
先決條件
本機開發環境。
說明指南預期您有一台可以用於開發的機器。 .NET 教學課程 Hello World 在 10 分鐘內 提供在 macOS、Windows 或 Linux 上設定本機開發環境的指示。
建立您的應用程式
開啟新的指令提示字元,然後執行下列命令:
dotnet new console -o myApp
cd myApp
使用 dotnet
命令來建立一個類型為 new
的 console
應用程式。 參數 -o
會建立名為 myApp
的目錄,其中儲存您的應用程式,並填入所需的檔案。 命令 cd myApp
會將您放入新建立的應用程式目錄。
安裝 Infer.NET 套件
若要使用 Infer.NET,您必須安裝 Microsoft.ML.Probabilistic.Compiler
套件。 在命令提示字元中,執行下列命令:
dotnet add package Microsoft.ML.Probabilistic.Compiler
或者,在 .NET 10及以上:
dotnet package add Microsoft.ML.Probabilistic.Compiler
設計模型
範例使用在辦公室舉行的乒乓球或桌上足球比賽。 您掌握每場比賽的參與者和結果。 您想要從此數據推斷玩家的技能。 假設每個玩家都有一個正態分佈的潛在技能,而他們的比賽表現是這個技能的帶有雜訊的版本。 數據會限制優勝者的表現大於輸家的表現。 這是熱門 TrueSkill 模型的簡化版本,也支援小組、繪圖和其他延伸模組。 此模型的進階版本用於熱門遊戲《光環》和《戰爭機器》的配對。
您需要列出推斷的球員技能,以及其變異數 – 技能的不確定性量值。
遊戲結果範例數據
遊戲 | 勝利者 | 失敗者 |
---|---|---|
1 | 玩家 0 | 玩家 1 |
2 | 玩家 0 | 玩家 3 |
3 | 玩家 0 | 玩家 4 |
4 | 玩家 1 | 玩家 2 |
5 | 玩家 3 | 玩家 1 |
6 | 玩家 4 | 玩家 2 |
仔細看看範例數據,您會發現球員 3 和 4 都有一勝一負。 讓我們看看使用概率編程排名會是什麼樣子。 另請注意,也有玩家零,因為即使是辦公室的配對列表對於我們開發人員來說也是從零開始計數的。
撰寫一些程序代碼
設計模型之後,是時候使用 Infer.NET 模型 API 將它表示為概率程式。 在慣用的文字編輯器中開啟 Program.cs
,並以下列程序代碼取代其所有內容:
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}");
}
}
}
}
執行您的應用程式
在命令提示字元中,執行下列命令:
dotnet run
結果
您的結果應該如下所示:
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)
在結果中,請注意,根據模型,玩家 3 排名略高於玩家 4。 這是因為球員 3 戰勝球員 1 的勝利比球員 4 勝 2 更重要 , 請注意, 球員 1 擊敗球員 2。 玩家 0 是整體冠軍!
持續學習
設計統計模型是一種技能。 Microsoft研究劍橋團隊已經寫了一本免費的線上書籍,該書對這篇文章進行了簡要介紹。 這本書的第 3 章更詳細地涵蓋了 TrueSkill 模型。 一旦您有模型,就可以使用 Infer.NET 網站上的 大量檔 ,將模型轉換成程序代碼。
後續步驟
請查看 Infer.NET GitHub 存放庫,以繼續學習並尋找更多範例。