チュートリアル: ML.NET でクラスタリングを使用してあやめの花を分類する

このチュートリアルでは、ML.NET を使ってあやめのデータ セットクラスタリング モデルを作成する方法を示します。

このチュートリアルでは、次の作業を行う方法について説明します。

  • 問題を把握する
  • 適切な機械学習タスクを選択する
  • データを準備する
  • データを読み込んで変換する
  • 学習アルゴリズムを選択する
  • モデルをトレーニングする
  • モデルを使用して予測を行う

必須コンポーネント

問題を把握する

この問題は、アヤメの花のセットを特徴に基づいて異なるグループに分類するというものです。 対象となる特徴は、がくの長さと幅および花弁の長さと幅です。 このチュートリアルでは、各花の種類は不明であるものとします。 特徴からデータ セットの構造を理解し、データのインスタンスがこの構造にどのように当てはまるかを予測します。

適切な機械学習タスクを選択する

各花がどのグループに属するかわからないので、教師なし機械学習タスクを選択します。 同じグループ内の要素同士の方が他のグループの要素より似ているようにデータ セットをグループに分割するので、クラスタリング機械学習タスクを使用します。

コンソール アプリケーションを作成する

  1. "IrisFlowerClustering" という名前の C# コンソール アプリケーションを作成します。 [次へ] をクリックします。

  2. 使用するフレームワークとして [.NET 6] を選択します。 [作成] ボタンをクリックします。

  3. プロジェクトに Data という名前のディレクトリを作成して、データ セットとモデルのファイルを保存します。

    ソリューション エクスプローラーで、プロジェクトを右クリックし、 [追加]>[新しいフォルダー] を選択します。 「Data」と入力して Enter キーを押します。

  4. Microsoft.ML NuGet パッケージをインストールします。

    注意

    このサンプルでは、特に明記されていない限り、記載されている最新の安定バージョンの NuGet パッケージを使用します。

    ソリューション エクスプローラーで、プロジェクトを右クリックし、 [NuGet パッケージの管理] を選択します。 [パッケージ ソース] として [nuget.org] を選択します。 [参照] タブを選択し、「Microsoft.ML」を検索し、 [インストール] ボタンを選択します。 [変更のプレビュー] ダイアログの [OK] を選択します。表示されているパッケージのライセンス条項に同意する場合は、 [ライセンスの同意] ダイアログの [同意する] を選択します。

データを準備する

  1. iris.data データ セットをダウンロードし、前の手順で作成した Data フォルダーに保存します。 あやめのデータ セットについて詳しくは、Wikipedia の「Iris flower data set」(あやめのデータ セット) のページと、データ セットのソースである「Iris Data Set」(あやめのデータ セット) のページをご覧ください。

  2. ソリューション エクスプローラーで、iris.data ファイルを右クリックして、 [プロパティ] を選択します。 [詳細設定] で、 [出力ディレクトリにコピー] の値を [新しい場合はコピーする] に変更します。

Iris.data ファイルには、次の値を表す 5 つの列が含まれます。

  • がくの長さ (センチメートル単位)
  • がくの幅 (センチメートル単位)
  • 花弁の長さ (センチメートル単位)
  • 花弁の幅 (センチメートル単位)
  • アヤメの種類

クラスタリングの例が目的なので、このチュートリアルでは最後の列を無視します。

データ クラスを作成する

入力データと予測のためのクラスを作成します。

  1. ソリューション エクスプローラーで、プロジェクトを右クリックし、 [追加]>[新しい項目] を選択します。

  2. [新しい項目の追加] ダイアログ ボックスで、 [クラス] を選択し、 [名前] フィールドを「IrisData.cs」に変更します。 次に [追加] を選択します。

  3. 以下の using ディレクティブを新しいファイルに追加します。

    using Microsoft.ML.Data;
    

