Tutorial: Kategorisieren von Schwertlilien unter Verwendung eines k-Means-Algorithmus mit ML.NET

Dieses Tutorial zeigt, wie Sie mit ML.NET ein Clusteringmodell für das Schwertlilien-Dataset erstellen.

In diesem Tutorial lernen Sie, wie die folgenden Aufgaben ausgeführt werden:

  • Das Problem verstehen
  • Auswählen der entsprechenden Machine Learning-Aufgabe
  • Vorbereiten der Daten
  • Laden und Transformieren der Daten
  • Auswählen eines Lernalgorithmus
  • Trainieren des Modells
  • Verwenden des Modells für Vorhersagen

Voraussetzungen

Das Problem verstehen

Bei diesem Problem geht es darum, Schwertlilien anhand ihrer Blütenmerkmale in unterschiedliche Gruppen einzuteilen. Die entsprechenden Merkmale sind Länge und Breite des Kelchblatts sowie Länge und Breite des Kronblatts. Für dieses Tutorial wird angenommen, dass der Typ jeder Blume unbekannt ist. Sie werden die Struktur eines Datasets basierend auf Merkmalen kennenlernen und vorhersagen können, wie eine Dateninstanz in diese Struktur passt.

Auswählen der entsprechenden Machine Learning-Aufgabe

Da Sie nicht wissen, zu welcher Gruppe jede Blume gehört, wählen Sie die Aufgabe Unüberwachtes maschinelles Lernen aus. Um ein Dataset so in Gruppen zu unterteilen, dass Elemente in derselben Gruppe einander ähnlicher sind als in anderen Gruppen, verwenden Sie eine Clustering-Aufgabe für maschinelles Lernen.

Erstellen einer Konsolenanwendung

  1. Erstellen Sie eine C#-Konsolenanwendung mit dem Namen „IrisFlowerClustering“. Klicken Sie auf die Schaltfläche Weiter.

  2. Wählen Sie .NET 6 als zu verwendendes Framework aus. Klicken Sie auf die Schaltfläche Erstellen .

  3. Erstellen Sie ein Verzeichnis mit dem Namen Data in Ihrem Projekt, um das Dataset und die Modelldateien zu speichern:

    Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und wählen Sie Hinzufügen>Neuer Ordner aus. Geben Sie „Data“ ein, und drücken Sie die EINGABETASTE.

  4. Installieren Sie das NuGet-Paket Microsoft.ML:

    Hinweis

    In diesem Beispiel wird, sofern nicht anders angegeben, die neueste stabile Version der genannten NuGet-Pakete verwendet.

    Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und wählen Sie NuGet-Pakete verwalten aus. Wählen Sie als Paketquelle „nuget.org“ aus. Klicken Sie dann auf die Registerkarte Durchsuchen, suchen Sie nach Microsoft.ML, und klicken Sie anschließend auf Installieren. Wählen Sie die Schaltfläche OK im Dialogfeld Vorschau der Änderungen und dann die Schaltfläche Ich stimme zu im Dialogfeld Zustimmung zur Lizenz aus, wenn Sie den Lizenzbedingungen für die aufgelisteten Pakete zustimmen.

Vorbereiten der Daten

  1. Laden Sie das Dataset iris.data herunter und speichern Sie es im Ordner Data, den Sie im vorherigen Schritt erstellt haben. Weitere Informationen zum Schwertlilien-Dataset finden Sie im englischen Wikipedia-Artikel Iris flower data set und auf der Website Iris Data Set, der Quelle des Datasets.

  2. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf die Datei iris.data, und wählen Sie Eigenschaften aus. Ändern Sie unter Erweitert den Wert von In Ausgabeverzeichnis kopieren in Kopieren, wenn neuer.

Die Datei iris.data enthält fünf Spalten, die Folgendes darstellen:

  • Kelchblattlänge in Zentimetern
  • Kelchblattbreite in Zentimetern
  • Kronblattlänge in Zentimetern
  • Kronblattbreite in Zentimetern
  • Schwertlilienart

