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
Dapatkan langganan Microsoft Fabric. Atau, daftar untuk uji coba Microsoft Fabric gratis.
Masuk ke Microsoft Fabric.
Gunakan pengalih pengalaman di sisi kiri halaman beranda Anda untuk beralih ke pengalaman Ilmu Data Synapse.
- Jika Anda tidak memiliki Microsoft Fabric lakehouse, buat dengan mengikuti langkah-langkah di Membuat lakehouse di Microsoft Fabric.
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:
Buka halaman beranda Synapse Ilmu Data.
Pilih Gunakan sampel.
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.
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:
- Pilih ruang kerja Anda di navigasi kiri
- Temukan dan pilih nama eksperimen - dalam hal ini, sample_aisample-textclassification
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.")
Konten terkait
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk