Tutorial: Membuat, mengevaluasi, dan menilai model klasifikasi teks

Tutorial ini menyajikan contoh end-to-end dari alur kerja Ilmu Data Synapse untuk model klasifikasi teks, di Microsoft Fabric. Skenario ini menggunakan regresi word2vec dan logistik, pada Spark, untuk menentukan genre buku dari himpunan data buku British Library, hanya berdasarkan judul buku.

Tutorial ini mencakup langkah-langkah berikut:

  • Menginstal pustaka kustom
  • Muat data
  • Memahami dan memproses data dengan analisis data eksploratif
  • Latih model pembelajaran mesin dengan regresi word2vec dan logistik, dan lacak eksperimen dengan MLflow dan fitur autologging Fabric
  • Muat model pembelajaran mesin untuk penilaian dan prediksi

Prasyarat

Ikuti di buku catatan

Anda bisa memilih salah satu opsi ini untuk diikuti dalam buku catatan:

  • Buka dan jalankan notebook bawaan dalam pengalaman Ilmu Data Synapse
  • Unggah buku catatan Anda dari GitHub ke pengalaman Ilmu Data Synapse

Buka buku catatan bawaan

Contoh notebook klasifikasi genre Judul menyertai tutorial ini.

Untuk membuka buku catatan sampel bawaan tutorial dalam pengalaman Ilmu Data Synapse:

  1. Buka halaman beranda Synapse Ilmu Data.

  2. Pilih Gunakan sampel.

  3. Pilih sampel yang sesuai:

    • Dari tab Alur kerja end-to-end (Python) default, jika sampelnya adalah untuk tutorial Python.
    • Dari tab Alur kerja end-to-end (R), jika sampelnya adalah untuk tutorial R.
    • Dari tab Tutorial cepat, jika sampel adalah untuk tutorial cepat.
  4. Lampirkan lakehouse ke buku catatan sebelum Anda mulai menjalankan kode.

Mengimpor notebook dari GitHub

AIsample - Title Genre Classification.ipynb adalah notebook yang menyertai tutorial ini.

Untuk membuka buku catatan yang menyertai tutorial ini, ikuti instruksi dalam Menyiapkan sistem Anda untuk tutorial ilmu data, untuk mengimpor buku catatan ke ruang kerja Anda.

Jika Anda lebih suka menyalin dan menempelkan kode dari halaman ini, Anda bisa membuat buku catatan baru.

Pastikan untuk melampirkan lakehouse ke buku catatan sebelum Anda mulai menjalankan kode.

Langkah 1: Menginstal pustaka kustom

Untuk pengembangan model pembelajaran mesin atau analisis data ad-hoc, Anda mungkin perlu menginstal pustaka kustom dengan cepat untuk sesi Apache Spark Anda. Anda memiliki dua opsi untuk menginstal pustaka.

  • Gunakan kemampuan penginstalan sebaris (%pip atau %conda) buku catatan Anda untuk menginstal pustaka, hanya di buku catatan Anda saat ini.
  • Atau, Anda dapat membuat lingkungan Fabric, menginstal pustaka dari sumber publik atau mengunggah pustaka kustom ke dalamnya, dan kemudian admin ruang kerja Anda dapat melampirkan lingkungan sebagai default untuk ruang kerja. Semua pustaka di lingkungan kemudian akan tersedia untuk digunakan dalam notebook dan definisi pekerjaan Spark di ruang kerja. Untuk informasi selengkapnya tentang lingkungan, lihat membuat, mengonfigurasi, dan menggunakan lingkungan di Microsoft Fabric.

Untuk model klasifikasi, gunakan wordcloud pustaka untuk mewakili frekuensi kata dalam teks, di mana ukuran kata mewakili frekuensinya. Untuk tutorial ini, gunakan %pip install untuk menginstal wordcloud di notebook Anda.

Catatan

Kernel PySpark dimulai ulang setelah %pip install dijalankan. Instal pustaka yang diperlukan sebelum Anda menjalankan sel lain.

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

Langkah 2: Muat data

Himpunan data memiliki metadata tentang buku dari British Library yang kolaborasi antara pustaka dan Microsoft didigitalkan. Metadata adalah informasi klasifikasi untuk menunjukkan apakah buku adalah fiksi atau nonfiksi. Dengan himpunan data ini, tujuannya adalah untuk melatih model klasifikasi yang menentukan genre buku, hanya berdasarkan judulnya.

