Tutorial: Vorhersagen von Preisen per Regression mit ML.NET

In diesem Tutorial wird veranschaulicht, wie mit ML.NET ein Regressionsmodell für die Vorhersage von Preisen für Taxifahrten in New York City erstellt wird.

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

  • Vorbereiten und Verstehen der Daten
  • Laden und Transformieren der Daten
  • Auswählen eines Lernalgorithmus
  • Trainieren des Modells
  • Evaluieren des Modells
  • Verwenden des Modells für Vorhersagen

Voraussetzungen

Erstellen einer Konsolenanwendung

  1. Erstellen Sie eine C#-Konsolenanwendung mit dem Namen „TaxiFarePrediction“.

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

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

  4. Installieren Sie die NuGet-Pakete Microsoft.ML und Microsoft.ML.FastTree:

    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. Wählen Sie anschließend die Registerkarte Durchsuchen aus, suchen Sie nach Microsoft.ML, und wählen Sie das Paket in der Liste und anschließend die Schaltfläche Installieren aus. 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. Gehen Sie für das NuGet-Paket Microsoft.ML.FastTreee genauso vor.

Vorbereiten und Verstehen der Daten

  1. Laden Sie die Datasets taxi-fare-train.csv und taxi-fare-test.csv herunter, und speichern Sie sie im zuvor erstellten Ordner Data. Diese Datasets werden zum Trainieren des Machine Learning-Modells und zum anschließenden Auswerten der Genauigkeit des Modells verwendet. Diese Datasets stammen ursprünglich aus dem Dataset „NYC TLC Taxi Trip“.

  2. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf jede der „*.csv“-Dateien, und wählen Sie Eigenschaften aus. Ändern Sie unter Erweitert den Wert von In Ausgabeverzeichnis kopieren in Kopieren, wenn neuer.

  3. Öffnen Sie das Dataset taxi-fare-train.csv, und sehen Sie sich die Spaltenheader in der ersten Zeile an. Sehen Sie sich jede der Spalten an. Machen Sie sich mit den Daten vertraut, und entscheiden Sie, welche Spalten Features sind, und welche Spalte die Bezeichnung ist.

label ist die Spalte, die vorhergesagt werden soll. Die identifizierten Features sind die Eingaben, die Sie für das Modell zum Vorhersagen von Label bereitstellen.

Das angegebene Dataset enthält die folgenden Spalten:

  • vendor_id: Die ID des Taxiunternehmers ist ein Feature.
  • rate_code: Der Tariftyp der Taxifahrt ist ein Feature.
  • passenger_count: Die Anzahl der Fahrgäste bei einer Fahrt ist ein Feature.
  • trip_time_in_secs: Die Dauer der Fahrt. Der Fahrpreis soll vorhergesagt werden, bevor die Fahrt abgeschlossen ist. Zu diesem Zeitpunkt wissen Sie noch nicht, wie lange die Fahrt dauert. Deshalb ist die Fahrtzeit kein Feature, und Sie müssen diese Spalte aus dem Modell ausschließen.
  • trip_distance: Die Fahrtstrecke ist ein Feature.
  • payment_type: Die Zahlungsmethode (Bargeld oder Kreditkarte) ist ein Feature.
  • fare_amount: Der gesamte gezahlte Taxifahrtpreis ist die Bezeichnung.

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 TaxiTrip.cs. Wählen Sie dann die Schaltfläche Hinzufügen aus.

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

    using Microsoft.ML.Data;
    

Entfernen Sie die vorhandene Klassendefinition, und fügen Sie den folgenden Code mit den beiden Klassen TaxiTrip und TaxiTripFarePrediction der Datei TaxiTrip.cs hinzu:

public class TaxiTrip
{
    [LoadColumn(0)]
    public string? VendorId;

    [LoadColumn(1)]
    public string? RateCode;

    [LoadColumn(2)]
    public float PassengerCount;

    [LoadColumn(3)]
    public float TripTime;

    [LoadColumn(4)]
    public float TripDistance;

    [LoadColumn(5)]
    public string? PaymentType;

    [LoadColumn(6)]
    public float FareAmount;
}

public class TaxiTripFarePrediction
{
    [ColumnName("Score")]
    public float FareAmount;
}

TaxiTrip ist die Eingabedatenklasse und verfügt über Definitionen für jede der Datasetspalten. Verwenden Sie das LoadColumnAttribute-Attribut, um die Indizes der Quellspalten im Dataset festzulegen.

