Поделиться через


Инструкция: Создание, оценка и оценивание модели классификации текста

В этом руководстве представлен полный пример рабочего процесса Обработки и анализа данных Synapse для модели классификации текста в Microsoft Fabric. Сценарий использует обработку естественного языка Word2vec (NLP) и логистическую регрессию в Spark для определения жанра книги из набора данных книги британской библиотеки. Определение основано исключительно на названии книги.

В этом руководстве рассматриваются следующие действия.

  • Установка пользовательских библиотек
  • Загрузка данных
  • Понимание и обработка данных с помощью исследовательского анализа данных
  • Обучите модель машинного обучения с использованием Word2vec NLP и логистической регрессии, а также отслеживайте эксперименты с MLflow и функцией автоматического логирования Fabric.
  • Загрузка модели машинного обучения для оценки и прогнозирования

Необходимые условия

  • Получите подписку Microsoft Fabric. Или подпишитесь на бесплатную пробную версию Microsoft Fabric.

  • Войдите в Microsoft Fabric.

  • Используйте переключатель интерфейса в левой нижней части домашней страницы, чтобы перейти на Fabric.

    Снимок экрана меню переключателя режимов, где показано, как выбрать Data Science.

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

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

  • Откройте и запустите встроенную записную книжку.
  • Отправьте записную книжку из GitHub.

Открытие встроенной записной книжки

Пример блокнота для классификации жанров и заголовка сопровождает это руководство.

  1. Чтобы открыть пример ноутбука для этого руководства, следуйте инструкциям в Подготовка системы для учебников по анализу данных.

  2. Перед началом выполнения кода обязательно подключить lakehouse к блокноту.

Импорт записной книжки из GitHub

AIsample — Жанровая классификация Title.ipynb — это тетрадь, сопровождающая это руководство.

Шаг 1. Установка пользовательских библиотек

Для разработки моделей машинного обучения или нерегламентированного анализа данных может потребоваться быстро установить пользовательскую библиотеку для сеанса Apache Spark. У вас есть два варианта установки библиотеки.

  • Чтобы установить библиотеку только в текущей записной книжке, используйте встроенные функции установки (%pip или %conda) вашей записной книжки.
  • В качестве альтернативы можно создать среду Fabric и установить библиотеки из общедоступных источников или отправить в него пользовательские библиотеки. Затем администратор рабочей области может присоединить среду по умолчанию для этой рабочей области. На этом этапе все библиотеки в среде становятся доступными для использования во всех записных книжках и всех определениях заданий Spark в этой рабочей области. Дополнительные сведения о средах см. в статье о создании, настройке и использовании среды в ресурсе Microsoft Fabric .

Для модели классификации используйте библиотеку wordcloud для представления частоты слова в тексте. В wordcloud ресурсах размер слова представляет свою частоту. В этом руководстве используйте %pip install для установки wordcloud в ноутбук.

Заметка

Ядро PySpark перезапускается после выполнения %pip install. Установите необходимые библиотеки перед запуском любых других ячеек.

# Install wordcloud for text visualization by using pip
%pip install wordcloud

Шаг 2. Загрузка данных

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

Идентификатор записи BL Тип ресурса Имя Даты, связанные с именем Тип имени Роль Все имена Титул Названия вариантов Заголовок серии Число в серии Страна публикации Место публикации Издатель Дата публикации Издание Физическое описание Классификация Dewey Сигнатура BL Темы Жанр Языки Примечания Идентификатор записи BL для физического ресурса идентификатор классификации идентификатор пользователя создано_в идентификаторы_предметов аннотатор_дата_публикации аннотатор_нормализованная_дата_публикации заявление об издании аннотатором аннотатoр_жанр аннотатор_FAST_жанровые_термины аннотатор_FAST_тематические_термины комментарии аннотатора основной_язык_аннотатора аннотатор_резюме_другие_языки язык резюме аннотаторов перевод аннотатора annotator_original_language аннотатор_издатель аннотатор_место_публикации страна_аннотатора заголовок аннотатора Ссылка на оцифровку книги аннотированный
014602826 Монография Йирсли, Энн 1753-1806 Человек Мор, Ханна, 1745-1833; Йирсли, Энн, 1753-1806 Стихотворения на разные случаи [С префаторным письмом Ханны Мур.] Англия Лондон 1786 Примечание к рукописи четвертого издания Digital Store 11644.d.32 Английский 003996603 Неверно
014602830 Монография А, Т. Человек Олхэм, Джон, 1653-1683 [человек]; A, T. [person] Сатир против Vertue. (Стихотворение: должно быть произнесено Town-Hector [Джон Олхэм. Предисловие, подписанное: Т. А.]) Англия Лондон 1679 15 страниц (4°) Цифровой магазин 11602.ee.10. (2.) Английский 000001143 Неверно

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

