今回は前回の「scikit-learn準拠モデルを作成する」に引き続き,特徴量削減器を作ってみます.
準拠モデルに関してはGridserchCV
やcross_validation
など便利なツールが使えるというメリットがありましたが,こちらは正直そういったメリットはありません.
ただただ,他のSelectorと同じ感覚で使えるようになるという感じです.
また,その分前回やったやつより制約条件が厳しくないので簡単に作れると思うのでぜひご参考に.
はじめに¶
正直参考資料がなく,公式ドキュメントとエラーコードをみながら作成しました.そのため,なにか足りないものがあったりするかもしれません.その場合は優しくコメントなどで教えていただけますと幸いです.
やり方¶
準拠モデルを作る流れとかなり似ています.準拠モデルを作るときはsklearn.base.BaseEstimator
と,回帰ならsklearn.base.RegressorMixin
を継承して,fit
,predict
メソッドを定義してあげることで作成できました.
(それらにはかなり詳細な条件がありましたが,それらは割愛しています.)
準拠特徴量選択器はsklearn.base.BaseEstimator
と,sklearn.feature_selection.SelectorMixin
を継承して,fit
,_get_support_mask
メソッドを定義してあげることで作成できます.
sklearn.feature_selection.SelectorMixin
は0.23.2以降で使用できます.
正確には0.23.2では使用でき,0.22.2では使用できないため,安定版では0.23.2以降を使用しなければならないという意味です.
こういった類はsklearn.base
にあることが多いのにsklearn.feature_selection
にあるのが少し紛らわしいですね.
公式ドキュメント↓
今回は全部の値が同じものを削除するfeature_selectorを自作します.正直公式でVarianceThreshold
というものが用意されており,これを使えば同じことができるのですが,デモということでこれを作っていきます.
VarianceThreshold
の公式ドキュメント↓
モジュールのインポート¶
from sklearn.feature_selection import SelectorMixin
from sklearn.base import BaseEstimator
from sklearn.utils import check_array
from sklearn.utils.validation import check_is_fitted
import numpy as np
import pandas as pd
サンプルデータの作成¶
あえてfeature0とfeature4を全く同じものにしています.これを検出することができれば完成となります.
n_features = 5
n_samples = 10
np.random.seed(334)
X_sample = np.random.rand(n_samples, n_features-1)
X_sample = pd.DataFrame(np.hstack([X_sample, X_sample[:, 0].reshape(-1, 1)]), columns = ['feature{}'.format(i) for i in range(n_features)])
X_sample.head()
feature0 | feature1 | feature2 | feature3 | feature4 | |
---|---|---|---|---|---|
0 | 0.238137 | 0.032485 | 0.124268 | 0.170548 | 0.238137 |
1 | 0.290201 | 0.823047 | 0.799337 | 0.106531 | 0.290201 |
2 | 0.839951 | 0.596350 | 0.822898 | 0.609054 | 0.839951 |
3 | 0.761943 | 0.004310 | 0.522597 | 0.077540 | 0.761943 |
4 | 0.526384 | 0.730158 | 0.608606 | 0.526219 | 0.526384 |
selectorの定義¶
class DemoSelector(BaseEstimator, SelectorMixin):
# なくても良い.モデルのパラメータを何か事前に決定したいときに引数を受け付ける.
def __init__(self):
pass
def fit(self, X):
# 入ってきたXが妥当か判別
X = check_array(X)
n_features = X.shape[1]
# np.ndarrayに変換
X = np.array(X)
# uniqueな特徴量のindexを得る.
X_selected_, self.i_selected_ = np.unique(X, return_index = True)
# 慣例
return self
def _get_support_mask(self):
# fitしないと生成しないインスタンス変数名を渡してあげることでfitしたかどうかの判定をしてくれる.
check_is_fitted(self, 'i_selected_')
return np.array([n in set(self.i_selected_) for n in range(n_features)])
作成したselectorの使い方¶
よくあるscikit-learnのやつと同様の方法で使うことができます.
たとえばtransform
, fit_transform
, get_support
など.
使い方を間違えなくてすみそうですね.
具体的には
selector = DemoSelector()
selector.fit(X_sample)
selector.get_support()
array([ True, True, True, True, False])
きちんと4つ目が重複しているよと教えてくれています. これをきちんと反映させるためには
X_sample_selected = selector.transform(X_sample)
X_sample_selected
array([[0.23813657, 0.03248529, 0.1242676 , 0.17054811],
[0.29020083, 0.8230467 , 0.79933736, 0.10653089],
[0.83995102, 0.59634954, 0.82289845, 0.6090536 ],
[0.761943 , 0.00430986, 0.52259655, 0.07754032],
[0.52638392, 0.73015785, 0.60860575, 0.52621901],
[0.95810948, 0.31299043, 0.56670188, 0.03181133],
[0.53230587, 0.07213189, 0.29677673, 0.64166072],
[0.21747158, 0.47006189, 0.92899115, 0.47937367],
[0.95307794, 0.43918351, 0.7654608 , 0.08430146],
[0.2072126 , 0.28007235, 0.14935997, 0.93878843]])
としてあげればいいですね.
ちなみに¶
ちなみにinverse_transform
も同時に実装されるのですが,これは削除されたものを0埋めして復元してくれるみたいです.挙動として興味があったので試してみました.使い道があるかどうかはわかりません.
selector.inverse_transform(X_sample_selected)
array([[0.23813657, 0.03248529, 0.1242676 , 0.17054811, 0. ],
[0.29020083, 0.8230467 , 0.79933736, 0.10653089, 0. ],
[0.83995102, 0.59634954, 0.82289845, 0.6090536 , 0. ],
[0.761943 , 0.00430986, 0.52259655, 0.07754032, 0. ],
[0.52638392, 0.73015785, 0.60860575, 0.52621901, 0. ],
[0.95810948, 0.31299043, 0.56670188, 0.03181133, 0. ],
[0.53230587, 0.07213189, 0.29677673, 0.64166072, 0. ],
[0.21747158, 0.47006189, 0.92899115, 0.47937367, 0. ],
[0.95307794, 0.43918351, 0.7654608 , 0.08430146, 0. ],
[0.2072126 , 0.28007235, 0.14935997, 0.93878843, 0. ]])
まとめ¶
- scikit-learn 0.23.2以降で使用可能
- sklearn.feature_selection.SelectorMixinとsklearn.base.BaseEstimatorを継承
- fit, _get_support_maskを定義
0 件のコメント:
コメントを投稿