はじめに
この実験では、scikit-learn で多項式カーネル近似を使用して、効率的に多項式カーネル特徴空間近似を生成する方法を示します。これは、カーネル化された分類器の精度に近似する線形分類器を訓練するために使用されます。私たちは、581,012 個のサンプルと 54 個の特徴を持ち、6 つのクラスに分布する Covtype データセットを使用します。このデータセットの目的は、地図学的変数のみから森林被覆タイプを予測することです (遠隔センシングデータは使用しません)。読み込んだ後、LIBSVM のウェブページにあるデータセットのバージョンに一致させるために、2 値分類問題に変換します。これは、元の論文で使用されたものです。
VM のヒント
VM の起動が完了したら、左上隅をクリックして ノートブック タブに切り替えて、Jupyter Notebook を使用して練習します。
Jupyter Notebook の読み込みには数秒待つ必要がある場合があります。Jupyter Notebook の制限により、操作の検証を自動化することはできません。
学習中に問題が発生した場合は、Labby にお問い合わせください。セッション後にフィードバックを提供してください。私たちは迅速に問題を解決します。
データの読み込みと準備
まず、Covtype データセットを読み込み、1 つのクラスのみを選択することで 2 値分類問題に変換します。その後、データを訓練セットとテストセットに分割し、特徴を正規化します。
from sklearn.datasets import fetch_covtype
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler, Normalizer
## Covtype データセットを読み込み、1 つのクラスのみを選択
X, y = fetch_covtype(return_X_y=True)
y[y!= 2] = 0
y[y == 2] = 1
## データを訓練セットとテストセットに分割
X_train, X_test, y_train, y_test = train_test_split(
X, y, train_size=5000, test_size=10000, random_state=42
)
## 特徴を正規化
mm = make_pipeline(MinMaxScaler(), Normalizer())
X_train = mm.fit_transform(X_train)
X_test = mm.transform(X_test)
ベースラインモデルの構築
ベースラインモデルを構築し、その精度を表示するために、元の特徴で線形 SVM を訓練します。
from sklearn.svm import LinearSVC
## 元の特徴で線形 SVM を訓練
lsvm = LinearSVC(dual="auto")
lsvm.fit(X_train, y_train)
lsvm_score = 100 * lsvm.score(X_test, y_test)
## ベースラインモデルの精度を表示
print(f"Linear SVM score on raw features: {lsvm_score:.2f}%")
カーネル近似モデルの構築
ここでは、異なる n_components の値を持つ PolynomialCountSketch によって生成された特徴で線形 SVM を訓練します。n_components の異なる値をループして各モデルの精度を表示します。
from sklearn.kernel_approximation import PolynomialCountSketch
n_runs = 1
N_COMPONENTS = [250, 500, 1000, 2000]
for n_components in N_COMPONENTS:
ps_lsvm_score = 0
for _ in range(n_runs):
## PolynomialCountSketch によって生成された特徴で線形 SVM を訓練
pipeline = make_pipeline(
PolynomialCountSketch(n_components=n_components, degree=4),
LinearSVC(dual="auto"),
)
pipeline.fit(X_train, y_train)
ps_lsvm_score += 100 * pipeline.score(X_test, y_test)
ps_lsvm_score /= n_runs
## モデルの精度を表示
print(f"Linear SVM score on {n_components} PolynomialCountSketch features: {ps_lsvm_score:.2f}%")
カーネル化 SVM モデルの構築
カーネルの性能をどの程度近似できるかを見るために、カーネル化 SVM を訓練します。
from sklearn.svm import SVC
## カーネル化 SVM を訓練
ksvm = SVC(C=500.0, kernel="poly", degree=4, coef0=0, gamma=1.0)
ksvm.fit(X_train, y_train)
ksvm_score = 100 * ksvm.score(X_test, y_test)
## カーネル化 SVM の精度を表示
print(f"Kernel-SVM score on raw features: {ksvm_score:.2f}%")
結果を比較する
異なる手法の結果を訓練時間に対してプロットし、それらの性能を比較します。
import matplotlib.pyplot as plt
## 異なる手法の結果をプロット
fig, ax = plt.subplots(figsize=(7, 7))
ax.scatter(
[
lsvm_time,
],
[
lsvm_score,
],
label="Linear SVM",
c="green",
marker="^",
)
for n_components in N_COMPONENTS:
ax.scatter(
[
results[f"LSVM + PS({n_components})"]["time"],
],
[
results[f"LSVM + PS({n_components})"]["score"],
],
c="blue",
)
ax.annotate(
f"n_comp.={n_components}",
(
results[f"LSVM + PS({n_components})"]["time"],
results[f"LSVM + PS({n_components})"]["score"],
),
xytext=(-30, 10),
textcoords="offset pixels",
)
ax.scatter(
[
ksvm_time,
],
[
ksvm_score,
],
label="Kernel SVM",
c="red",
marker="x",
)
ax.set_xlabel("Training time (s)")
ax.set_ylabel("Accuracy (%)")
ax.legend()
plt.show()
まとめ
この実験では、scikit-learn で多項式カーネル近似を使用して、多項式カーネル特徴空間の近似を効率的に生成する方法を示しました。この手法を Covtype データセットに適用し、2 値分類問題に変換し、カーネル化されたものの精度に近似する線形分類器を訓練しました。また、異なる手法の性能を比較し、訓練時間に対する結果をプロットしました。