本文介紹瞭如何使用 Infer.NET 進行機率性編程。 機率性編程是一種將自定義模型表示爲計算機程序的機器學習方法。 藉助它能夠在模型中包含專業知識,使機器學習系統更易理解。 它還支持在線推斷,即在新數據到達時進行學習的過程。 Azure、Xbox 及必應中的多種 Microsoft 產品均使用了 Infer.NET。編程
基於機率性編程,建立對真實世界過程的統計模型。app
本地.NET開發環境設置機器學習
dotnet new console -o myApp
cd myApp
dotnet
命令將建立 console
類型的 new
應用程序。 -o
參數將建立名稱爲 myApp
的目錄,會在其中存儲應用並填充所需的文件。 cd myApp
命令會將你轉到新建立的應用目錄。編輯器
需安裝 Microsoft.ML.Probabilistic.Compiler
包才能使用 Infer.NET。 在命令提示符中運行下面的命令:學習
dotnet add package Microsoft.ML.Probabilistic.Compiler
示例使用在室內中進行的乒乓球或桌上足球比賽。 咱們具備參賽者的信息和每場比賽的結果。 咱們想要經過此數據推斷玩家的實力。 假設每位玩家的潛在實力呈正態分佈,且他們在給定比賽中的表現是此實力受干擾後的狀態。數據被設定的約束條件是贏家的表現大於輸家的表現。 這是熱門的 TrueSkill 模型的簡化版,此模型也支持團隊、平局及其餘擴展項。 熱銷的 Halo 和 Gears of War 遊戲中的比賽安排使用了此模型的高級版。ui
咱們須要列出所推斷玩家的實力以及他們的差別(衡量實力的不肯定性)。this
遊戲結果示例數據編碼
遊戲 | 勝者 | 敗者 |
---|---|---|
1 | 玩家 0 | 玩家 1 |
2 | 玩家 0 | 玩家 3 |
3 | 玩家 0 | 玩家 4 |
4 | 玩家 1 | 玩家 2 |
5 | 玩家 3 | 玩家 1 |
6 | 玩家 4 | 玩家 2 |
仔細觀察樣本數據,你會發現玩家3和4都有1次勝利和1次失敗。 讓咱們看看使用機率編程的排名是什麼樣的。另請注意基於咱們開發的編碼習慣,玩家編號是從零開始的,即便是室內遊戲匹配列表也是從零開始的。spa
設計模型後,就可使用 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是總冠軍!