Определите следующие параметры, чтобы применить эту записную книжку к разным наборам данных:

IS_CUSTOM_DATA = False  # If True, the user must manually upload the dataset
DATA_FOLDER = "Files/title-genre-classification"
DATA_FILE = "blbooksgenre.csv"

# Data schema
TEXT_COL = "Title"
LABEL_COL = "annotator_genre"
LABELS = ["Fiction", "Non-fiction"]

EXPERIMENT_NAME = "sample-aisample-textclassification"  # MLflow experiment name

Скачайте набор данных и отправьте его в lakehouse

Следующий фрагмент кода скачивает общедоступную версию набора данных, а затем сохраняет ее в Fabric lakehouse:

Важный

Добавьте lakehouse в записную книжку перед запуском. Невыполнение этого приводит к ошибке.

if not IS_CUSTOM_DATA:
    # Download demo data files into the lakehouse, if they don't exist
    import os, requests

    remote_url = "https://synapseaisolutionsa.z13.web.core.windows.net/data/Title_Genre_Classification"
    fname = "blbooksgenre.csv"
    download_path = f"/lakehouse/default/{DATA_FOLDER}/raw"

    if not os.path.exists("/lakehouse/default"):
        # Add a lakehouse, if no default lakehouse was added to the notebook
        # A new notebook won't link to any lakehouse by default
        raise FileNotFoundError(
            "Default lakehouse not found, please add a lakehouse and restart the session."
        )
    os.makedirs(download_path, exist_ok=True)
    if not os.path.exists(f"{download_path}/{fname}"):
        r = requests.get(f"{remote_url}/{fname}", timeout=30)
        with open(f"{download_path}/{fname}", "wb") as f:
            f.write(r.content)
    print("Downloaded demo data files into lakehouse.")

Импорт обязательных библиотек

Перед любой обработкой необходимо импортировать необходимые библиотеки, включая библиотеки для Spark и SynapseML:

import numpy as np
from itertools import chain

from wordcloud import WordCloud
import matplotlib.pyplot as plt
import seaborn as sns

import pyspark.sql.functions as F

from pyspark.ml import Pipeline
from pyspark.ml.feature import *
from pyspark.ml.tuning import CrossValidator, ParamGridBuilder
from pyspark.ml.classification import LogisticRegression
from pyspark.ml.evaluation import (
    BinaryClassificationEvaluator,
    MulticlassClassificationEvaluator,
)

from synapse.ml.stages import ClassBalancer
from synapse.ml.train import ComputeModelStatistics

import mlflow

Определение гиперпараметров

Следующий фрагмент кода определяет необходимые гиперпараметры для обучения модели:

Важно

Измените эти гиперпараметры, только если вы понимаете каждый параметр.

# Hyperparameters 
word2vec_size = 128  # The length of the vector for each word
min_word_count = 3  # The minimum number of times that a word must appear to be considered
max_iter = 10  # The maximum number of training iterations
k_folds = 3  # The number of folds for cross-validation

Начните запись времени, необходимого для запуска этой записной книжки:

# Record the notebook running time
import time

ts = time.time()

Настройка отслеживания экспериментов MLflow

Автологирование расширяет возможности ведения журнала MLflow. Автологирование автоматически записывает входные значения параметров и выходные метрики модели машинного обучения при его обучении. Затем вы записываете эту информацию в рабочее пространство. В рабочей области можно получить доступ и визуализировать сведения с помощью API MLflow или соответствующего эксперимента в рабочей области. Дополнительные сведения об автологе см. в разделе "Автологирование" в ресурсе Microsoft Fabric .

Чтобы отключить автологирование Microsoft Fabric в сеансе записной книжки, вызовите mlflow.autolog() и задайте disable=True:

# Set up Mlflow for experiment tracking

mlflow.set_experiment(EXPERIMENT_NAME)
mlflow.autolog(disable=True)  # Disable Mlflow autologging

Чтение необработанных данных даты из lakehouse

raw_df = spark.read.csv(f"{DATA_FOLDER}/raw/{DATA_FILE}", header=True, inferSchema=True)

Шаг 3. Выполнение анализа аналитических данных

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

display(raw_df.limit(20))

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

Чтобы очистить данные, удалите дубликаты:

df = (
    raw_df.select([TEXT_COL, LABEL_COL])
    .where(F.col(LABEL_COL).isin(LABELS))
    .dropDuplicates([TEXT_COL])
    .cache()
)

display(df.limit(20))

Примените балансировку классов для решения любой предвзятости:

# Create a ClassBalancer instance, and set the input column to LABEL_COL
cb = ClassBalancer().setInputCol(LABEL_COL)

# Fit the ClassBalancer instance to the input DataFrame, and transform the DataFrame
df = cb.fit(df).transform(df)

# Display the first 20 rows of the transformed DataFrame
display(df.limit(20))

Чтобы маркеризировать набор данных, разделите абзацы и предложения на меньшие единицы. Таким образом, проще назначить значение. Затем удалите стоп-слова, чтобы повысить производительность. Удаление стоп-слов заключается в удалении слов, которые обычно встречаются во всех документах в корпусе. Удаление стоп-слов является одним из наиболее часто используемых шагов предварительной обработки в приложениях обработки естественного языка (NLP). В следующем фрагменте кода рассматриваются следующие действия.

# Text transformer
tokenizer = Tokenizer(inputCol=TEXT_COL, outputCol="tokens")
stopwords_remover = StopWordsRemover(inputCol="tokens", outputCol="filtered_tokens")

# Build the pipeline
pipeline = Pipeline(stages=[tokenizer, stopwords_remover])

token_df = pipeline.fit(df).transform(df)

display(token_df.limit(20))

Отображение библиотеки wordcloud для каждого класса. Библиотека облаков слов отображает ключевые слова, которые часто встречаются в текстовых данных, представляя их в визуально заметной форме. Библиотека WordCloud эффективна, так как ключевые слова формируют облачную цветную картину, чтобы лучше схватывать основные текстовые данные с первого взгляда. Дополнительные сведения о wordcloud см. в этом ресурсе .

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

# WordCloud
for label in LABELS:
    tokens = (
        token_df.where(F.col(LABEL_COL) == label)
        .select(F.explode("filtered_tokens").alias("token"))
        .where(F.col("token").rlike(r"^\w+$"))
    )

    top50_tokens = (
        tokens.groupBy("token").count().orderBy(F.desc("count")).limit(50).collect()
    )

    # Generate a wordcloud image
    wordcloud = WordCloud(
        scale=10,
        background_color="white",
        random_state=42,  # Make sure the output is always the same for the same input
    ).generate_from_frequencies(dict(top50_tokens))

    # Display the generated image by using matplotlib
    plt.figure(figsize=(10, 10))
    plt.title(label, fontsize=20)
    plt.axis("off")
    plt.imshow(wordcloud, interpolation="bilinear")

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

# Label transformer
label_indexer = StringIndexer(inputCol=LABEL_COL, outputCol="labelIdx")
vectorizer = Word2Vec(
    vectorSize=word2vec_size,
    minCount=min_word_count,
    inputCol="filtered_tokens",
    outputCol="features",
)

# Build the pipeline
pipeline = Pipeline(stages=[label_indexer, vectorizer])
vec_df = (
    pipeline.fit(token_df)
    .transform(token_df)
    .select([TEXT_COL, LABEL_COL, "features", "labelIdx", "weight"])
)

display(vec_df.limit(20))

Шаг 4. Обучение и оценка модели

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

Подготовка обучающих и тестовых наборов данных

Следующий фрагмент кода разделяет набор данных:

# Split the dataset into training and testing
(train_df, test_df) = vec_df.randomSplit((0.8, 0.2), seed=42)

Отслеживание экспериментов машинного обучения

Отслеживание экспериментов машинного обучения управляет всеми экспериментами и их компонентами, например параметрами, метриками, моделями и другими артефактами. Отслеживание позволяет организации и управлению всеми компонентами, которым требуется определенный эксперимент машинного обучения. Это также позволяет легко воспроизводить прошлые результаты с сохраненными экспериментами. Дополнительные сведения см. на странице Эксперименты машинного обучения в Microsoft Fabric.

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

# Build the logistic regression classifier
lr = (
    LogisticRegression()
    .setMaxIter(max_iter)
    .setFeaturesCol("features")
    .setLabelCol("labelIdx")
    .setWeightCol("weight")
)

Настройка гиперпараметров

Создайте сетку параметров для поиска по гиперпараметрам. Затем создайте оценщик для кросс-валидации, чтобы произвести модель CrossValidator, как показано в следующем фрагменте кода:

# Build a grid search to select the best values for the training parameters
param_grid = (
    ParamGridBuilder()
    .addGrid(lr.regParam, [0.03, 0.1])
    .addGrid(lr.elasticNetParam, [0.0, 0.1])
    .build()
)

if len(LABELS) > 2:
    evaluator_cls = MulticlassClassificationEvaluator
    evaluator_metrics = ["f1", "accuracy"]
else:
    evaluator_cls = BinaryClassificationEvaluator
    evaluator_metrics = ["areaUnderROC", "areaUnderPR"]