既存のクラス定義を削除し、IrisData クラスと ClusterPrediction クラスを定義する次のコードを IrisData.cs ファイルに追加します。

public class IrisData
{
    [LoadColumn(0)]
    public float SepalLength;

    [LoadColumn(1)]
    public float SepalWidth;

    [LoadColumn(2)]
    public float PetalLength;

    [LoadColumn(3)]
    public float PetalWidth;
}

public class ClusterPrediction
{
    [ColumnName("PredictedLabel")]
    public uint PredictedClusterId;

    [ColumnName("Score")]
    public float[]? Distances;
}

IrisData は入力データ クラスであり、データ セットの各特徴の定義が含まれます。 データ セット ファイル内のソース列のインデックスを指定するには、LoadColumn 属性を使用します。

ClusterPrediction クラスは、IrisData インスタンスに適用されたクラスタリング モデルの出力を表します。 ColumnName 属性を使って、PredictedClusterId フィールドを PredictedLabel 列に、Distances フィールドを Score 列に、それぞれバインドします。 クラスタリング タスクの場合、これらの列には次の意味があります。

  • PredictedLabel 列には、予測されたクラスターの ID が含まれます。
  • Score 列には、クラスターの重心へのユークリッド距離を二乗した値の配列が含まれます。 配列の長さは、クラスターの数と同じです。

Note

入力データと予測データのクラス内の浮動小数点値を表すには、float 型を使います。

データおよびモデルのパスを定義する

Program.cs ファイルに戻り、データ セット ファイルと、モデルを保存するファイルへのパスを保持するために、2 つのフィールドを追加します。

  • _dataPath には、モデルのトレーニングに使用するデータ セットがあるファイルへのパスが含まれます。
  • _modelPath には、トレーニング済みモデルが格納されるファイルへのパスが含まれます。

次のコードを using ステートメントの下に追加して、これらのパスを指定します。

string _dataPath = Path.Combine(Environment.CurrentDirectory, "Data", "iris.data");
string _modelPath = Path.Combine(Environment.CurrentDirectory, "Data", "IrisClusteringModel.zip");

ML のコンテキストの作成

以下の追加の using ディレクティブを、Program.cs ファイルの先頭に追加します。

using Microsoft.ML;
using IrisFlowerClustering;

Console.WriteLine("Hello World!"); の行を次のコードに置き換えます。

var mlContext = new MLContext(seed: 0);

Microsoft.ML.MLContext クラスは機械学習環境を表し、ログ記録のメカニズムとデータの読み込みのエントリ ポイント、モデルのトレーニング、予測、およびその他のタスクを提供します。 これは、概念的には Entity Framework での DbContext の使用に相当します。

データの読み込みの設定

MLContext の下に次のコードを追加して、データを読み込む方法を設定します。

IDataView dataView = mlContext.Data.LoadFromTextFile<IrisData>(_dataPath, hasHeader: false, separatorChar: ',');

ジェネリック MLContext.Data.LoadFromTextFile 拡張メソッドは、指定された IrisData 型からデータ セット スキーマを推測し、IDataView を返します。これはトランスフォーマーの入力として使用できます。

学習パイプラインを作成する

このチュートリアルでは、クラスタリング タスクの学習パイプラインは、次の 2 つの手順で構成されています。

  • 読み込まれた列を、クラスタリング トレーナーによって使用される 1 つの Features 列に連結します。
  • KMeansTrainer トレーナーを使用して、K- 平均法++ クラスタリング アルゴリズムを使用するモデルをトレーニングします。

データの読み込み後に、次のものを追加します。

string featuresColumnName = "Features";
var pipeline = mlContext.Transforms
    .Concatenate(featuresColumnName, "SepalLength", "SepalWidth", "PetalLength", "PetalWidth")
    .Append(mlContext.Clustering.Trainers.KMeans(featuresColumnName, numberOfClusters: 3));

このコードは、データ セットを 3 つのクラスターに分割することを指定します。

