はじめに
scikit-learn ライブラリは、テキストの特徴抽出と評価のためのツールを提供します。この実験では、20newsgroups データセットを使用して、テキストデータから特徴を抽出し、パイプラインを構築し、ハイパーパラメータチューニングを使用してモデルのパフォーマンスを評価する方法を示します。
VM のヒント
VM の起動が完了したら、左上隅をクリックして Notebook タブに切り替え、Jupyter Notebook を開いて練習を行ってください。
場合によっては、Jupyter Notebook の読み込みが完了するまで数秒待つ必要があることがあります。Jupyter Notebook の制限により、操作の検証を自動化することはできません。
学習中に問題が発生した場合は、いつでも Labby に質問してください。セッション終了後にフィードバックを提供していただければ、迅速に問題を解決します。
データの読み込み
ここでは、20 の異なるカテゴリにまたがる約 20,000 のニュースグループ文書のコレクションである 20newsgroups データセットを読み込みます。この実験では、2 つのカテゴリ、alt.atheism と talk.religion.misc に焦点を当てます。
from sklearn.datasets import fetch_20newsgroups
categories = [
"alt.atheism",
"talk.religion.misc",
]
data_train = fetch_20newsgroups(
subset="train",
categories=categories,
shuffle=True,
random_state=42,
remove=("headers", "footers", "quotes"),
)
data_test = fetch_20newsgroups(
subset="test",
categories=categories,
shuffle=True,
random_state=42,
remove=("headers", "footers", "quotes"),
)
print(f"Loading 20 newsgroups dataset for {len(data_train.target_names)} categories:")
print(data_train.target_names)
print(f"{len(data_train.data)} documents")
ハイパーパラメータチューニングを伴うパイプラインの定義
テキスト分類のために、テキストの特徴ベクトル化器と単純な分類器を組み合わせたパイプラインを定義します。分類器として Complement Naive Bayes を、特徴抽出には TfidfVectorizer を使用します。
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import ComplementNB
from sklearn.pipeline import Pipeline
import numpy as np
pipeline = Pipeline(
[
("vect", TfidfVectorizer()),
("clf", ComplementNB()),
]
)
parameter_grid = {
"vect__max_df": (0.2, 0.4, 0.6, 0.8, 1.0),
"vect__min_df": (1, 3, 5, 10),
"vect__ngram_range": ((1, 1), (1, 2)), ## unigrams or bigrams
"vect__norm": ("l1", "l2"),
"clf__alpha": np.logspace(-6, 6, 13),
}
ハイパーパラメータチューニング
RandomizedSearchCV を使用してハイパーパラメータのグリッドを探索し、パイプラインに最適なハイパーパラメータの組み合わせを見つけます。この場合、探索空間を制限するために n_iter=40 を設定しています。n_iter を増やすとより詳細な分析が可能になりますが、計算時間が増加します。
from pprint import pprint
from sklearn.model_selection import RandomizedSearchCV
random_search = RandomizedSearchCV(
estimator=pipeline,
param_distributions=parameter_grid,
n_iter=40,
random_state=0,
n_jobs=2,
verbose=1,
)
print("Performing grid search...")
print("Hyperparameters to be evaluated:")
pprint(parameter_grid)
random_search.fit(data_train.data, data_train.target)
test_accuracy = random_search.score(data_test.data, data_test.target)
結果の可視化
plotly.express を使用して、ハイパーパラメータチューニングの結果を可視化することができます。散布図を使って、スコアリング時間と平均テストスコアのトレードオフを可視化します。また、平行座標を使って、調整されたハイパーパラメータの関数として平均テストスコアをさらに可視化することもできます。
import pandas as pd
import plotly.express as px
import math
def shorten_param(param_name):
"""Remove components' prefixes in param_name."""
if "__" in param_name:
return param_name.rsplit("__", 1)[1]
return param_name
cv_results = pd.DataFrame(random_search.cv_results_)
cv_results = cv_results.rename(shorten_param, axis=1)
param_names = [shorten_param(name) for name in parameter_grid.keys()]
labels = {
"mean_score_time": "CV Score time (s)",
"mean_test_score": "CV score (accuracy)",
}
fig = px.scatter(
cv_results,
x="mean_score_time",
y="mean_test_score",
error_x="std_score_time",
error_y="std_test_score",
hover_data=param_names,
labels=labels,
)
fig.update_layout(
title={
"text": "trade-off between scoring time and mean test score",
"y": 0.95,
"x": 0.5,
"xanchor": "center",
"yanchor": "top",
}
)
column_results = param_names + ["mean_test_score", "mean_score_time"]
transform_funcs = dict.fromkeys(column_results, lambda x: x)
## Using a logarithmic scale for alpha
transform_funcs["alpha"] = math.log10
## L1 norms are mapped to index 1, and L2 norms to index 2
transform_funcs["norm"] = lambda x: 2 if x == "l2" else 1
## Unigrams are mapped to index 1 and bigrams to index 2
transform_funcs["ngram_range"] = lambda x: x[1]
fig = px.parallel_coordinates(
cv_results[column_results].apply(transform_funcs),
color="mean_test_score",
color_continuous_scale=px.colors.sequential.Viridis_r,
labels=labels,
)
fig.update_layout(
title={
"text": "Parallel coordinates plot of text classifier pipeline",
"y": 0.99,
"x": 0.5,
"xanchor": "center",
"yanchor": "top",
}
)
まとめ
この実験では、テキストデータから特徴を抽出し、パイプラインを構築し、ハイパーパラメータチューニングを用いてモデルの性能を評価する方法を示しました。20newsgroups データセットを使用して、RandomizedSearchCV を使ってパイプラインに最適なハイパーパラメータの組み合わせを見つけ、plotly.express を使って結果を可視化する方法を示しました。