Die Klasse TaxiTripFarePrediction stellt die vorhergesagten Ergebnisse dar. Sie verfügt über ein einzelnes Feld für einen Gleitkommawert (FareAmount) mit einem angewendeten ScoreColumnNameAttribute-Attribut. Für die Regressionsaufgabe enthält die Spalte Score die vorhergesagten Bezeichnungswerte.

Hinweis

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

Definieren von Daten und Modellpfaden

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

using Microsoft.ML;
using TaxiFarePrediction;

Sie müssen drei Felder erstellen, die die Pfade zu den Dateien mit Datasets und der Datei zum Speichern des Modells enthalten:

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

Fügen Sie den folgenden Code direkt unter dem usings-Abschnitt hinzu, um diese Pfade und die _textLoader-Variable anzugeben:

string _trainDataPath = Path.Combine(Environment.CurrentDirectory, "Data", "taxi-fare-train.csv");
string _testDataPath = Path.Combine(Environment.CurrentDirectory, "Data", "taxi-fare-test.csv");
string _modelPath = Path.Combine(Environment.CurrentDirectory, "Data", "Model.zip");

Alle ML.NET-Operationen beginnen in der MLContext-Klasse. Beim Initialisieren von mlContext wird eine neue ML.NET-Umgebung erstellt, die für alle Objekte des Workflows für die Modellerstellung gemeinsam genutzt werden kann. Die Klasse ähnelt dem Konzept von DBContext in Entity Framework.

Initialisieren der Variablen

Ersetzen Sie die Zeile Console.WriteLine("Hello World!") durch den folgenden Code, um die mlContext-Variable zu deklarieren und zu initialisieren:

MLContext mlContext = new MLContext(seed: 0);

Fügen Sie den folgenden Text als nächste Codezeile ein, um die Train-Methode aufzurufen:

var model = Train(mlContext, _trainDataPath);

Die Train()-Methode führt die folgenden Aufgaben aus:

  • Laden der Daten.
  • Extrahieren und Transformieren der Daten.
  • Trainieren des Modells.
  • Zurückgeben des Modells.

Die Train-Methode trainiert das Modell. Erstellen Sie diese Methode mit folgendem Code direkt darunter:

ITransformer Train(MLContext mlContext, string dataPath)
{

}

Laden und Transformieren der Daten

ML.NET verwendet das IDataView-Interface als flexible, effiziente Möglichkeit, Tabellendaten in Zahlen- oder Textform zu beschreiben. Mit IDataView können entweder Textdateien geladen werden, oder es kann ein Echtzeitladevorgang durchgeführt werden (z. B. SQL-Datenbank- oder Protokolldateien). Fügen Sie den folgenden Code am Ende der ersten Zeile der Train()-Methode hinzu.

IDataView dataView = mlContext.Data.LoadFromTextFile<TaxiTrip>(dataPath, hasHeader: true, separatorChar: ',');

Da Sie den Preis der Taxifahrt vorhersagen möchten, ist die Spalte FareAmount das Label-Element für die Vorhersage (Ausgabe des Modells). Verwenden Sie die CopyColumnsEstimator-Transformationsklasse, um FareAmount zu kopieren, und fügen Sie den folgenden Code hinzu:

var pipeline = mlContext.Transforms.CopyColumns(outputColumnName: "Label", inputColumnName:"FareAmount")

Da der Algorithmus, der das Modell trainiert, numerische Features erfordert, müssen Sie die kategorischen Datenwerte (VendorId, RateCode und PaymentType) in Zahlen transformieren (VendorIdEncoded, RateCodeEncoded und PaymentTypeEncoded). Verwenden Sie hierzu die OneHotEncodingTransformer-Transformationsklasse, mit der verschiedenen Werten in den Spalten verschiedene numerische Schlüsselwerte zugeordnet werden, und fügen Sie den folgenden Code hinzu:

.Append(mlContext.Transforms.Categorical.OneHotEncoding(outputColumnName: "VendorIdEncoded", inputColumnName:"VendorId"))
.Append(mlContext.Transforms.Categorical.OneHotEncoding(outputColumnName: "RateCodeEncoded", inputColumnName: "RateCode"))
.Append(mlContext.Transforms.Categorical.OneHotEncoding(outputColumnName: "PaymentTypeEncoded", inputColumnName: "PaymentType"))

