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


Руководство. Анализ тональности отзывов фильмов с помощью предварительно обученной модели TensorFlow в ML.NET

В этом руководстве показано, как использовать предварительно обученную модель TensorFlow для классификации тональности в комментариях к веб-сайту. Классификатор двоичной тональности — это консольное приложение на C#, разработанное с помощью Visual Studio.

Модель TensorFlow, используемая в этом руководстве, была обучена с помощью обзоров фильмов из базы данных IMDB. Завершив разработку приложения, вы сможете предоставить текст обзора фильма, и приложение сообщит вам, имеет ли обзор положительный или отрицательный тон.

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

  • Загрузка предварительно обученной модели TensorFlow
  • Преобразование текста комментариев веб-сайта в функции, подходящие для модели
  • Использование модели для прогнозирования

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

Предпосылки

Настройка

Создание приложения

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

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

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

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

    Замечание

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

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

Добавление модели TensorFlow в проект

Замечание

Модель для этого руководства — из репозитория dotnet/machinelearning-testdata GitHub. Модель находится в формате TensorFlow SavedModel.

  1. Скачайте zip-файл sentiment_model и распакуйте его.

    Zip-файл содержит следующее:

    • saved_model.pb: сама модель TensorFlow. Модель принимает массив признаков целых чисел фиксированной длины (размер 600), представляющих текст в строке обзора IMDB, и выводит две вероятности, сумма которых равна 1: вероятность того, что входной обзор имеет положительную тональность, и вероятность того, что входной обзор имеет отрицательную тональность.
    • imdb_word_index.csv: сопоставление отдельных слов с целочисленным значением. Сопоставление используется для создания входных функций для модели TensorFlow.
  2. Скопируйте содержимое самого sentiment_model внутреннего каталога в каталог проекта sentiment_model. Этот каталог содержит модель и дополнительные файлы поддержки, необходимые для этого руководства, как показано на следующем рисунке:

    содержимое каталога sentiment_model

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

Добавление using директив и глобальных переменных

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

    using Microsoft.ML;
    using Microsoft.ML.Data;
    using Microsoft.ML.Transforms;
    
  2. Создайте глобальную переменную сразу после using директив, чтобы сохранить путь к файлу модели.

    string _modelPath = Path.Combine(Environment.CurrentDirectory, "sentiment_model");
    
    • _modelPath — это путь к файлу обученной модели.

Моделирование данных

Обзоры фильмов — это текст в свободной форме. Приложение преобразует текст в формат входных данных, ожидаемый моделью в ряде дискретных этапов.

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

Недвижимость Ценность Тип
ReviewText этот фильм очень хороший струна
VariableLengthFeatures 14,22,9,66,78,... int[]

Затем массив признаков переменной длины изменяется до фиксированной длины 600. Это длина, которую ожидает модель TensorFlow.

Недвижимость Ценность Тип
ReviewText этот фильм очень хороший струна
VariableLengthFeatures 14,22,9,66,78,... int[]
Функции 14,22,9,66,78,... int[600]
  1. Создайте класс для входных данных в нижней части файла Program.cs :

    /// <summary>
    /// Class to hold original sentiment data.
    /// </summary>
    public class MovieReview
    {
        public string? ReviewText { get; set; }
    }
    

    Класс входных данных MovieReview имеет string для комментариев пользователей ReviewText.

  2. Создайте класс для функций переменной длины после MovieReview класса:

    /// <summary>
    /// Class to hold the variable length feature vector. Used to define the
    /// column names used as input to the custom mapping action.
    /// </summary>
    public class VariableLength
    {
        /// <summary>
        /// This is a variable length vector designated by VectorType attribute.
        /// Variable length vectors are produced by applying operations such as 'TokenizeWords' on strings
        /// resulting in vectors of tokens of variable lengths.
        /// </summary>
        [VectorType]
        public int[]? VariableLengthFeatures { get; set; }
    }
    

    Свойство VariableLengthFeatures имеет атрибут VectorType , чтобы назначить его вектором. Все элементы вектора должны быть одинаковыми. В наборах данных с большим количеством столбцов загрузка нескольких столбцов в виде одного вектора уменьшает количество передач данных при применении преобразований данных.

    Этот класс используется в действии ResizeFeatures . Имена его свойств (в данном случае только один) используются для указания столбцов в DataView, которые можно использовать в качестве входных данных для пользовательского действия сопоставления.

  3. Создайте класс для функций фиксированной длины после VariableLength класса:

    /// <summary>
    /// Class to hold the fixed length feature vector. Used to define the
    /// column names used as output from the custom mapping action,
    /// </summary>
    public class FixedLength
    {
        /// <summary>
        /// This is a fixed length vector designated by VectorType attribute.
        /// </summary>
        [VectorType(Config.FeatureLength)]
        public int[]? Features { get; set; }
    }
    

    Этот класс используется в действии ResizeFeatures . Имена его свойств (в данном случае только один) используются для указания столбцов в DataView, которые можно использовать в качестве выходных данных пользовательского действия сопоставления.

    Обратите внимание, что имя свойства Features определяется моделью TensorFlow. Нельзя изменить имя этого свойства.

  4. Создайте класс для прогнозирования после FixedLength класса:

    /// <summary>
    /// Class to contain the output values from the transformation.
    /// </summary>
    public class MovieReviewSentimentPrediction
    {
        [VectorType(2)]
        public float[]? Prediction { get; set; }
    }
    

    MovieReviewSentimentPrediction — это класс прогнозирования, используемый после обучения модели. MovieReviewSentimentPrediction имеет один float массив (Prediction) и VectorType атрибут.

  5. Создайте другой класс для хранения значений конфигурации, таких как длина вектора признаков:

    static class Config
    {
        public const int FeatureLength = 600;
    }
    

