Бөлісу құралы:


Руководство. Классификация проблем поддержки с использованием многоклассовой классификации с ML.NET

В этом примере руководства показано использование ML.NET для создания классификатора проблем GitHub для обучения модели, которая классифицирует и прогнозирует метку "Область" для проблемы с GitHub с помощью консольного приложения .NET с помощью C# в Visual Studio.

В этом руководстве вы узнаете, как:

  • Подготовка данных
  • Преобразование данных
  • Обучение модели
  • Оценка модели
  • Прогнозирование с помощью обученной модели
  • Развертывание и прогнозирование с помощью загруженной модели

Исходный код для этого руководства можно найти в репозитории dotnet/samples .

Предпосылки

Создайте консольное приложение

Создание проекта

  1. Создайте консольное приложение C# с именем GitHubIssueClassification. Нажмите кнопку Далее.

  2. Выберите .NET 7 в качестве платформы для использования. Нажмите кнопку "Создать".

  3. Создайте каталог с именем Data в проекте, чтобы сохранить файлы набора данных:

    В обозревателе решений щелкните проект правой кнопкой мыши и выберите команду "Добавить>новую папку". Введите "Данные" и нажмите клавишу ВВОД.

  4. Создайте каталог с именем Models в проекте, чтобы сохранить модель:

    В обозревателе решений щелкните проект правой кнопкой мыши и выберите команду "Добавить>новую папку". Введите "Модели" и нажмите клавишу ВВОД.

  5. Установите пакет NuGet Microsoft.ML:

    Замечание

    В этом примере используется последняя стабильная версия упомянутых пакетов NuGet, если не указано иное.

    В обозревателе решений щелкните проект правой кнопкой мыши и выберите пункт "Управление пакетами NuGet". Выберите "nuget.org" в качестве источника пакета, перейдите на вкладку "Обзор", найдите Microsoft.ML и выберите "Установить". Нажмите кнопку "ОК " в диалоговом окне "Предварительные изменения" , а затем нажмите кнопку "Принять" в диалоговом окне принятия лицензий, если вы согласны с условиями лицензии для перечисленных пакетов.

Подготовка данных

  1. Скачайте наборы данных issues_train.tsv и наборы данных issues_test.tsv и сохраните их в созданной ранее папке данных . Первый набор данных обучает модель машинного обучения, а второй — для оценки точности модели.

  2. В обозревателе решений щелкните правой кнопкой мыши каждый из файлов *.tsv и выберите "Свойства". В разделе "Дополнительно" измените значение Копировать в выходной каталог на Копировать, если новее.

Создание классов и определение путей

Добавьте следующие дополнительные using директивы в начало файла Program.cs :

using Microsoft.ML;
using GitHubIssueClassification;

Создайте три глобальных поля для хранения путей к недавно загруженным файлам и глобальные переменные для MLContext, DataView и PredictionEngine.

  • _trainDataPath имеет путь к набору данных, используемому для обучения модели.
  • _testDataPath имеет путь к набору данных, используемому для оценки модели.
  • _modelPath имеет путь, в котором сохранена обученная модель.
  • _mlContext — это объект, предоставляющий MLContext контекст обработки.
  • _trainingDataView IDataView используется для обработки обучаемого набора данных.
  • _predEngine PredictionEngine<TSrc,TDst> используется для отдельных прогнозов.

Добавьте следующий код в строку непосредственно под using директивами, чтобы указать эти пути и другие переменные:

string _appPath = Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]) ?? ".";
string _trainDataPath = Path.Combine(_appPath, "..", "..", "..", "Data", "issues_train.tsv");
string _testDataPath = Path.Combine(_appPath, "..", "..", "..", "Data", "issues_test.tsv");
string _modelPath = Path.Combine(_appPath, "..", "..", "..", "Models", "model.zip");

MLContext _mlContext;
PredictionEngine<GitHubIssue, IssuePrediction> _predEngine;
ITransformer _trainedModel;
IDataView _trainingDataView;