evaluator = evaluator_cls(labelCol="labelIdx", weightCol="weight")

# Build a cross-evaluator estimator
crossval = CrossValidator(
    estimator=lr,
    estimatorParamMaps=param_grid,
    evaluator=evaluator,
    numFolds=k_folds,
    collectSubModels=True,
)

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

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

def evaluate(model, df):
    log_metric = {}
    prediction = model.transform(df)
    for metric in evaluator_metrics:
        value = evaluator.evaluate(prediction, {evaluator.metricName: metric})
        log_metric[metric] = value
        print(f"{metric}: {value:.4f}")
    return prediction, log_metric

Отслеживание экспериментов с помощью MLflow

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

with mlflow.start_run(run_name="lr"):
    models = crossval.fit(train_df)
    best_metrics = {k: 0 for k in evaluator_metrics}
    best_index = 0
    for idx, model in enumerate(models.subModels[0]):
        with mlflow.start_run(nested=True, run_name=f"lr_{idx}") as run:
            print("\nEvaluating on test data:")
            print(f"subModel No. {idx + 1}")
            prediction, log_metric = evaluate(model, test_df)

            if log_metric[evaluator_metrics[0]] > best_metrics[evaluator_metrics[0]]:
                best_metrics = log_metric
                best_index = idx

            print("log model")
            mlflow.spark.log_model(
                model,
                f"{EXPERIMENT_NAME}-lrmodel",
                registered_model_name=f"{EXPERIMENT_NAME}-lrmodel",
                dfs_tmpdir="Files/spark",
            )

            print("log metrics")
            mlflow.log_metrics(log_metric)

            print("log parameters")
            mlflow.log_params(
                {
                    "word2vec_size": word2vec_size,
                    "min_word_count": min_word_count,
                    "max_iter": max_iter,
                    "k_folds": k_folds,
                    "DATA_FILE": DATA_FILE,
                }
            )

    # Log the best model and its relevant metrics and parameters to the parent run
    mlflow.spark.log_model(
        models.subModels[0][best_index],
        f"{EXPERIMENT_NAME}-lrmodel",
        registered_model_name=f"{EXPERIMENT_NAME}-lrmodel",
        dfs_tmpdir="Files/spark",
    )
    mlflow.log_metrics(best_metrics)
    mlflow.log_params(
        {
            "word2vec_size": word2vec_size,
            "min_word_count": min_word_count,
            "max_iter": max_iter,
            "k_folds": k_folds,
            "DATA_FILE": DATA_FILE,
        }
    )

Чтобы просмотреть эксперименты, выполните следующее:

  1. Выберите рабочую область в левой навигации
  2. Найдите и выберите имя эксперимента — в данном случае sample_aisample-textclassification

снимок экрана эксперимента.

Шаг 5. Оценка и сохранение результатов прогнозирования

Microsoft Fabric позволяет пользователям работать с моделями машинного обучения с помощью масштабируемой PREDICT функции. Эта функция поддерживает пакетную оценку (или пакетное выведение) в любом вычислительном механизме. Вы можете создавать пакетные прогнозы прямо из записной книжки или на странице элемента для конкретной модели. Дополнительные сведения о PREDICT функции и его использовании в Fabric см. в статье "Оценка модели машинного обучения с помощью PREDICT в Microsoft Fabric".

В результатах оценки модель 1 имеет наибольшие значения метрик для обеих областей под кривой Precision-Recall (AUPRC) и под кривой операционной характеристики приемника (AUC-ROC). Поэтому для прогнозирования следует использовать модель 1.

Мера AUC-ROC широко используется для измерения производительности двоичных классификаторов. Однако иногда становится более уместным оценивать классификатор с использованием метода измерений AUPRC. Диаграмма AUC-ROC визуализирует компромисс между истинной положительной скоростью (TPR) и ложноположительной положительной скоростью (FPR). Кривая AUPRC объединяет как точность (положительное прогнозное значение или PPV), так и отзыв (истинная положительная скорость или TPR) в одной визуализации. Следующие фрагменты кода охватывают следующие действия.

# Load the best model
model_uri = f"models:/{EXPERIMENT_NAME}-lrmodel/1"
loaded_model = mlflow.spark.load_model(model_uri, dfs_tmpdir="Files/spark")

# Verify the loaded model
batch_predictions = loaded_model.transform(test_df)
batch_predictions.show(5)
# Code to save userRecs in the lakehouse
batch_predictions.write.format("delta").mode("overwrite").save(
    f"{DATA_FOLDER}/predictions/batch_predictions"
)
# Determine the entire runtime
print(f"Full run cost {int(time.time() - ts)} seconds.")