ID rekaman BL Jenis sumber daya Nama Tanggal yang terkait dengan nama Jenis nama Role Semua nama Judul Judul varian Judul seri Angka dalam seri Negara publikasi Tempat publikasi Publisher Tanggal publikasi Edisi Deskripsi fisik Klasifikasi Dewey Tanda rak BL Topik Genre Bahasa Catatan ID rekaman BL untuk sumber daya fisik classification_id user_id created_at subject_ids annotator_date_pub annotator_normalised_date_pub annotator_edition_statement annotator_genre annotator_FAST_genre_terms annotator_FAST_subject_terms annotator_comments annotator_main_language annotator_other_languages_summaries annotator_summaries_language annotator_translation annotator_original_language annotator_publisher annotator_place_pub annotator_country annotator_title Tautan ke buku digital Beranotasi
014602826 Monografi Yearsley, Ann 1753-1806 person Lebih lanjut, Hannah, 1745-1833 [orang]; Yearsley, Ann, 1753-1806 [orang] Puisi pada beberapa kesempatan [Dengan surat prefatory oleh Hannah More.] Inggris London 1786 Catatan MANUSKRIP edisi keempat Penyimpanan Digital 11644.d.32 Inggris 003996603 Salah
014602830 Monografi A, T. person Oldham, John, 1653-1683 [orang]; A, T. [orang] Satyr melawan Vertue. (Sebuah puisi: seharusnya diucapkan oleh Seorang Town-Hector [Oleh John Oldham. Kata awalan ditandatangani: T. A.]) Inggris London 1679 15 halaman (4°) Penyimpanan Digital 11602.ee.10. (2.) Inggris 000001143 Salah

Tentukan parameter berikut sehingga Anda bisa menerapkan buku catatan ini pada himpunan data yang berbeda:

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

Mengunduh himpunan data dan mengunggah ke lakehouse

Kode ini mengunduh versi himpunan data yang tersedia untuk umum, lalu menyimpannya di Fabric lakehouse.

Penting

Tambahkan lakehouse ke buku catatan sebelum Anda menjalankannya. Kegagalan untuk melakukannya akan mengakibatkan kesalahan.

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

    remote_url = "https://synapseaisolutionsa.blob.core.windows.net/public/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.")

Mengimpor pustaka yang diperlukan

Sebelum pemrosesan apa pun, Anda perlu mengimpor pustaka yang diperlukan, termasuk pustaka untuk Spark dan 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

Tentukan hiperparameter

Tentukan beberapa hiperparameter untuk pelatihan model.

Penting

Ubah hiperparameter ini hanya jika Anda memahami setiap parameter.

# 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

Mulai rekam waktu yang diperlukan untuk menjalankan buku catatan ini:

# Record the notebook running time
import time

ts = time.time()

Menyiapkan pelacakan eksperimen MLflow

Autologging memperluas kemampuan pengelogan MLflow. Autologging secara otomatis menangkap nilai parameter input dan metrik output model pembelajaran mesin saat Anda melatihnya. Anda kemudian mencatat informasi ini ke ruang kerja. Di ruang kerja, Anda dapat mengakses dan memvisualisasikan informasi dengan API MLflow, atau eksperimen yang sesuai, di ruang kerja. Untuk mempelajari selengkapnya tentang autologging, lihat Autologging di Microsoft Fabric.

# Set up Mlflow for experiment tracking

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

Untuk menonaktifkan autologging Microsoft Fabric dalam sesi notebook, panggil mlflow.autolog() dan atur disable=True:

Membaca data tanggal mentah dari lakehouse

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

Langkah 3: Lakukan analisis data eksploratif

Jelajahi himpunan display data dengan perintah , untuk melihat statistik tingkat tinggi untuk himpunan data dan untuk menampilkan tampilan bagan:

display(raw_df.limit(20))

Menyiapkan data

Hapus duplikat untuk membersihkan data:

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

display(df.limit(20))

Terapkan penyeimbangan kelas untuk mengatasi bias apa pun:

# 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))

Pisahkan paragraf dan kalimat menjadi unit yang lebih kecil, untuk membuat token himpunan data. Dengan cara ini, menjadi lebih mudah untuk menetapkan makna. Kemudian, hapus stopword untuk meningkatkan performa. Penghapusan stopword melibatkan penghapusan kata-kata yang umumnya terjadi di semua dokumen di korpus. Penghapusan stopword adalah salah satu langkah praproses yang paling umum digunakan dalam aplikasi pemrosesan bahasa alami (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))