Создайте некоторые классы для входных данных и прогнозов. Добавьте новый класс в проект:

  1. В обозревателе решений щелкните проект правой кнопкой мыши и выберите пункт "Добавить>новый элемент".

  2. В диалоговом окне "Добавление нового элемента" выберите класс и измените поле "Имя" на GitHubIssueData.cs. Затем нажмите кнопку "Добавить".

    Файл GitHubIssueData.cs откроется в редакторе кода. Добавьте следующую using директиву в начало GitHubIssueData.cs:

    using Microsoft.ML.Data;
    
  3. Удалите существующее определение класса и добавьте следующий код в файл GitHubIssueData.cs . Этот код содержит два класса: GitHubIssue и IssuePrediction.

    public class GitHubIssue
    {
        [LoadColumn(0)]
        public string? ID { get; set; }
        [LoadColumn(1)]
        public string? Area { get; set; }
        [LoadColumn(2)]
        public required string Title { get; set; }
        [LoadColumn(3)]
        public required string Description { get; set; }
    }
    
    public class IssuePrediction
    {
        [ColumnName("PredictedLabel")]
        public string? Area;
    }
    

    Это label столбец, который вы хотите прогнозировать. Идентифицированные Features входные данные предоставляют модели для прогнозирования метки.

    Используйте LoadColumnAttribute , чтобы указать индексы исходных столбцов в наборе данных.

    GitHubIssue — это класс входного набора данных и имеет следующие String поля:

    • Первый столбец ID (идентификатор проблемы GitHub).
    • Второй столбец Area (прогноз для обучения).
    • Третий столбец (название проблемы GitHub) — это первыйTitle, feature используемый для прогнозированияArea.
    • Четвертый столбец Description является вторым feature , используемым для прогнозирования Area.

    IssuePrediction — это класс, используемый для прогнозирования после обучения модели. Он имеет один (stringArea) и PredictedLabelColumnName атрибут. Он PredictedLabel используется во время прогнозирования и оценки. Для оценки используются входные данные с данными обучения, прогнозируемые значения и модель.

    Все операции ML.NET начинаются в классе MLContext . Инициализация mlContext создает новую среду ML.NET, которую можно совместно использовать для объектов рабочего процесса создания модели. Это концептуально похоже на DBContext в Entity Framework.

Инициализация переменных

Инициализировать _mlContext глобальную переменную новым экземпляром MLContext, используя случайное начальное значение (seed: 0), для повторяемых или детерминированных результатов при нескольких тренировках. Замените Console.WriteLine("Hello World!") строку следующим кодом:

_mlContext = new MLContext(seed: 0);

Загрузка данных

ML.NET использует интерфейс IDataView как гибкий и эффективный способ описания числовых или текстовых табличных данных. IDataView может загружать текстовые файлы или в режиме реального времени (например, базы данных SQL или файлы журналов).

Чтобы инициализировать и загрузить _trainingDataView глобальную переменную, чтобы использовать ее для конвейера, добавьте следующий код после mlContext инициализации:

_trainingDataView = _mlContext.Data.LoadFromTextFile<GitHubIssue>(_trainDataPath,hasHeader: true);

LoadFromTextFile() определяет схему данных и считывает его в файле. Он принимает переменные пути к данным и возвращает значение IDataView.

Добавьте следующее LoadFromTextFile() после вызова метода:

var pipeline = ProcessData();

Метод ProcessData выполняет следующие задачи:

  • Извлекает и преобразует данные.
  • Возвращает конвейер обработки.

ProcessData Создайте метод в нижней части файла Program.cs с помощью следующего кода:

IEstimator<ITransformer> ProcessData()
{

}

Извлечение функций и преобразование данных

Как, стараясь предсказать метку области GitHub для GitHubIssue, используйте метод MapValueToKey() для преобразования столбца Area в столбец с числовым типом ключа Label (формат, поддерживаемый алгоритмами классификации) и добавьте его как новый столбец набора данных.

var pipeline = _mlContext.Transforms.Conversion.MapValueToKey(inputColumnName: "Area", outputColumnName: "Label")

Затем вызов mlContext.Transforms.Text.FeaturizeText, который преобразует текстовые (Title и Description) столбцы в числовый вектор для каждого вызываемого TitleFeaturized и DescriptionFeaturized. Добавьте фичизацию для обоих столбцов в пайплайн, используя следующий код:

.Append(_mlContext.Transforms.Text.FeaturizeText(inputColumnName: "Title", outputColumnName: "TitleFeaturized"))
.Append(_mlContext.Transforms.Text.FeaturizeText(inputColumnName: "Description", outputColumnName: "DescriptionFeaturized"))

Последний шаг подготовки данных объединяет все столбцы признаков в столбец "Компоненты" с помощью метода Concatenate(). По умолчанию алгоритм обучения обрабатывает только компоненты из столбца "Компоненты ". Добавьте это преобразование в конвейер со следующим кодом:

.Append(_mlContext.Transforms.Concatenate("Features", "TitleFeaturized", "DescriptionFeaturized"))

Затем добавьте AppendCacheCheckpoint к кэшу DataView, чтобы при повторной итерации по данным с помощью кэша, вы могли повысить производительность, как в следующем коде:

.AppendCacheCheckpoint(_mlContext);

Предупреждение

Используйте AppendCacheCheckpoint для небольших и средних наборов данных, чтобы снизить время обучения. Не используйте его (удалите. ДобавлениеCacheCheckpoint()) при обработке очень больших наборов данных.

Верните конвейер в конце ProcessData метода.

return pipeline;

Этот шаг выполняет предварительную обработку и выделение признаков. Использование дополнительных компонентов, доступных в ML.NET, может обеспечить лучшие результаты в модели.

Создание и обучение модели

Добавьте следующий вызов BuildAndTrainModelметода в следующую строку после вызова ProcessData() метода:

var trainingPipeline = BuildAndTrainModel(_trainingDataView, pipeline);

Метод BuildAndTrainModel выполняет следующие задачи:

  • Создает класс алгоритма обучения.
  • Обучает модель.
  • Прогнозирует область на основе обучающих данных.
  • Возвращает модель.

Создайте метод BuildAndTrainModel сразу после объявления метода ProcessData(), используя следующий код.

IEstimator<ITransformer> BuildAndTrainModel(IDataView trainingDataView, IEstimator<ITransformer> pipeline)
{

}

О задаче классификации

Классификация — это задача машинного обучения, которая использует данные для определения категории, типа или класса элемента или строки данных и часто является одним из следующих типов:

  • Двоичное значение: A или B.
  • Мультикласс: несколько категорий, которые можно спрогнозировать с помощью одной модели.

Для этого типа проблемы используйте алгоритм обучения многоклассовой классификации, так как прогнозирование категории проблем может быть одной из нескольких категорий (мультиклассов), а не только двух (двоичных).

Добавьте алгоритм машинного обучения в определения преобразования данных, добавив следующую строку кода в BuildAndTrainModel():

