Samouczek: przewidywanie cen przy użyciu regresji za pomocą ML.NET

W tym samouczku pokazano, jak utworzyć model regresji przy użyciu ML.NET do przewidywania cen, w szczególności opłat za taksówki w Nowym Jorku.

Ten samouczek zawiera informacje na temat wykonywania następujących czynności:

  • Przygotowywanie i zrozumienie danych
  • Ładowanie i przekształcanie danych
  • Wybieranie algorytmu uczenia
  • Trenowanie modelu
  • Ocena modelu
  • Korzystanie z modelu na potrzeby przewidywań

Wymagania wstępne

Tworzenie aplikacji konsolowej

  1. Utwórz aplikację konsolową języka C# o nazwie "TaxiFarePrediction".

  2. Wybierz platformę .NET 6 jako platformę do użycia. Kliknij przycisk Utwórz.

  3. Utwórz katalog o nazwie Dane w projekcie, aby przechowywać pliki zestawu danych i modelu.

  4. Zainstaluj pakiet NuGet Microsoft.ML i Microsoft.ML.FastTree :

    Uwaga

    W tym przykładzie użyto najnowszej stabilnej wersji pakietów NuGet wymienionych, chyba że określono inaczej.

    W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt i wybierz polecenie Zarządzaj pakietami NuGet. Wybierz pozycję "nuget.org" jako źródło pakietu, wybierz kartę Przeglądaj , wyszukaj Microsoft.ML, wybierz pakiet z listy i wybierz przycisk Zainstaluj . Wybierz przycisk OK w oknie dialogowym Podgląd zmian , a następnie wybierz przycisk Akceptuję w oknie dialogowym Akceptacja licencji , jeśli zgadzasz się z postanowieniami licencyjnymi dla wymienionych pakietów. Zrób to samo dla pakietu NuGet Microsoft.ML.FastTree .

Przygotowywanie i zrozumienie danych

  1. Pobierz taxi-fare-train.csv i zestawy danych taxi-fare-test.csv i zapisz je w folderze Dane utworzonym w poprzednim kroku. Używamy tych zestawów danych do trenowania modelu uczenia maszynowego, a następnie oceniamy, jak dokładny jest model. Te zestawy danych pochodzą z zestawu danych NYC TLC Taxi Trip.

  2. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy każdą z plików *.csv i wybierz polecenie Właściwości. W obszarze Zaawansowane zmień wartość opcji Kopiuj do katalogu wyjściowego , aby skopiować, jeśli jest nowsza.

  3. Otwórz zestaw danychtaxi-fare-train.csv i przyjrzyj się nagłówkom kolumn w pierwszym wierszu. Przyjrzyj się poszczególnym kolumnom. Zapoznaj się z danymi i zdecyduj, które kolumny są funkcjami i która z nich jest etykietą.

Jest label to kolumna, którą chcesz przewidzieć. Zidentyfikowane Featuressą dane wejściowe, które dają modelowi w celu przewidywania wartości Label.

Podany zestaw danych zawiera następujące kolumny:

  • vendor_id: Identyfikator dostawcy taksówki jest funkcją.
  • rate_code: Typ stawki przejazdu taksówką jest funkcją.
  • passenger_count: Liczba pasażerów w podróży jest funkcją.
  • trip_time_in_secs: Ilość czasu zajęła podróż. Chcesz przewidzieć taryfę podróży przed ukończeniem podróży. W tej chwili nie wiesz, jak długo będzie trwać podróż. W związku z tym czas podróży nie jest funkcją i wykluczysz tę kolumnę z modelu.
  • trip_distance: Odległość podróży jest funkcją.
  • payment_type: Metoda płatności (gotówka lub karta kredytowa) jest funkcją.
  • fare_amount: Łączna opłata za taksówkę to etykieta.

Tworzenie klas danych

Utwórz klasy dla danych wejściowych i przewidywań:

  1. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt, a następnie wybierz polecenie Dodaj>nowy element.

  2. W oknie dialogowym Dodawanie nowego elementu wybierz pozycję Klasa i zmień pole Nazwa na TaxiTrip.cs. Następnie wybierz przycisk Dodaj .

  3. Dodaj następujące using dyrektywy do nowego pliku:

    using Microsoft.ML.Data;
    

Usuń istniejącą definicję klasy i dodaj następujący kod, który ma dwie klasy TaxiTrip i TaxiTripFarePrediction, do pliku TaxiTrip.cs :

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 jest klasą danych wejściowych i ma definicje dla każdej kolumny zestawu danych. Użyj atrybutu LoadColumnAttribute , aby określić indeksy kolumn źródłowych w zestawie danych.

Klasa TaxiTripFarePrediction reprezentuje przewidywane wyniki. Ma jedno pole float, FareAmount, z zastosowanym atrybutem ScoreColumnNameAttribute . W przypadku zadania regresji kolumna Score (Generowanie wyników ) zawiera przewidywane wartości etykiet.

Uwaga

float Użyj typu , aby reprezentować wartości zmiennoprzecinkowe w klasach danych wejściowych i przewidywania.