Tampilkan pustaka wordcloud untuk setiap kelas. Pustaka wordcloud adalah presentasi kata kunci yang menonjol secara visual yang sering muncul dalam data teks. Pustaka wordcloud efektif karena penyajian kata kunci membentuk gambar warna seperti cloud, untuk menangkap data teks utama dengan lebih baik secara sekilas. Pelajari lebih lanjut tentang 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")

Terakhir, gunakan word2vec untuk memvektorisasi teks. Teknik word2vec membuat representasi vektor dari setiap kata dalam teks. Kata-kata yang digunakan dalam konteks serupa, atau yang memiliki hubungan semantik, ditangkap secara efektif melalui kedekatannya di ruang vektor. Kedekatan ini menunjukkan bahwa kata serupa memiliki vektor kata yang sama.

# 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))

Langkah 4: Melatih dan mengevaluasi model

Dengan data di tempat, tentukan model. Di bagian ini, Anda melatih model regresi logistik untuk mengklasifikasikan teks vektorisasi.

Menyiapkan himpunan data pelatihan dan pengujian

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

Melacak eksperimen pembelajaran mesin

Eksperimen pembelajaran mesin adalah unit utama organisasi dan kontrol untuk semua eksekusi pembelajaran mesin terkait. Eksekusi sesuai dengan satu eksekusi kode model.

Pelacakan eksperimen pembelajaran mesin mengelola semua eksperimen dan komponennya, misalnya parameter, metrik, model, dan artefak lainnya. Pelacakan memungkinkan organisasi semua komponen yang diperlukan dari eksperimen pembelajaran mesin tertentu. Ini juga memungkinkan reproduksi hasil sebelumnya yang mudah dengan eksperimen yang disimpan. Pelajari selengkapnya tentang eksperimen pembelajaran mesin di Microsoft Fabric.

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

Sesuaikan hyperparameter

Buat kisi parameter untuk mencari hiperparameter. Kemudian buat estimator lintas evaluator, untuk menghasilkan CrossValidator model:

# 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,
)

Evaluasi model

Kita dapat mengevaluasi model pada himpunan data pengujian, untuk membandingkannya. Model yang terlatih dengan baik harus menunjukkan performa tinggi, pada metrik yang relevan, saat dijalankan terhadap validasi dan himpunan data pengujian.

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

Melacak eksperimen dengan menggunakan MLflow

Mulai proses pelatihan dan evaluasi. Gunakan MLflow untuk melacak semua eksperimen, dan parameter log, metrik, dan model. Semua informasi ini dicatat di bawah nama eksperimen di ruang kerja.

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,
        }
    )

Untuk melihat eksperimen Anda:

  1. Pilih ruang kerja Anda di navigasi kiri
  2. Temukan dan pilih nama eksperimen - dalam hal ini, sample_aisample-textclassification

Screenshot of an experiment.

Langkah 5: Menilai dan menyimpan hasil prediksi

Microsoft Fabric memungkinkan pengguna untuk mengoprasikan model pembelajaran mesin dengan fungsi yang PREDICT dapat diskalakan. Fungsi ini mendukung penilaian batch (atau inferensi batch) di mesin komputasi apa pun. Anda dapat membuat prediksi batch langsung dari buku catatan atau halaman item untuk model tertentu. Untuk mempelajari selengkapnya tentang PREDICT dan cara menggunakannya di Fabric, lihat Penilaian model pembelajaran mesin dengan PREDICT di Microsoft Fabric.

Dari hasil evaluasi sebelumnya, model 1 memiliki metrik terbesar untuk Area Di bawah Kurva Presisi-Pengenalan (AUPRC) dan untuk Area Di Bawah Karakteristik Operasi Penerima Kurva (AUC-ROC). Oleh karena itu, Anda harus menggunakan model 1 untuk prediksi.

Ukuran AUC-ROC banyak digunakan untuk mengukur performa pengklasifikasi biner. Namun, terkadang menjadi lebih tepat untuk mengevaluasi pengklasifikasi berdasarkan pengukuran AUPRC. Bagan AUC-ROC memvisualisasikan trade-off antara true positive rate (TPR) dan false positive rate (FPR). Kurva AUPRC menggabungkan presisi (nilai prediktif positif atau PPV) dan pengenalan (tingkat positif sejati atau TPR) dalam satu visualisasi.

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