Im letzten Schritt der Vorbereitung der Daten werden alle Feature-Spalten mithilfe der Transformationsklasse mlContext.Transforms.Concatenate in die Spalte Features kombiniert. Standardmäßig verarbeitet ein Lernalgorithmus nur Merkmale aus der Spalte Features. Fügen Sie den folgenden Code hinzu:

.Append(mlContext.Transforms.Concatenate("Features", "VendorIdEncoded", "RateCodeEncoded", "PassengerCount", "TripDistance", "PaymentTypeEncoded"))

Auswählen eines Lernalgorithmus

Bei diesem Problem geht es darum, den Preis einer Taxifahrt in New York City vorherzusagen. Dies mag auf den ersten Blick einfach von der zurückgelegten Stecke abhängen. Taxiunternehmer in New York berechnen jedoch abhängig von anderen Faktoren wie zusätzlichen Fahrgästen oder Kreditkartenzahlung anstelle von Barzahlung unterschiedliche Beträge. Ihr Ziel ist es, den Preiswert vorherzusagen. Dies ist ein realer Wert, der auf anderen Faktoren im Dataset basiert. Wählen Sie hierzu eine Machine Learning-Aufgabe für die Regression aus.

Fügen Sie die Machine Learning-Aufgabe FastTreeRegressionTrainer an die Definitionen für die Datentransformation an, indem Sie in Train() Folgendes als nächste Codezeile hinzufügen:

.Append(mlContext.Regression.Trainers.FastTree());

Trainieren des Modells

Fügen Sie die folgende Codezeile in der Train()-Methode hinzu, um das Modell an die dataview-Daten für das Trainieren anzupassen und das trainierte Modell zurückzugeben:

var model = pipeline.Fit(dataView);

Mit der Fit()-Methode wird Ihr Modell trainiert, indem das Dataset transformiert und das Training angewendet wird.

Geben Sie das trainierte Modell mit der folgenden Codezeile in der Methode Train() zurück:

return model;

Evaluieren des Modells

Evaluieren Sie als Nächstes die Leistung Ihres Modells mit Ihren Testdaten zur Qualitätssicherung und Validierung. Erstellen Sie mit dem folgenden Code die Evaluate()-Methode direkt nach Train():

void Evaluate(MLContext mlContext, ITransformer model)
{

}

Die Evaluate-Methode führt die folgenden Aufgaben aus:

  • Laden des Testdatasets.
  • Erstellen des Regressionsauswerters.
  • Evaluieren des Modells und Erstellen von Metriken.
  • Anzeigen der Metriken.

Fügen Sie der neuen Methode mit dem folgenden Code einen Aufruf direkt unter dem Train-Methodenaufruf hinzu:

Evaluate(mlContext, model);

Laden Sie das Testdataset, indem Sie die LoadFromTextFile()-Methode verwenden. Evaluieren Sie das Modell, indem Sie dieses Dataset als Qualitätsprüfung verwenden. Fügen Sie hierzu in der Evaluate-Methode den folgenden Code hinzu:

IDataView dataView = mlContext.Data.LoadFromTextFile<TaxiTrip>(_testDataPath, hasHeader: true, separatorChar: ',');

Fügen Sie als Nächstes Evaluate() den folgenden Code hinzu, um die Test-Daten zu transformieren:

var predictions = model.Transform(dataView);

Mit der Transform()-Methode werden Vorhersagen für die Eingabezeilen des Testdatasets getroffen.

Die RegressionContext.Evaluate-Methode berechnet die Qualitätsmetriken für das PredictionModel mit dem angegebenen Dataset. Das zurückgegebene RegressionMetrics-Objekt enthält alle von Regressionsauswertern berechneten Metriken.

Um diese zur Bestimmung der Qualität des Modells anzuzeigen, müssen Sie die Metriken zuerst abzurufen. Fügen Sie der Evaluate-Methode folgenden Code als nächste Zeile hinzu:

var metrics = mlContext.Regression.Evaluate(predictions, "Label", "Score");

Nach der Vorhersagekonfiguration wertet die Evaluate()-Methode das Modell aus. Dabei werden die Vorhersagewerte mit den tatsächlichen Labels im Testdataset verglichen und die Leistungsmetriken für das Modell zurückgegeben.

Fügen Sie den folgenden Code hinzu, um das Modell zu evaluieren und die Auswertungsmetriken zu erzeugen:

Console.WriteLine();
Console.WriteLine($"*************************************************");
Console.WriteLine($"*       Model quality metrics evaluation         ");
Console.WriteLine($"*------------------------------------------------");

