単変量特徴選択

Beginner

This tutorial is from open-source community. Access the source code

はじめに

この実験では、ノイズの多いデータセットでの分類精度を向上させるために単変量特徴選択をどのように使用するかを示します。単変量特徴選択を適用する前後でサポートベクターマシン (SVM) を使用してデータセットを分類します。各特徴について、単変量特徴選択の p 値と SVM の対応する重みをプロットします。これにより、モデルの精度を比較し、単変量特徴選択がモデルの重みに与える影響を調べます。

VM のヒント

VM の起動が完了したら、左上隅をクリックして ノートブック タブに切り替えて、Jupyter Notebook を使った練習にアクセスします。

Jupyter Notebook の読み込みには数秒待つ必要がある場合があります。Jupyter Notebook の制限により、操作の検証を自動化することはできません。

学習中に問題がある場合は、Labby にお問い合わせください。セッション後にフィードバックを提供してください。すぐに問題を解決いたします。

サンプルデータを生成する

まず、このデモ用にいくつかのサンプルデータを生成します。iris データセットを使用し、それに相関のないノイズデータを追加します。

import numpy as np
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

## iris データセット
X, y = load_iris(return_X_y=True)

## 相関のないいくつかのノイズデータ
E = np.random.RandomState(42).uniform(0, 0.1, size=(X.shape[0], 20))

## ノイズデータを情報的な特徴に追加する
X = np.hstack((X, E))

## 特徴を選択し、分類器を評価するためにデータセットを分割する
X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, random_state=0)

単変量特徴選択

次に、F 検定を用いて特徴の評点付けを行う単変量特徴選択を行います。4 つの最も重要な特徴を選択するためにデフォルトの選択関数を使用します。

from sklearn.feature_selection import SelectKBest, f_classif

selector = SelectKBest(f_classif, k=4)
selector.fit(X_train, y_train)
scores = -np.log10(selector.pvalues_)
scores /= scores.max()

特徴の単変量スコアをプロットする

各特徴の単変量スコアをプロットすることで、どの特徴が有意であるかを確認することができます。

import matplotlib.pyplot as plt

X_indices = np.arange(X.shape[-1])
plt.figure(1)
plt.clf()
plt.bar(X_indices - 0.05, scores, width=0.2)
plt.title("Feature univariate score")
plt.xlabel("Feature number")
plt.ylabel(r"Univariate score ($-Log(p_{value})$)")
plt.show()

SVM と比較する

ここでは、単変量特徴選択を行った場合と行わなかった場合の SVM の分類精度を比較します。

単変量特徴選択なし
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import MinMaxScaler
from sklearn.svm import LinearSVC

clf = make_pipeline(MinMaxScaler(), LinearSVC(dual="auto"))
clf.fit(X_train, y_train)
print(
    "Classification accuracy without selecting features: {:.3f}".format(
        clf.score(X_test, y_test)
    )
)

svm_weights = np.abs(clf[-1].coef_).sum(axis=0)
svm_weights /= svm_weights.sum()
単変量特徴選択後
clf_selected = make_pipeline(
    SelectKBest(f_classif, k=4), MinMaxScaler(), LinearSVC(dual="auto")
)
clf_selected.fit(X_train, y_train)
print(
    "Classification accuracy after univariate feature selection: {:.3f}".format(
        clf_selected.score(X_test, y_test)
    )
)

svm_weights_selected = np.abs(clf_selected[-1].coef_).sum(axis=0)
svm_weights_selected /= svm_weights_selected.sum()

特徴選択の比較をプロットする

各特徴の特徴スコアと重みをプロットすることで、単変量特徴選択の影響を確認することができます。

plt.bar(
    X_indices - 0.45, scores, width=0.2, label=r"Univariate score ($-Log(p_{value})$)"
)

plt.bar(X_indices - 0.25, svm_weights, width=0.2, label="SVM weight")

plt.bar(
    X_indices[selector.get_support()] - 0.05,
    svm_weights_selected,
    width=0.2,
    label="SVM weights after selection",
)

plt.title("Comparing feature selection")
plt.xlabel("Feature number")
plt.yticks(())
plt.axis("tight")
plt.legend(loc="upper right")
plt.show()

まとめ

この実験では、ノイズの多いデータセットでの分類精度を向上させるために単変量特徴選択をどのように使用するかを示しました。サンプルデータを生成し、単変量特徴選択を行い、単変量特徴選択を行った場合と行わなかった場合の SVM の分類精度を比較しました。また、各特徴の特徴スコアと重みをプロットして、単変量特徴選択の影響を確認しました。