var trainingPipeline = pipeline.Append(_mlContext.MulticlassClassification.Trainers.SdcaMaximumEntropy("Label", "Features"))
        .Append(_mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel"));

SdcaMaximumEntropy — это алгоритм обучения многоклассовой классификации. Это добавляется к pipeline, принимая Title и Description в виде признаков (Features), а также Label в качестве входных параметров для изучения исторических данных.

Обучение модели

Вместите модель в splitTrainSet данные и верните обученную модель, добавив следующую строку кода в BuildAndTrainModel() методе:

_trainedModel = trainingPipeline.Fit(trainingDataView);

Метод Fit()обучает модель путем преобразования набора данных и применения обучения.

PredictionEngine — это удобный API, который позволяет передавать и выполнять прогноз на одном экземпляре данных. Добавьте это в качестве следующей строки в методе BuildAndTrainModel() :

_predEngine = _mlContext.Model.CreatePredictionEngine<GitHubIssue, IssuePrediction>(_trainedModel);

Прогнозирование с помощью обученной модели

Добавьте проблему GitHub для тестирования прогноза обученной модели в методе Predict путем создания экземпляра GitHubIssue:

GitHubIssue issue = new GitHubIssue() {
    Title = "WebSockets communication is slow in my machine",
    Description = "The WebSockets communication used under the covers by SignalR looks like is going slow in my development machine.."
};

Используйте функцию Predict() для создания прогноза для одной строки данных:

var prediction = _predEngine.Predict(issue);

Использование модели: результаты прогнозирования

Отображение GitHubIssue и соответствующее Area прогнозирование меток для совместного использования результатов и соответствующего действия. Создайте отображение результатов с помощью следующего Console.WriteLine() кода:

Console.WriteLine($"=============== Single Prediction just-trained-model - Result: {prediction.Area} ===============");

Возврат модели, обученной для оценки

Возвращает модель в конце BuildAndTrainModel метода.

return trainingPipeline;

Оценка модели

Теперь, когда вы создали и обучили модель, необходимо оценить ее с помощью другого набора данных для обеспечения качества и проверки. В методе Evaluate передается модель, созданная в BuildAndTrainModel, для оценки. Evaluate Создайте метод сразу после BuildAndTrainModel, как показано в следующем коде:

void Evaluate(DataViewSchema trainingDataViewSchema)
{

}

Метод Evaluate выполняет следующие задачи:

  • Загружает тестовый набор данных.
  • Создает средство оценки нескольких классов.
  • Оценивает модель и создает метрики.
  • Отображает метрики.

Добавьте вызов нового метода прямо под вызовом BuildAndTrainModel метода, используя следующий код:

Evaluate(_trainingDataView.Schema);

Как и ранее с набором обучающих данных, загрузите тестовый набор данных, добавив следующий код в Evaluate метод:

var testDataView = _mlContext.Data.LoadFromTextFile<GitHubIssue>(_testDataPath,hasHeader: true);

Метод Evaluate() вычисляет метрики качества для модели с помощью указанного набора данных. Он возвращает MulticlassClassificationMetrics объект, содержащий общие метрики, вычисляемые средствами оценки многоклассовой классификации. Чтобы отобразить метрики для определения качества модели, необходимо сначала получить их. Обратите внимание на использование метода Transform() глобальной переменной машинного обучения _trainedModel ( ITransformer) для ввода функций и возврата прогнозов. Добавьте следующий код в метод в качестве следующей Evaluate строки:

var testMetrics = _mlContext.MulticlassClassification.Evaluate(_trainedModel.Transform(testDataView));

Для многоклассовой классификации оцениваются следующие метрики:

  • Микро точность . Каждая пара класса выборки способствует одинаковой метрике точности. Вы хотите, чтобы микро точность была как можно ближе к одной.
  • Точность макросов — каждый класс соответствует метрикам точности. Классы меньшинства получают равный вес, как и более крупные классы. Вы хотите, чтобы точность макросов была максимально близкой к одной.
  • Логарифмическая потеря — см. Логарифмическая потеря. Вы хотите, чтобы потеря журнала была как можно ближе к нулю.
  • Уменьшение логарифмической потери — диапазон от [-inf, 1.00], где 1.00 – это идеальный прогноз, а 0 указывает на средние прогнозы. Вы хотите, чтобы сокращение потери журналов было максимально близко к одному.

Отображение метрик для проверки модели

Используйте следующий код, чтобы отобразить метрики, предоставить общий доступ к результатам и действовать над ними:

Console.WriteLine($"*************************************************************************************************************");
Console.WriteLine($"*       Metrics for Multi-class Classification model - Test Data     ");
Console.WriteLine($"*------------------------------------------------------------------------------------------------------------");
Console.WriteLine($"*       MicroAccuracy:    {testMetrics.MicroAccuracy:0.###}");
Console.WriteLine($"*       MacroAccuracy:    {testMetrics.MacroAccuracy:0.###}");
Console.WriteLine($"*       LogLoss:          {testMetrics.LogLoss:#.###}");
Console.WriteLine($"*       LogLossReduction: {testMetrics.LogLossReduction:#.###}");
Console.WriteLine($"*************************************************************************************************************");

Сохранение модели в файле

После удовлетворения модели сохраните его в файле, чтобы сделать прогнозы позже или в другом приложении. Добавьте следующий код в метод Evaluate.

SaveModelAsFile(_mlContext, trainingDataViewSchema, _trainedModel);

Создайте метод SaveModelAsFile ниже Evaluate метода.

void SaveModelAsFile(MLContext mlContext,DataViewSchema trainingDataViewSchema, ITransformer model)
{

}

Добавьте следующий код в SaveModelAsFile метод. Этот код использует Save метод для сериализации и хранения обученной модели в виде ZIP-файла.

mlContext.Model.Save(model, trainingDataViewSchema, _modelPath);

Развертывание и прогнозирование с помощью модели

Добавьте вызов нового метода прямо под вызовом Evaluate метода, используя следующий код:

PredictIssue();

PredictIssue Создайте метод сразу после Evaluate метода (и непосредственно перед методом) с помощью следующего SaveModelAsFile кода:

void PredictIssue()
{

}

Метод PredictIssue выполняет следующие задачи:

  • Загружает сохраненную модель.
  • Создает одну проблему тестовых данных.
  • Прогнозирует область на основе тестовых данных.
  • Объединяет тестовые данные и прогнозы для создания отчетов.
  • Отображает прогнозируемые результаты.

Загрузите сохраненную модель в приложение, добавив следующий код в PredictIssue метод:

ITransformer loadedModel = _mlContext.Model.Load(_modelPath, out var modelInputSchema);

Добавьте проблему GitHub для тестирования прогноза обученной модели в методе Predict путем создания экземпляра GitHubIssue:

GitHubIssue singleIssue = new GitHubIssue() { Title = "Entity Framework crashes", Description = "When connecting to the database, EF is crashing" };

Как и ранее, создайте PredictionEngine экземпляр со следующим кодом:

_predEngine = _mlContext.Model.CreatePredictionEngine<GitHubIssue, IssuePrediction>(loadedModel);

PredictionEngine — это удобный API, который позволяет выполнять прогноз на одном экземпляре данных. PredictionEngine не является потокобезопасной. Его можно использовать в однопоточных или прототипных средах. Для повышения производительности и безопасности потоков в рабочих средах используйте PredictionEnginePool службу, которая создает ObjectPoolPredictionEngine объекты для использования во всем приложении. См. это руководство по использованию PredictionEnginePool в веб-API ASP.NET Core.

Замечание

PredictionEnginePool Расширение службы в настоящее время находится в предварительной версии.

PredictionEngine Используйте для прогнозирования метки Area GitHub, добавив следующий код в PredictIssue метод прогнозирования:

var prediction = _predEngine.Predict(singleIssue);

Использование загруженной модели для прогнозирования

Отобразите Area, чтобы классифицировать проблему и действовать соответствующим образом. Создайте отображение результатов с помощью следующего Console.WriteLine() кода:

Console.WriteLine($"=============== Single Prediction - Result: {prediction.Area} ===============");

Results

Ваши результаты должны быть похожи на следующие. В процессе конвейера отображаются сообщения. Вы можете видеть предупреждения или обрабатывать сообщения. Эти сообщения были удалены из следующих результатов для ясности.

=============== Single Prediction just-trained-model - Result: area-System.Net ===============
*************************************************************************************************************
*       Metrics for Multi-class Classification model - Test Data
*------------------------------------------------------------------------------------------------------------
*       MicroAccuracy:    0.738
*       MacroAccuracy:    0.668
*       LogLoss:          .919
*       LogLossReduction: .643
*************************************************************************************************************
=============== Single Prediction - Result: area-System.Data ===============

Поздравляю! Теперь вы успешно создали модель машинного обучения для классификации и прогнозирования метки Области для проблемы GitHub. Исходный код для этого руководства можно найти в репозитории dotnet/samples .

Дальнейшие шаги

Из этого руководства вы узнали, как:

  • Подготовка данных
  • Преобразование данных
  • Обучение модели
  • Оценка модели
  • Прогнозирование с помощью обученной модели
  • Развертывание и прогнозирование с помощью загруженной модели

Продолжите к следующему уроку, чтобы узнать больше.