Учебник. Прогнозирование цен с помощью регрессии с ML.NET
Статья
В этом учебнике показано, как создать модель регрессии с помощью ML.NET, чтобы прогнозировать цены, в частности плату за проезд в такси по Нью-Йорку.
В этом руководстве вы узнаете, как:
Подготовка и анализ данных
Загрузка и преобразование данных
Выбор алгоритма обучения
Обучение модели
Оценка модели
Использование модели для прогнозирования
Предварительные требования
Visual Studio 2022 с установленной рабочей нагрузкой "Разработка классических приложений .NET".
Создание консольного приложение
Создайте консольное приложение C# с именем TaxiFarePrediction.
Выберите .NET 6 в качестве используемой платформы. Нажмите кнопку Создать .
Создайте каталог с именем Data в проекте для хранения набора данных и файлов модели.
Установите пакеты NuGet Microsoft.ML и Microsoft.ML.FastTree:
Примечание
В этом примере используется последняя стабильная версия пакетов NuGet, упомянутых выше, если не указано иное.
В обозревателе решений щелкните проект правой кнопкой мыши и выберите Управление пакетами NuGet. Выберите в качестве источника пакета "nuget.org", откройте вкладку Обзор, найдите Microsoft.ML, выберите пакет в списке и нажмите кнопку Установить. Нажмите кнопку ОК в диалоговом окне Предварительный просмотр изменений, а затем нажмите кнопку Принимаю в диалоговом окне Принятие условий лицензионного соглашения, если вы согласны с указанными условиями лицензионного соглашения для выбранных пакетов. Сделайте то же самое для пакета Microsoft.ML.FastTree в NuGet.
Подготовка и анализ данных
Скачайте наборы данных taxi-fare-train.csv и taxi-fare-test.csv, сохранив их в созданной на предыдущем шаге папке Data. Эти наборы данных используются для обучения модели машинного обучения и последующей оценки точности этой модели. Эти наборы данных взяты из наборов данных NYC TLC Taxi Trip.
В Обозреватель решений щелкните правой кнопкой мыши каждый из файлов *.csv и выберите Свойства. В разделе Дополнительно для параметра Копировать в выходной каталог установите значение Копировать более позднюю версию.
Откройте набор данных taxi-fare-train.csv и просмотрите заголовки столбцов в первой строке. Теперь изучите каждый из столбцов. Разберитесь, какие данные в них хранятся, и определите, какие столбцы являются признаками, а в каком содержится метка.
label — это столбец, который необходимо спрогнозировать. Определены Featuresвходные данные, которые вы предоставляете модели для прогнозирования Label.
Предоставленный набор данных содержит следующие столбцы:
vendor_id: идентификатор поставщика услуг такси — это признак.
rate_code: тип тарифа для поездки на такси — это признак.
passenger_count: число пассажиров в поездке — это признак.
trip_time_in_secs: время, затраченное на поездку. Вам требуется спрогнозировать плату за одну поездку до того, как поездка будет завершена. На этот момент вам неизвестна продолжительность поездки. Таким образом, продолжительность поездки не является признаком и соответствующий столбец следует исключить из модели.
trip_distance: расстояние поездки — это признак.
payment_type: метод оплаты (наличные или кредитная карта) — это признак.
fare_amount: общая сумма, уплаченная за поездку на такси, — это метка.
Создание классов данных
Создайте классы для входных данных и прогнозов:
В обозревателе решений щелкните проект правой кнопкой мыши и выберите пункты Добавить>Новый элемент.
В диалоговом окне Добавление нового элемента выберите Класс и измените значение поля Имя на TaxiTrip.cs. Теперь нажмите кнопку Добавить.
Добавьте следующие директивы using в новый файл.
using Microsoft.ML.Data;
Удалите из файла TaxiTrip.cs существующее определение класса и добавьте следующий код с двумя классами TaxiTrip и TaxiTripFarePrediction:
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 содержит входные данные и определения для каждого из столбцов в этом наборе данных. Используйте атрибут LoadColumnAttribute, чтобы указать индексы исходных столбцов в наборе данных.
Класс TaxiTripFarePrediction представляет результаты прогнозирования. Он содержит одно поле типа float FareAmount, к которому применен атрибут ScoreColumnNameAttribute. Для задачи регрессии столбец Оценка содержит прогнозируемые значения метки.
Примечание
Используйте тип float для представления значений с плавающей запятой в классах данных ввода и прогнозирования.
Определение путей к данным и модели
Добавьте следующие новые операторы using в начало файла Program.cs:
using Microsoft.ML;
using TaxiFarePrediction;
Необходимо создать три поля, которые будут содержать пути к файлам с наборами данных и к файлу для сохранения модели:
_trainDataPath содержит путь к файлу с набором данных, используемым для обучения модели.
_testDataPath содержит путь к файлу с набором данных, используемым для оценки модели.
_modelPath содержит путь к файлу для сохранения обучаемой модели.
Добавьте следующий код прямо под разделом с операторами using, чтобы указать эти пути и переменную _textLoader:
Все операции ML.NET запускаются в классе MLContext. Инициализация mlContext создает новую среду ML.NET, которую могут совместно использовать объекты рабочего процесса создания модели. По существу он аналогичен классу DBContext в Entity Framework.
Инициализация переменных
Замените строку Console.WriteLine("Hello World!") следующим кодом, чтобы объявить и инициализировать переменную mlContext:
MLContext mlContext = new MLContext(seed: 0);
Добавьте следующий код в качестве следующей строки кода для вызова метода Train:
var model = Train(mlContext, _trainDataPath);
Метод Train() выполняет следующие задачи:
загрузка данных;
извлечение и преобразование данных;
обучение модели;
возвращение модели.
Метод Train обучает модель. Создайте этот метод сразу под оператором using, используя следующий код:
ML.NET использует интерфейс IDataView в качестве гибкого и эффективного средства описания числовых или текстовых табличных данных.
IDataView может загружать данные из текстового файла или в режиме реального времени (например, из базы данных SQL или файлов журнала). Добавьте следующий код в первую строку метода Train():
Так как вам нужно спрогнозировать плату за такси, столбец FareAmount является меткой Label, которую вы будете прогнозировать (выходные данные модели). Используйте класс преобразования CopyColumnsEstimator, чтобы скопировать FareAmount, и добавьте следующий код:
var pipeline = mlContext.Transforms.CopyColumns(outputColumnName: "Label", inputColumnName:"FareAmount")
Алгоритм, который обучает модель, принимает числовые признаки, поэтому значения категориальных данных (VendorId, RateCode и PaymentType) нужно преобразовать в числа (VendorIdEncoded, RateCodeEncoded и PaymentTypeEncoded). Для этого используйте класс преобразования OneHotEncodingTransformer, который присваивает разные числовые значения ключа разным значениям в каждом из столбцов, и добавьте следующий код:
Последний шаг на этапе подготовки данных заключается в объединении всех столбцов признаков в столбце Features с помощью класса преобразования mlContext.Transforms.Concatenate. По умолчанию алгоритм обучения обрабатывает только признаки, представленные в столбце Features. Добавьте следующий код:
Задача заключается в прогнозировании стоимости поездки в такси в Нью-Йорке. На первый взгляд может показаться, что плата зависит только от расстояния. Но службы такси в Нью-Йорке изменяют плату с учетом еще нескольких факторов, таких как наличие дополнительных пассажиров или оплата кредитной картой вместо наличных. Вы хотите спрогнозировать стоимость, которая является реальным значением, зависящим от других факторов в наборе данных. Для этого нужно выбрать задачу машинного обучения регрессия.
Добавьте задачу машинного обучения FastTreeRegressionTrainer к определениям преобразований данных, добавив в Train() следующую строку кода:
Согласуйте модель с учебным dataview и получите обученную модель, добавив в метод Train() следующую строку кода:
var model = pipeline.Fit(dataView);
Метод Fit() обучает модель путем преобразования набора данных и применения обучения.
Возвратите обученную модель с помощью следующей строки кода в методе Train():
return model;
Оценка модели
Затем оцените эффективность модели с помощью тестовых данных для контроля качества и проверки. Создайте метод Evaluate() сразу после Train(), используя следующий код:
Добавьте вызов нового метода сразу под вызовом метода Train, используя следующий код:
Evaluate(mlContext, model);
Загрузите тестовый набор данных с помощью метода LoadFromTextFile(). Оцените модель с помощью этого набора данных для проверки ее качества, добавив следующий код в метод Evaluate:
Затем преобразуйте данные Test, добавив следующий код для Evaluate():
var predictions = model.Transform(dataView);
Метод Transform() осуществляет прогнозирование для входных строк тестового набора данных.
Метод RegressionContext.Evaluate вычисляет метрики качества для PredictionModel на основе указанного набора данных. Возвращает объект RegressionMetrics, который содержит общие метрики, вычисляемые с помощью средств оценки регрессии.
Чтобы отобразить их для оценки качества модели, сначала метрики необходимо получить. Добавьте в следующую строку метода Evaluate приведенный ниже код:
var metrics = mlContext.Regression.Evaluate(predictions, "Label", "Score");
После получения прогноза метод Evaluate() оценивает модель, сравнивая спрогнозированные значения с фактическими метками (Labels) в тестовом наборе данных, а затем возвращает метрики эффективности модели.
Добавьте следующий код, чтобы оценить модель и создать для нее метрики оценки:
Console.WriteLine();
Console.WriteLine($"*************************************************");
Console.WriteLine($"* Model quality metrics evaluation ");
Console.WriteLine($"*------------------------------------------------");
Также в качестве метрики для оценки регрессионных моделей используется коэффициент детерминации. Коэффициент детерминации может иметь значения в диапазоне от 0 до 1. Чем ближе его значение к 1, тем лучше модель. Чтобы отображать значение коэффициента детерминации, добавьте следующий код в метод Evaluate:
Среднеквадратичное отклонение является одной из метрик, используемых для оценки регрессионной модели. Чем ниже это отклонение, тем лучше модель. Чтобы отображать значение среднеквадратичного отклонения, добавьте следующий код в метод Evaluate:
Console.WriteLine($"* Root Mean Squared Error: {metrics.RootMeanSquaredError:#.##}");
Использование модели для прогнозирования
Создайте метод TestSinglePrediction сразу после метода Evaluate, вставив в него следующий код:
Метод TestSinglePrediction выполняет следующие задачи:
создание отдельного комментария тестовых данных;
прогнозирование суммы оплаты на основе тестовых данных;
объединение тестовых данных и прогнозов для создания отчетов;
отображение результатов прогнозирования.
Добавьте вызов нового метода сразу под вызовом метода Evaluate, используя следующий код:
TestSinglePrediction(mlContext, model);
Для прогнозирования цены используйте PredictionEngine, добавив в TestSinglePrediction() следующий код:
var predictionFunction = mlContext.Model.CreatePredictionEngine<TaxiTrip, TaxiTripFarePrediction>(model);
Класс PredictionEngine представляет собой удобный API, позволяющий осуществить прогнозирование на основе единственного экземпляра данных.
PredictionEngine не является потокобезопасным. Допустимо использовать в средах прототипов или средах с одним потоком. Для улучшенной производительности и потокобезопасности в рабочей среде используйте службу PredictionEnginePool, которая создает ObjectPool объектов PredictionEngine для использования во всем приложении. См. руководство по использованию PredictionEnginePool в веб-API ASP.NET Core.
Примечание
Расширение службы PredictionEnginePool сейчас доступно в предварительной версии.
Для этого руководства в этом классе используется один тестовый проход. Позже можно добавить другие сценарии и поэкспериментировать с этой моделью. Добавьте поездку для проверки прогнозирования стоимости обученной моделью с помощью метода TestSinglePrediction(), создав экземпляр TaxiTrip:
Затем спрогнозируйте стоимость на основе отдельного экземпляра данных о поездке на такси и передайте ее в PredictionEngine, добавив следующие строки кода в метод TestSinglePrediction():
var prediction = predictionFunction.Predict(taxiTripSample);
Функция Predict() создает прогноз по одному экземпляру данных.
Чтобы отобразить прогнозируемую плату за указанную поездку, добавьте в метод TestSinglePrediction следующий код:
Console.WriteLine($"**********************************************************************");
Console.WriteLine($"Predicted fare: {prediction.FareAmount:0.####}, actual fare: 15.5");
Console.WriteLine($"**********************************************************************");
Запустите программу, чтобы узнать прогноз платы за такси для тестового примера.
Поздравляем! Вы успешно создали модель машинного обучения для прогнозирования платы за проезд в такси, оценили ее точность и использовали ее для получения прогнозов. Исходный код для этого руководства можно найти в репозитории GitHub dotnet/samples.
Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.
Отзыв о .NET
.NET — это проект с открытым исходным кодом. Выберите ссылку, чтобы оставить отзыв:
Управление приемом и подготовкой данных, обучением моделей и развертыванием, а также мониторингом решений машинного обучения с помощью Python, Машинное обучение Azure и MLflow.
В этом руководстве показано, как создать консольное приложение .NET Core, которое классифицирует мнения, выраженные в комментариях с веб-сайта, и предпринимает соответствующие действия. Двоичный классификатор тональности использует C# в Visual Studio.
Наши руководства по ML.NET помогут вам научиться создавать специализированные решения на базе искусственного интеллекта и интегрировать их в свои .NET-приложения.
В этом руководстве показано, как построить приложение для рекомендации фильмов с помощью ML.NET в консольном проекте .NET Core. Используется C# и Visual Studio 2019.