モデルをトレーニングする

前のセクションで追加した手順では、トレーニング用にパイプラインを準備しましたが、トレーニングは実行されていません。 ファイルの末尾に次の行を追加して、データの読み込みとモデルのトレーニングを実行します。

var model = pipeline.Fit(dataView);

モデルを保存する

この時点で、既存または新規のどの .NET アプリケーションにも統合できるモデルができました。 モデルを .zip ファイルに保存するには、次のコードを Fit メソッドの呼び出しの下に追加します。

using (var fileStream = new FileStream(_modelPath, FileMode.Create, FileAccess.Write, FileShare.Write))
{
    mlContext.Model.Save(model, dataView.Schema, fileStream);
}

モデルを使用して予測を行う

予測を行うには、トランスフォーマー パイプラインを介して入力の型のインスタンスを受け取り、出力の型のインスタンスを生成する PredictionEngine<TSrc,TDst> クラスを使用します。 次の行を追加して、そのクラスのインスタンスを作成します。

var predictor = mlContext.Model.CreatePredictionEngine<IrisData, ClusterPrediction>(model);

PredictionEngine は、データの 1 つのインスタンスに対して予測を実行できる便利な API です。 PredictionEngine はスレッド セーフではありません。 シングル スレッド環境またはプロトタイプ環境で使用できます。 運用環境でパフォーマンスとスレッド セーフを向上させるには、PredictionEnginePool サービスを使用します。これにより、アプリケーション全体で使用するできる PredictionEngine オブジェクトの ObjectPool が作成されます。 ASP.NET Core Web API で PredictionEnginePool を使用する方法については、こちらのガイドを参照してください。

注意

PredictionEnginePool サービスの拡張機能は、現在プレビュー段階です。

テスト データのインスタンスを格納するための TestIrisData クラスを作成します。

  1. ソリューション エクスプローラーで、プロジェクトを右クリックし、 [追加]>[新しい項目] を選択します。

  2. [新しい項目の追加] ダイアログ ボックスで、 [クラス] を選択し、 [名前] フィールドを「TestIrisData.cs」に変更します。 次に [追加] を選択します。

  3. 次の例に示すように、静的になるようにクラスを変更します。

    static class TestIrisData
    

このチュートリアルでは、このクラスで 1 つのあやめのデータ インスタンスを示します。 他のシナリオを追加してモデルで実験できます。 TestIrisData クラスに次のコードを追加します。

internal static readonly IrisData Setosa = new IrisData
{
    SepalLength = 5.1f,
    SepalWidth = 3.5f,
    PetalLength = 1.4f,
    PetalWidth = 0.2f
};

指定した項目が属するクラスターを発見するには、Program.cs ファイルに戻り、次のコードをファイルの末尾に追加します。

var prediction = predictor.Predict(TestIrisData.Setosa);
Console.WriteLine($"Cluster: {prediction.PredictedClusterId}");
Console.WriteLine($"Distances: {string.Join(" ", prediction.Distances ?? Array.Empty<float>())}");

プログラムを実行し、指定したデータ インスタンスが含まれるクラスターと、そのインスタンスからクラスターの重心までの平方距離を確認します。 結果は以下のようになるはずです。

Cluster: 2
Distances: 11.69127 0.02159119 25.59896

おめでとうございます! これで、アヤメのクラスタリングの機械学習モデルを作成し、それを使用して予測を行うことができました。 このチュートリアルのソース コードは、dotnet/samples GitHub リポジトリで確認できます。

次の手順

このチュートリアルでは、次の作業を行う方法を学びました。

  • 問題を把握する
  • 適切な機械学習タスクを選択する
  • データを準備する
  • データを読み込んで変換する
  • 学習アルゴリズムを選択する
  • モデルをトレーニングする
  • モデルを使用して予測を行う

学習を続けてその他のサンプルを確認するには、GitHub リポジトリをご覧ください。