Borutaを活用した特徴量選択を試してみた

* 製造業出身のデータサイエンティストがお送りする記事
* 今回はBorutaを活用した特徴量選択を試してみました。

##はじめに
Borutaとは、あえて目的変数と関係のない説明変数を追加して、例えばランダムフォレストを行なって変数重要度をオリジナルの説明変数と比較し、選択すべき説明変数を検討する方法となります。

##Borutaを使用した変数選択
下記4ステップの手順を踏んでいます。

1. 判別に寄与しないはずの偽の特徴量を作成。
2. 偽の特徴量と一緒にランダムフォレストを訓練。
3. 各特徴量の重要度と偽の特徴量の特徴量を比較。
4. 複数回比較し検定を行うことで、本当に重要な特徴量のみを選択。

初めに全ての特徴量を用いてボストン住宅価格を予測してみます。
使用する手法はランダムフォレストを使ってみます。

```php
# ライブラリーのインポート
import numpy as np
import pandas as pd
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
from boruta import BorutaPy

# スコア計算のためのライブラリ
from sklearn.metrics import r2_score
from sklearn.metrics import mean_absolute_error

# ボストン住宅の価格のデータセットを読み込む
boston = load_boston()
X = pd.DataFrame(boston.data, columns=boston.feature_names)
y = pd.Series(boston.target, name='target')

# 乱数シード
RANDOM_STATE = 3

# 訓練データとテストデータに分割する
X_train, X_test, y_train, y_test = train_test_split(X, y)

# 全部の特徴量で学習
RF = RandomForestRegressor(random_state=RANDOM_STATE)
RF.fit(X_train, y_train)

# 予測　
pred_RF = RF.predict(X_test)

# 評価
# 決定係数(R2)
r2_RF = r2_score(y_test, pred_RF)

# 平均絶対誤差(MAE)
mae_RF = mean_absolute_error(y_test, pred_RF)

print("R2　:　%.3f" % r2_RF)
print("MAE : %.3f" % mae_RF)

#R2　:　0.903
#MAE : 2.226
```

次にBorutaを使って選択された特徴量を用いて予測を行ってみます。

```php
# RandomForestRegressorでBorutaを実行
RF1 = RandomForestRegressor(random_state=RANDOM_STATE)
feat_selector = BorutaPy(RF1, n_estimators='auto', verbose=2, random_state=1)
feat_selector.fit(X_train.values, y_train.values)

# 選択された特徴量を確認
selected = feat_selector.support_
print('選択された特徴量の数: %d' % np.sum(selected))
print(selected)
print(X.columns[selected])
```

選択された説明変数は下記9個です。

```
Iteration: 	1 / 100
Confirmed: 	0
Tentative: 	13
Rejected: 	0
Iteration: 	2 / 100
Confirmed: 	0
Tentative: 	13
Rejected: 	0
Iteration: 	3 / 100
Confirmed: 	0
Tentative: 	13
Rejected: 	0
Iteration: 	4 / 100
Confirmed: 	0
Tentative: 	13
Rejected: 	0
Iteration: 	5 / 100
Confirmed: 	0
Tentative: 	13
Rejected: 	0
Iteration: 	6 / 100
Confirmed: 	0
Tentative: 	13
Rejected: 	0
Iteration: 	7 / 100
Confirmed: 	0
Tentative: 	13
Rejected: 	0
Iteration: 	8 / 100
Confirmed: 	9
Tentative: 	0
Rejected: 	4


BorutaPy finished running.

Iteration: 	9 / 100
Confirmed: 	9
Tentative: 	0
Rejected: 	4
選択された特徴量の数: 9
[ True False False False  True  True  True  True False  True  True  True
  True]
Index(['CRIM', 'NOX', 'RM', 'AGE', 'DIS', 'TAX', 'PTRATIO', 'B', 'LSTAT'], dtype='object')
```

Borutaで選択された説明変数を用いてボストン住宅価格を予測してみます。

```php
# 選択した特徴量で学習
X_train_selected = X_train[X.columns[selected]]
X_test_selected = X_test[X.columns[selected]]
RF2 = RandomForestRegressor(random_state=RANDOM_STATE)
RF2.fit(X_train_selected, y_train)

# 予測　
pred_RF_boruta = RF2.predict(X_test_selected)

# 評価
# 決定係数(R2)
r2_RF_boruta = r2_score(y_test, pred_RF_boruta)

# 平均絶対誤差(MAE)
mae_RF_boruta = mean_absolute_error(y_test, pred_RF_boruta)

print("R2　:　%.3f" % r2_RF_boruta)
print("MAE : %.3f" % mae_RF_boruta)

#R2　:　0.902
#MAE : 2.253
```

##さいごに
最後まで読んで頂き、ありがとうございました。
今回はBorutaを活用した特徴量選択を試してみました。
ボストン住宅価格では、特徴量が予め絞り込まれておりますので効果は無いように見えますが、実務では、説明変数が多いので活用してみようと思います。

訂正要望がありましたら、ご連絡頂けますと幸いです。