Definiowanie ścieżek danych i modelu

Dodaj następujące dodatkowe using instrukcje na początku pliku Program.cs :

using Microsoft.ML;
using TaxiFarePrediction;

Aby zapisać model, należy utworzyć trzy pola do przechowywania ścieżek do plików z zestawami danych i pliku:

  • _trainDataPath zawiera ścieżkę do pliku z zestawem danych używanym do trenowania modelu.
  • _testDataPath zawiera ścieżkę do pliku z zestawem danych używanym do oceny modelu.
  • _modelPath zawiera ścieżkę do pliku, w którym przechowywany jest wytrenowany model.

Dodaj następujący kod bezpośrednio poniżej sekcji usings , aby określić te ścieżki i dla zmiennej _textLoader :

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");

Wszystkie operacje ML.NET są uruchamiane w klasie MLContext. Inicjowanie mlContext tworzy nowe środowisko ML.NET, które można udostępnić w obiektach przepływu pracy tworzenia modelu. Jest ona podobna, koncepcyjnie, do DBContext w programie Entity Framework.

Inicjowanie zmiennych

Zastąp Console.WriteLine("Hello World!") wiersz następującym kodem, aby zadeklarować i zainicjować zmienną mlContext :

MLContext mlContext = new MLContext(seed: 0);

Dodaj następujący wiersz kodu, aby wywołać metodę Train :

var model = Train(mlContext, _trainDataPath);

Metoda Train() wykonuje następujące zadania:

  • Ładuje dane.
  • Wyodrębnia i przekształca dane.
  • Trenuje model.
  • Zwraca model.

Metoda Train trenuje model. Utwórz tę metodę tuż poniżej, używając następującego kodu:

ITransformer Train(MLContext mlContext, string dataPath)
{

}

Ładowanie i przekształcanie danych

ML.NET używa interfejsu IDataView jako elastycznego, wydajnego sposobu opisywania danych tabelarycznych liczbowych lub tekstowych. IDataView może ładować pliki tekstowe lub w czasie rzeczywistym (na przykład bazy danych SQL lub pliki dziennika). Dodaj następujący kod jako pierwszy wiersz Train() metody:

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

Jeśli chcesz przewidzieć taryfę za przejazd taksówką, FareAmount kolumna jest Label przewidywana (dane wyjściowe modelu). CopyColumnsEstimator Użyj klasy transform, aby skopiować FareAmountelement i dodać następujący kod:

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

Algorytm, który trenuje model, wymaga funkcji liczbowych, więc musisz przekształcić dane kategorii (, RateCodei ) na liczby (VendorIdVendorIdEncoded, RateCodeEncoded, i PaymentTypePaymentTypeEncoded). W tym celu użyj klasy przekształcenia OneHotEncodingTransformer , która przypisuje różne wartości klucza liczbowego do różnych wartości w każdej kolumnie i dodaj następujący kod:

.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"))

Ostatni krok przygotowywania danych łączy wszystkie kolumny funkcji w kolumnie mlContext.Transforms.ConcatenateFunkcje przy użyciu klasy transformacji. Domyślnie algorytm uczenia przetwarza tylko funkcje z kolumny Funkcje . Dodaj następujący kod:

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

Wybieranie algorytmu uczenia

Ten problem dotyczy przewidywania taryfy taksówki w Nowym Jorku. Na pierwszy rzut oka może się wydawać, że zależy to po prostu od odległości podróży. Jednak dostawcy taksówki w Nowym Jorku pobierają różne kwoty dla innych czynników, takich jak dodatkowi pasażerowie lub płacąc kartą kredytową zamiast gotówki. Chcesz przewidzieć wartość ceny, która jest rzeczywistą wartością, na podstawie innych czynników w zestawie danych. W tym celu należy wybrać zadanie uczenia maszynowego regresji .

Dołącz zadanie uczenia maszynowego FastTreeRegressionTrainer do definicji przekształcania danych, dodając następujący wiersz kodu w Train()pliku :

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

Trenowanie modelu

Dopasuj model do trenowania dataview i zwróć wytrenowany model, dodając następujący wiersz kodu w metodzie Train() :

var model = pipeline.Fit(dataView);

Metoda Fit() trenuje model, przekształcając zestaw danych i stosując szkolenie.

Zwróć wytrenowany model z następującym wierszem kodu w metodzie Train() :

return model;

Ocena modelu

Następnie oceń wydajność modelu przy użyciu danych testowych w celu zapewnienia jakości i weryfikacji. Utwórz metodę Evaluate() tuż po Train(), z następującym kodem:

void Evaluate(MLContext mlContext, ITransformer model)
{

}

Metoda Evaluate wykonuje następujące zadania:

  • Ładuje testowy zestaw danych.
  • Tworzy ewaluator regresji.
  • Ocenia model i tworzy metryki.
  • Wyświetla metryki.

Dodaj wywołanie do nowej metody bezpośrednio pod Train wywołaniem metody przy użyciu następującego kodu:

Evaluate(mlContext, model);

