反復特徴量選択


AIって結局何なのかよく分からないので、とりあえず100日間勉強してみた Day30


経緯についてはこちらをご参照ください。



■本日の進捗

●反復特徴量選択を理解

■はじめに

引き続き「Pythonではじめる機械学習(オライリー・ジャパン)」で学んでいきます。

これまで自動特徴量選択からモデルをひとつ用いて特徴量選択をするモデルベース特徴量選択と、全く使わない特徴量選択である単変量統計を学んできました。今回は自動特徴量選択の最終稿として複数のモデルを作る反復特徴量選択を理解していきたいと思います。

■反復特徴量選択

反復特徴量選択(interative feature selection)とは、学習モデルの予測精度を最適化するために特徴量をすべて使って学習する状態からひとつずつ特徴量を削減していく(あるいは全く特徴量がない状態からひとつずつ増やしていく)手法です。

すべての特徴量を使った状態からひとつずつ削減していく手法のひとつに再帰的特徴量選択(recursive feature elimination : RFE)があります。この手法も再帰的にモデルを作っていく中で各学習モデルが用いた特徴量に重要度をつけ、最も重要度の低い特徴量を削減していきます。

この手法はひとつだけモデルを作成するモデルベース特徴量選択より更に高度な故に更に処理に時間がかかります。また、試行回数が多くなるので選択したモデルに依存しやすくなる可能性があります。

まずは前回のおさらいですが、あやめデータセットに大量のノイズを付加したデータにロジスティック回帰で学習させたモデルの予測精度のスコアは0.844でした。

同じデータセットにランダムフォレストを用いたRFEを適用してみます。

import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.feature_selection import RFE

iris = load_iris()
X = pd.DataFrame(iris.data, columns=iris.feature_names)
y = iris.target

np.random.seed(8)
for i in range(88):
    X[f'noise_feature_{i+1}'] = np.random.rand(X.shape[0])

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=8)

selector = RFE(RandomForestClassifier(n_estimators=100, random_state=8), n_features_to_select=10)

selector.fit(X_train, y_train)
X_train_rfe = selector.transform(X_train)
X_test_rfe = selector.transform(X_test)

model = LogisticRegression(max_iter=1000, random_state=8)
model.fit(X_train_rfe, y_train)

score = model.score(X_test_rfe, y_test)
print("score is ", score)

今回は最終的に残す特徴量の数を10(n_features_to_select=10)までにしたので最低でも作為的に付加したノイズ特徴量が6つは残ることになります。それでも適切に特徴量削減をできているのかスコアが大きく向上しています。

この場合は4つの特徴量のみが重要であることが予め分かっているので、検証のためにn_features_to_selectの引数を4にしてみましょう。

import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.feature_selection import RFE

iris = load_iris()
X = pd.DataFrame(iris.data, columns=iris.feature_names)
y = iris.target

np.random.seed(8)
for i in range(88):
    X[f'noise_feature_{i+1}'] = np.random.rand(X.shape[0])

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=8)

selector = RFE(RandomForestClassifier(n_estimators=100, random_state=8), n_features_to_select=4)

selector.fit(X_train, y_train)
X_train_rfe = selector.transform(X_train)
X_test_rfe = selector.transform(X_test)

model = LogisticRegression(max_iter=1000, random_state=8)
model.fit(X_train_rfe, y_train)

score = model.score(X_test_rfe, y_test)
print("score is ", score)

元のあやめデータセットにロジスティック回帰を適用した場合のモデルの予測精度はおよそ0.933付近(この乱数シードではこの値にある)なので、見事にノイズを除去できていることが分かります。

■おわりに

自動特徴量選択手法を3つ学んできました。汎化性能を上げたい場合や解釈しやすいモデルを構築したい場合に有用な手法でだと理解しました。

■参考文献

  1. Andreas C. Muller, Sarah Guido. Pythonではじめる機械学習. 中田 秀基 訳. オライリー・ジャパン. 2017. 392p.
  2. ChatGPT. 4o mini. OpenAI. 2024. https://chatgpt.com/
  3. API Reference. scikit-learn.org. https://scikit-learn.org/stable/api/index.html


コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です