Für das Clusteringbeispiel wird in diesem Tutorial die letzte Spalte ignoriert.

Erstellen von Datenklassen

Erstellen Sie Klassen für die Eingabedaten und die Vorhersagen:

  1. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und wählen Sie dann Hinzufügen>Neues Element aus.

  2. Wählen Sie im Dialogfeld Neues Element hinzufügen die Option Klasse aus, und ändern Sie das Feld Name in IrisData.cs. Wählen Sie dann die Schaltfläche Hinzufügen aus.

  3. Fügen Sie der neuen Datei die folgenden using-Anweisungen hinzu:

    using Microsoft.ML.Data;
    

Entfernen Sie die vorhandene Klassendefinition, und fügen Sie der Datei IrisData.cs den folgenden Code hinzu, der die Klassen IrisData und ClusterPrediction definiert:

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 ist die Eingabedatenklasse und verfügt über Definitionen für jedes Merkmal im Dataset. Verwenden Sie das Attribut LoadColumn, um die Indizes der Quellspalten in der Datasetdatei festzulegen.

Die Klasse ClusterPrediction repräsentiert die Ausgabe des Clusteringmodells, das auf eine IrisData-Instanz angewendet wird. Verwenden Sie das Attribut ColumnName, um die Felder PredictedClusterId und Distances an die Spalten PredictedLabel bzw. Score zu binden. Bei der Clusteringaufgabe haben diese Spalten die folgende Bedeutung:

  • Die Spalte PredictedLabel enthält die ID des vorhergesagten Clusters.
  • Die Spalte Score enthält ein Array mit den quadratischen euklidischen Abständen zum Clusterschwerpunkt. Die Arraylänge ist gleich der Anzahl von Clustern.

Hinweis

Verwenden Sie den Typ float, um Gleitkommawerte in den Eingabe- und Vorhersagedatenklassen darzustellen.

Definieren von Daten und Modellpfaden

Wechseln Sie zurück zur Datei Program.cs, und fügen Sie zwei Felder hinzu, die die Pfade zur Datasetdatei und zur Datei zum Speichern des Modells enthalten:

  • _dataPath enthält den Pfad zur Datei mit dem Dataset, das zum Trainieren des Modells verwendet wird.
  • _modelPath enthält den Pfad zur Datei, in der das trainierte Modell gespeichert ist.

Fügen Sie den folgenden Code unter den using-Anweisungen hinzu, um diese Pfade anzugeben:

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

ML-Kontext erstellen

Fügen Sie am Anfang der Datei Program.cs folgende zusätzliche using-Anweisungen hinzu:

using Microsoft.ML;
using IrisFlowerClustering;

Ersetzen Sie die Zeile Console.WriteLine("Hello World!"); durch folgenden Code:

var mlContext = new MLContext(seed: 0);

Die Klasse Microsoft.ML.MLContext stellt die Umgebung für maschinelles Lernen dar und bietet Mechanismen für die Protokollierung sowie Einstiegspunkte für das Laden von Daten, das Trainieren von Modellen, Vorhersagen und weitere Aufgaben. Dies ist im Prinzip vergleichbar mit der Verwendung von DbContext in Entity Framework.

Einrichten des Ladens von Daten

Fügen Sie den folgenden Code unterhalb von MLContext hinzu, um die Methode zum Laden von Daten einzurichten:

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

Die generische MLContext.Data.LoadFromTextFile-Erweiterungsmethode leitet das Datasetschema aus dem bereitgestellten IrisData-Typ ab und gibt IDataView zurück, was als Eingabe für Transformatoren verwendet werden kann.

Erstellen einer Lernpipeline

Im Rahmen dieses Tutorials umfasst die Pipeline der Clusteraufgabe die zwei folgenden Schritte:

  • Verketten geladener Spalten zu einer Spalte Features, die von einem Clustertrainer verwendet wird;
  • Verwenden eines KMeansTrainer-Trainers, um das Modell mithilfe des Clusteralgorithmus k-means++ zu trainieren.