Создайте MLContext, словарь для поиска и действия для изменения размера признаков

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

  1. Замените Console.WriteLine("Hello World!") строку следующим кодом, чтобы объявить и инициализировать переменную mlContext:

    MLContext mlContext = new MLContext();
    
  2. Создайте словарь для кодирования слов в виде целых чисел с помощью LoadFromTextFile метода для загрузки данных сопоставления из файла, как показано в следующей таблице:

    Слово Index
    детишки 362
    хотеть 181
    неправильный 355
    Эффекты 302
    чувство 547

    Добавьте приведенный ниже код, чтобы создать поисковую карту.

    var lookupMap = mlContext.Data.LoadFromTextFile(Path.Combine(_modelPath, "imdb_word_index.csv"),
        columns: new[]
            {
                new TextLoader.Column("Words", DataKind.String, 0),
                new TextLoader.Column("Ids", DataKind.Int32, 1),
            },
        separatorChar: ','
        );
    
  3. Action Добавьте значение для изменения размера массива целых чисел переменной длины в целый массив фиксированного размера с следующими строками кода:

    Action<VariableLength, FixedLength> ResizeFeaturesAction = (s, f) =>
    {
        var features = s.VariableLengthFeatures;
        Array.Resize(ref features, Config.FeatureLength);
        f.Features = features;
    };
    

Загрузка предварительно обученной модели TensorFlow

  1. Добавьте код для загрузки модели TensorFlow:

    TensorFlowModel tensorFlowModel = mlContext.Model.LoadTensorFlowModel(_modelPath);
    

    После загрузки модели можно извлечь ее входную и выходную схему. Схемы отображаются только для интереса и обучения. Этот код не нужен для работы окончательного приложения:

    DataViewSchema schema = tensorFlowModel.GetModelSchema();
    Console.WriteLine(" =============== TensorFlow Model Schema =============== ");
    var featuresType = (VectorDataViewType)schema["Features"].Type;
    Console.WriteLine($"Name: Features, Type: {featuresType.ItemType.RawType}, Size: ({featuresType.Dimensions[0]})");
    var predictionType = (VectorDataViewType)schema["Prediction/Softmax"].Type;
    Console.WriteLine($"Name: Prediction/Softmax, Type: {predictionType.ItemType.RawType}, Size: ({predictionType.Dimensions[0]})");
    
    

    Входная схема представляет собой массив целочисленных закодированных слов фиксированной длины. Схема результата — это массив вероятностей с плавающей запятой, указывающий, является ли тональность отзыва отрицательной или положительной. Эти значения суммируются до 1, так как вероятность того, что тональность положительная, является дополнением вероятности того, что настроение является отрицательным.

