👌

【18日目】特徴量選択をやってみる【2021アドベントカレンダー】

2021/12/18に公開

2021年1人アドベントカレンダー(機械学習)、18日目の記事になります。

https://qiita.com/advent-calendar/2021/solo_advent_calendar

テーマは 特徴量選択 になります。

scikit-learn の SequentialFeatureSelector と electFromModel、xfeat の GBDTFeatureSelector を試します。

https://cpp-learning.com/sklearn-feature-selection/

Colab のコードはこちら Open In Colab

SequentialFeatureSelector

SequentialFeatureSelector は 特徴量を順番に選択し、貪欲法により特徴量を選択する手法です。

from sklearn.feature_selection import SequentialFeatureSelector

# 特徴量の選択
n_features = 15

model = lgb.LGBMRegressor(random_state=42)

sfs = SequentialFeatureSelector(
    model, 
    n_features_to_select=n_features, 
    direction='forward'
)

sfs.fit(X_train_tf, y_train)
 
 # 選択された特徴量
print("元の特徴量の数", X_train_tf.shape[1], "選択された特徴量の数", 
        X_train_tf[:, sfs.get_support()].shape[1])

# 特徴量の選択
X_train_select = X_train_tf[:, sfs.get_support()]
X_test_select = X_test_tf[:, sfs.get_support()]

https://scikit-learn.org/stable/modules/generated/sklearn.feature_selection.SequentialFeatureSelector.html

SelectFromModel

SelectFromModel は 重要度の重みに基づいて特徴量を選択する。

from sklearn.feature_selection import SelectFromModel

threshold = 0.15

model = lgb.LGBMRegressor(random_state=42)

sfm = SelectFromModel(
    model, 
    threshold=threshold
)

sfm.fit(X_train_tf, y_train)
 
 # 選択された特徴量
print("元の特徴量の数", X_train_tf.shape[1], "選択された特徴量の数", 
        X_train_tf[:, sfm.get_support()].shape[1])

# 特徴量の選択
X_train_select = X_train_tf[:, sfm.get_support()]
X_test_select = X_test_tf[:, sfm.get_support()]

https://scikit-learn.org/stable/modules/generated/sklearn.feature_selection.SelectFromModel.html

Xfeat の GBDTFeatureSelector

GBDTFeatureSelector は勾配ブースティング決定木(GBDT)の特徴量の重要度に基づいて特徴量を選択する。

目的変数と説明変数を合わせてデータセットとして取り込み、目的変数のカラム名を指定する必要があるため、numpy の array 型になっているデータセットを DataFrame 化してカラム名をセットします。

One-Hot エンコーディングによりカラムが増えているので、ひと工夫が必要です。

### Nullのみで削除されるカラムを削除
for column in ["VGChartz_Score", "Total_Shipped"]:
    number_columns.remove(column)

# OneHotを考慮したの全カラム作成
all_columns = number_columns + \
                many_kinds_category_columns + \
                pipe["columns_transformers"].transformers_[2][1]["onehot"].get_feature_names(
                  few_kinds_category_columns).tolist()

X_train_tf_pd = pd.DataFrame(
                X_train_tf,
                columns=all_columns
            )

y_train_pd = pd.DataFrame(y_train).reset_index(drop=True)

df_tf_pd = pd.concat([X_train_tf_pd, y_train_pd], axis=1)
from xfeat import GBDTFeatureSelector

params = {
    "objective": "regression",
    "seed": SEED,
}
fit_kwargs = {
    "num_boost_round": 10,
}

selector = GBDTFeatureSelector(
    input_cols=df_tf_pd.columns.tolist(),
    target_col="Global_Sales",
    threshold=0.5,
    lgbm_params=params,
    lgbm_fit_kwargs=fit_kwargs,
)

# 選択した特徴量
print("Selected columns:", selector._selected_cols)

# 特徴量選択
df_selected = selector.fit_transform(df_tf_pd)

https://github.com/pfnet-research/xfeat

項目 RMSE
通常 0.192
SequentialFeatureSelector 0.201
SelectFromModel 0.206
Xfeat GBDTFeatureSelector 0.199

https://github.com/pfnet-research/xfeat

18日目は以上になります、最後までお読みいただきありがとうございました。

Discussion