Fügen Sie nach dem Laden der Daten Folgendes hinzu:

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

Der Code gibt an, dass das Dataset in drei Cluster aufgeteilt werden soll.

Trainieren des Modells

Die in den vorangegangenen Abschnitten hinzugefügten Schritte haben die Pipeline für das Training vorbereitet, es wurden jedoch keine ausgeführt. Fügen Sie unten in der Datei die folgende Zeile hinzu, um Daten zu laden und Modelltraining durchzuführen:

var model = pipeline.Fit(dataView);

Speichern des Modells

An diesem Punkt haben Sie ein Modell, das in eine der vorhandenen oder neuen .NET-Anwendungen integriert werden kann. Um das Modell in einer ZIP-Datei zu speichern, fügen Sie den folgenden Code unter dem Aufruf der Methode Fit hinzu:

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

Verwenden des Modells für Vorhersagen

Verwenden Sie für Vorhersagen die PredictionEngine<TSrc,TDst>-Klasse, die Instanzen des Eingabetyps über die Transformationspipeline annimmt und Instanzen des Ausgabetyps erzeugt. Fügen Sie die folgende Zeile hinzu, um eine Instanz dieser Klasse zu erstellen:

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

Die PredictionEngine ist eine Hilfs-API, mit der Sie eine Vorhersage für eine einzelne Instanz der Daten treffen können. PredictionEngine ist nicht threadsicher. Die Verwendung in Singlethread-oder Prototypumgebungen ist zulässig. Zur Verbesserung der Leistung und Threadsicherheit in Produktionsumgebungen verwenden Sie den PredictionEnginePool-Dienst, der einen ObjectPool aus PredictionEngine-Objekten für die Verwendung in Ihrer gesamten Anwendung erstellt. Informationen zur Verwendung von PredictionEnginePool in einer ASP.NET Core-Web-API finden Sie in dieser Anleitung.

Hinweis

Die PredictionEnginePool-Diensterweiterung ist derzeit als Vorschauversion verfügbar.

Erstellen Sie die Klasse TestIrisData, um Testdateninstanzen unterzubringen:

  1. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und wählen Sie dann Hinzufügen>Neues Element aus.

  2. Wählen Sie im Dialogfeld Neues Element hinzufügen die Option Klasse aus, und ändern Sie das Feld Name in TestIrisData.cs. Wählen Sie dann die Schaltfläche Hinzufügen aus.

  3. Ändern Sie die Klasse wie im folgenden Beispiel in „statisch“:

    static class TestIrisData
    

Dieses Tutorial führt eine Irisdateninstanz innerhalb dieser Klasse ein. Sie können weitere Szenarios zum Testen des Models hinzufügen. Fügen Sie den folgenden Code der TestIrisData-Klasse hinzu:

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

Um herauszufinden, zu welchem Cluster das angegebene Element gehört, kehren Sie zur Datei Program.cs zurück und fügen den folgenden Code unten in die Datei ein:

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

Führen Sie das Programm aus, um festzustellen, welcher Cluster die angegebene Dateninstanz und die quadratischen Abstände von dieser Instanz zum Clusterschwerpunkt enthält. Die Ergebnisse sollten den hier dargestellten ähneln:

Cluster: 2
Distances: 11.69127 0.02159119 25.59896

Herzlichen Glückwunsch! Sie haben erfolgreich ein Machine Learning-Modell für Iris-Clustering erstellt und für Vorhersagen verwendet. Sie finden den Quellcode für dieses Tutorial im GitHub-Repository dotnet/samples.

Nächste Schritte

In diesem Tutorial haben Sie Folgendes gelernt:

  • Das Problem verstehen
  • Auswählen der entsprechenden Machine Learning-Aufgabe
  • Vorbereiten der Daten
  • Laden und Transformieren der Daten
  • Auswählen eines Lernalgorithmus
  • Trainieren des Modells
  • Verwenden des Modells für Vorhersagen

In unserem GitHub-Repository können Sie mit dem Lernen fortfahren und weitere Beispiele finden.