RSquared ist eine weitere Auswertungsmetrik der Regressionsmodelle. RSquared akzeptiert Werte zwischen 0 (null) und 1. Je näher der Wert an 1 liegt, desto besser ist das Modell. Fügen Sie der Evaluate-Methode den folgenden Code hinzu, um den RSquared-Wert anzuzeigen:

Console.WriteLine($"*       RSquared Score:      {metrics.RSquared:0.##}");

RMS ist eine der Auswertungsmetriken aus dem Regressionsmodell. Je niedriger sie ausfällt, desto besser ist das Modell. Fügen Sie der Evaluate-Methode den folgenden Code hinzu, um den RMS-Wert anzuzeigen:

Console.WriteLine($"*       Root Mean Squared Error:      {metrics.RootMeanSquaredError:#.##}");

Verwenden des Modells für Vorhersagen

Erstellen Sie die TestSinglePrediction-Methode mit dem folgenden Code direkt nach der Evaluate-Methode:

void TestSinglePrediction(MLContext mlContext, ITransformer model)
{

}

Die TestSinglePrediction-Methode führt die folgenden Aufgaben aus:

  • Erstellen eines einzelnen Kommentars aus Testdaten.
  • Vorhersagen des Fahrpreisbetrags anhand der Testdaten.
  • Kombinieren von Testdaten und Vorhersagen für die Berichterstattung.
  • Anzeigen der vorhergesagten Ergebnisse.

Fügen Sie der neuen Methode mit dem folgenden Code einen Aufruf direkt unter dem Evaluate-Methodenaufruf hinzu:

TestSinglePrediction(mlContext, model);

Fügen Sie TestSinglePrediction() den folgenden Code hinzu, um mit PredictionEngine den Preis für die Fahrt vorherzusagen:

var predictionFunction = mlContext.Model.CreatePredictionEngine<TaxiTrip, TaxiTripFarePrediction>(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.

Dieses Tutorial verwendet eine Testfahrt innerhalb dieser Klasse. Sie können später weitere Szenarios zum Experimentieren mit dem Beispiel hinzufügen. Fügen Sie eine Fahrt hinzu, um die Kostenvorhersage des trainierten Modells in der TestSinglePrediction()-Methode zu testen, indem Sie eine TaxiTrip-Instanz erstellen:

var taxiTripSample = new TaxiTrip()
{
    VendorId = "VTS",
    RateCode = "1",
    PassengerCount = 1,
    TripTime = 1140,
    TripDistance = 3.75f,
    PaymentType = "CRD",
    FareAmount = 0 // To predict. Actual/Observed = 15.5
};

Als Nächstes wird der Preis für die Fahrt basierend auf einer einzelnen Instanz der Taxifahrtdaten vorhergesagt und an PredictionEngine übergeben, indem als nächste Codezeilen der TestSinglePrediction()-Methode Folgendes hinzugefügt wird:

var prediction = predictionFunction.Predict(taxiTripSample);

Die Predict()-Funktion trifft eine Vorhersage für eine einzelne Dateninstanz.

Um den vorhergesagten Preis der angegebenen Fahrt anzuzeigen, fügen Sie den folgenden Code der TestSinglePrediction-Methode hinzu:

Console.WriteLine($"**********************************************************************");
Console.WriteLine($"Predicted fare: {prediction.FareAmount:0.####}, actual fare: 15.5");
Console.WriteLine($"**********************************************************************");

Führen Sie das Programm aus, um den vorhergesagten Taxifahrtpreis für den Testfall anzuzeigen.

Herzlichen Glückwunsch! Hiermit haben Sie ein Machine Learning-Modell erfolgreich zum Vorhersagen von Taxifahrtpreisen erstellt, die Genauigkeit ausgewertet und es zum Vorhersagen der Preise verwendet. Sie finden den Quellcode für dieses Tutorial im GitHub-Repository dotnet/samples.

Nächste Schritte

In diesem Tutorial haben Sie Folgendes gelernt:

  • Vorbereiten und Verstehen der Daten
  • Erstellen einer Lernpipeline
  • Laden und Transformieren der Daten
  • Auswählen eines Lernalgorithmus
  • Trainieren des Modells
  • Evaluieren des Modells
  • Verwenden des Modells für Vorhersagen

Fahren Sie mit dem nächsten Tutorial fort, um mehr zu erfahren.