Załaduj testowy zestaw danych przy użyciu metody LoadFromTextFile(). Oceń model przy użyciu tego zestawu danych jako kontrolę jakości, dodając następujący kod w metodzie Evaluate :

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

Następnie przekształć Test dane, dodając następujący kod do Evaluate()elementu :

var predictions = model.Transform(dataView);

Metoda Transform() tworzy przewidywania dla wierszy wejściowych zestawu danych testowych.

Metoda RegressionContext.Evaluate oblicza metryki jakości dla określonego PredictionModel zestawu danych. Zwraca RegressionMetrics obiekt zawierający ogólne metryki obliczane przez ewaluatorów regresji.

Aby wyświetlić te metryki w celu określenia jakości modelu, należy najpierw pobrać metryki. Dodaj następujący kod jako następny wiersz w metodzie Evaluate :

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

Po ustawieniu przewidywania metoda Evaluate() ocenia model, który porównuje przewidywane wartości z rzeczywistymi Labels wartościami w zestawie danych testowych i zwraca metryki dotyczące sposobu działania modelu.

Dodaj następujący kod, aby ocenić model i wygenerować metryki oceny:

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

RSquared to kolejna metryka oceny modeli regresji. Funkcja RSquared przyjmuje wartości z zakresu od 0 do 1. Im bliżej jego wartości jest 1, tym lepiej jest model. Dodaj następujący kod do metody , Evaluate aby wyświetlić wartość RSquared:

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

Usługa RMS jest jedną z metryk oceny modelu regresji. Tym niższa jest, tym lepiej jest model. Dodaj następujący kod do metody , Evaluate aby wyświetlić wartość usługi RMS:

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

Korzystanie z modelu na potrzeby przewidywań

Utwórz metodę TestSinglePrediction tuż po metodzie Evaluate , używając następującego kodu:

void TestSinglePrediction(MLContext mlContext, ITransformer model)
{

}

Metoda TestSinglePrediction wykonuje następujące zadania:

  • Tworzy pojedynczy komentarz danych testowych.
  • Przewiduje kwotę taryfy na podstawie danych testowych.
  • Łączy dane testowe i przewidywania na potrzeby raportowania.
  • Wyświetla przewidywane wyniki.

Dodaj wywołanie do nowej metody bezpośrednio pod Evaluate wywołaniem metody przy użyciu następującego kodu:

TestSinglePrediction(mlContext, model);

Użyj elementu PredictionEngine , aby przewidzieć taryfę, dodając następujący kod do TestSinglePrediction()elementu :

var predictionFunction = mlContext.Model.CreatePredictionEngine<TaxiTrip, TaxiTripFarePrediction>(model);

PredictionEngine to wygodny interfejs API, który umożliwia przewidywanie dla pojedynczego wystąpienia danych. PredictionEngine nie jest bezpieczne wątkowo. Dopuszczalne jest użycie w środowiskach jednowątkowych lub prototypowych. Aby zwiększyć wydajność i bezpieczeństwo wątków w środowiskach produkcyjnych, użyj PredictionEnginePool usługi, która tworzy ObjectPoolPredictionEngine obiekty do użycia w całej aplikacji. Zobacz ten przewodnik dotyczący używania PredictionEnginePool w internetowym interfejsie API ASP.NET Core.

Uwaga

PredictionEnginePool Rozszerzenie usługi jest obecnie w wersji zapoznawczej.

W tym samouczku jest używana jedna podróż testowa w ramach tej klasy. Później możesz dodać inne scenariusze do eksperymentowania z modelem. Dodaj podróż, aby przetestować przewidywanie kosztów w wytrenowanego modelu w metodzie TestSinglePrediction() , tworząc wystąpienie klasy TaxiTrip:

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
};

Następnie należy przewidzieć taryfę na podstawie pojedynczego wystąpienia danych przejazdu taksówką i przekazać je do PredictionEngine obiektu, dodając następujące wiersze kodu w metodzie TestSinglePrediction() :

var prediction = predictionFunction.Predict(taxiTripSample);

Funkcja Predict() tworzy przewidywanie dla pojedynczego wystąpienia danych.

Aby wyświetlić przewidywaną taryfę określonej podróży, dodaj następujący kod do TestSinglePrediction metody :

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

Uruchom program, aby zobaczyć przewidywaną taryfę taksówek dla twojego przypadku testowego.

Gratulacje! Udało Ci się pomyślnie skompilować model uczenia maszynowego do przewidywania opłat za przejazd taksówką, ocenić jego dokładność i wykorzystać go do przewidywania. Kod źródłowy tego samouczka można znaleźć w repozytorium GitHub dotnet/samples .

Następne kroki

W niniejszym samouczku zawarto informacje na temat wykonywania następujących czynności:

  • Przygotowywanie i zrozumienie danych
  • Tworzenie potoku szkoleniowego
  • Ładowanie i przekształcanie danych
  • Wybieranie algorytmu uczenia
  • Trenowanie modelu
  • Ocena modelu
  • Korzystanie z modelu na potrzeby przewidywań

Przejdź do następnego samouczka, aby dowiedzieć się więcej.