Создание конвейера ML.NET

  1. Создайте конвейер и разделите входной текст на слова с помощью преобразования TokenizeIntoWords , чтобы разбить текст на слова в виде следующей строки кода:

    IEstimator<ITransformer> pipeline =
        // Split the text into individual words
        mlContext.Transforms.Text.TokenizeIntoWords("TokenizedWords", "ReviewText")
    

    Преобразование TokenizeIntoWords использует пробелы для анализа текста или строки на слова. Он создает новый столбец и разбивает каждую входную строку на вектор подстроок на основе определяемого пользователем разделителя.

  2. Сопоставите слова с целочисленной кодировкой с помощью таблицы подстановки, объявленной выше:

    // Map each word to an integer value. The array of integer makes up the input features.
    .Append(mlContext.Transforms.Conversion.MapValue("VariableLengthFeatures", lookupMap,
        lookupMap.Schema["Words"], lookupMap.Schema["Ids"], "TokenizedWords"))
    
  3. Измените кодировки целых чисел с переменной длиной на фиксированную длину, как это требует модель.

    // Resize variable length vector to fixed length vector.
    .Append(mlContext.Transforms.CustomMapping(ResizeFeaturesAction, "Resize"))
    
  4. Классифицируйте входные данные с помощью загруженной модели TensorFlow:

    // Passes the data to TensorFlow for scoring
    .Append(tensorFlowModel.ScoreTensorFlowModel("Prediction/Softmax", "Features"))
    

    Выходные данные модели TensorFlow называются Prediction/Softmax. Обратите внимание, что имя Prediction/Softmax определяется моделью TensorFlow. Вы не можете изменить это имя.

  5. Создайте новый столбец для прогноза выходных данных:

    // Retrieves the 'Prediction' from TensorFlow and copies to a column
    .Append(mlContext.Transforms.CopyColumns("Prediction", "Prediction/Softmax"));
    

    Необходимо скопировать Prediction/Softmax столбец в один с именем, который можно использовать в качестве свойства в классе C#: Prediction Символ / не допускается в имени свойства C#.

Создание модели ML.NET из конвейера

  1. Добавьте код для создания модели из конвейера:

    // Create an executable model from the estimator pipeline
    IDataView dataView = mlContext.Data.LoadFromEnumerable(new List<MovieReview>());
    ITransformer model = pipeline.Fit(dataView);
    

    Модель ML.NET создается из цепочки оценщиков в рамках конвейера, вызывая метод Fit. В этом случае вам не нужно подгонять данные для создания модели, так как модель TensorFlow уже предварительно обучена. Вы предоставляете пустой объект представления данных для удовлетворения требований Fit метода.

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

  1. PredictSentiment Добавьте метод над классомMovieReview:

    void PredictSentiment(MLContext mlContext, ITransformer model)
    {
    
    }
    
  2. Добавьте следующий код, чтобы создать PredictionEngine первую строку в методе PredictSentiment() :

    var engine = mlContext.Model.CreatePredictionEngine<MovieReview, MovieReviewSentimentPrediction>(model);
    

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

    Замечание

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

  3. Добавьте комментарий для тестирования прогноза обученной модели в методе Predict() путем создания экземпляра MovieReview:

    var review = new MovieReview()
    {
        ReviewText = "this film is really good"
    };
    
  4. Передайте данные Prediction Engine комментариев теста, добавив следующие строки кода в PredictSentiment() метод:

    var sentimentPrediction = engine.Predict(review);
    
  5. Функция Predict() делает прогноз по одной строке данных:

    Недвижимость Ценность Тип
    Прогноз [0.5459937, 0.454006255] float[]
  6. Отображение прогноза тональности с помощью следующего кода:

    Console.WriteLine($"Number of classes: {sentimentPrediction.Prediction?.Length}");
    Console.WriteLine($"Is sentiment/review positive? {(sentimentPrediction.Prediction?[1] > 0.5 ? "Yes." : "No.")}");
    
  7. Добавьте вызов PredictSentiment после вызова Fit() метода:

    PredictSentiment(mlContext, model);
    

Results

Создайте и запустите приложение.

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

Number of classes: 2
Is sentiment/review positive ? Yes

Поздравляю! Теперь вы успешно создали модель машинного обучения для классификации и прогнозирования тональности сообщений путем повторного использования предварительно обученной TensorFlow модели в ML.NET.

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

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

  • Загрузка предварительно обученной модели TensorFlow
  • Преобразование текста комментариев веб-сайта в функции, подходящие для модели
  • Использование модели для прогнозирования