次の方法で共有


Infer.NET と確率的プログラミングを使用してゲーム マッチアップ リスト アプリを作成する

このハウツー ガイドでは、Infer.NET を使用した確率的プログラミングについて説明します。 確率論的プログラミングは、カスタム モデルをコンピューター プログラムとして表現する機械学習アプローチです。 これにより、モデルにドメイン知識を組み込み、機械学習システムをより解釈しやすくなります。 また、オンライン推論 (新しいデータが到着した場合の学習プロセス) もサポートしています。 Infer.NET は、Azure、Xbox、Bingの Microsoft のさまざまな製品で使用されています。

確率論的プログラミングとは

確率論的プログラミングを使用すると、実際のプロセスの統計モデルを作成できます。

前提条件

  • ローカル開発環境。

    このハウツー ガイドでは、開発に使用できるマシンがあることを想定しています。 10 分後の .NET チュートリアル Hello World には、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 モデルの簡略化されたバージョンであり、チーム、描画、その他の拡張機能もサポートしています。 このモデルの 高度なバージョン は、ベストセラーのゲーム タイトル Halo と Gears of War のマッチメイキングに使用されます。

推論されたプレイヤーのスキルと、その差異 (スキルに関する不確実性の尺度) を一覧表示する必要があります。

ゲーム結果のサンプル データ

ゲーム 勝者 敗者
1 プレイヤー 0 プレイヤー 1
2 プレイヤー 0 プレイヤー 3
3 プレイヤー 0 プレイヤー 4
4 プレイヤー 1 プレイヤー 2
5 プレイヤー 3 プレイヤー 1
6 プレイヤー 4 プレイヤー 2

サンプル データを詳しく見ると、プレイヤー 3 と 4 の両方に 1 つの勝利と 1 つの損失があることがわかります。 確率論的プログラミングを使用して、ランキングの外観を見てみましょう。 オフィスの対戦リストであっても開発者にとってはゼロベースなので、プレーヤーがゼロである点にも注意してください。

コードを記述する

モデルを設計したら、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 よりわずかに高いランクに設定されていることに注意してください。 これは、プレイヤー 1 に対するプレイヤー 3 の勝利が、プレイヤー 2 に対するプレイヤー 4 の勝利よりも重要であるためです。プレイヤー 1 はプレイヤー 2 を倒すことに注意してください。 プレイヤー0は全体的なチャンピオンです!

学習を続ける

統計モデルの設計は、それ自体がスキルです。 Microsoft Research Cambridge チームは無料の オンラインブックを作成しており、この記事を優しく紹介しています。 本書の第 3 章では、TrueSkill モデルについて詳しく説明します。 モデルを念頭に置いたら、Infer.NET Web サイトの 広範なドキュメント を使用して、モデルをコードに変換できます。

次のステップ

Infer.NET GitHub リポジトリを確認して、学習を続け、その他のサンプルを見つけてください。