2016-04-26 6 views
0

.coef_属性値を使用してscikit-learn 0.17.1で機能を選択するには、Pythonクラスを作成しようとしています。私は、第10パーセンタイル以上の値の.coef_のフィーチャを選択したいだけです(10,11,12,13,14,15,16, ...、94,95,96,97,98,99,100番目)。scikit-learn機能の選択.coef_値のパーセンタイルに基づいて

SelectFromModels()でこれを行うことができませんでしたので、この機能の選択にはChooseCoefPercentile()という名前のカスタムクラスを作成しようとしました。私は.coef_のパーセンタイルに応じて機能を選択するには、次の機能を使用しようとしています:

from sklearn.datasets import load_iris 
from sklearn.cross_validation import train_test_split 
X_train, X_test, y_train, y_test = train_test_split(load_iris().data, 
            load_iris().target, test_size=0.33, random_state=42) 

def percentile_sep(coefs,p): 
    from numpy import percentile as pc 
    gt_p = coefs[coefs>pc(coefs,p)].argsort() 
    return list(gt_p) 

from sklearn.base import BaseEstimator, TransformerMixin 
class ChooseCoefPercentile(BaseEstimator, TransformerMixin): 
    def __init__(self, est_, perc=50): 
     self.perc = perc 
     self.est_ = est_ 
    def fit(self, *args, **kwargs): 
     self.est_.fit(*args, **kwargs) 
     return self 
    def transform(self, X): 
     perc_i = percentile_sep(self.est_.coef_,self.perc) 
     i_ = self.est_.coef_.argsort()[::-1][perc_i[:]] 
     X_tr = X[:,i_] 
     self.coef_ = self.est_.coef_[i_] 
     return X_tr 

# Import modules 
from sklearn import svm,ensemble,pipeline,grid_search 

# Instantiate feature selection estimator and classifier 
f_sel = ChooseCoefPercentile(svm.SVC(kernel='linear'),perc=10) 
clf = ensemble.RandomForestClassifier(random_state=42,oob_score=False) 

CustPipe = pipeline.Pipeline([("feat_s",f_sel),("Clf",clf)]) 
bf_est = grid_search.GridSearchCV(CustPipe,cv=2,param_grid={'Clf__n_estimators':[100,200]}) 
bf_est.fit(X_train, y_train) 

私は次のようなエラーになっています:

Traceback (most recent call last): 
    File "C:\Python27\test.py", line 35, in <module> 
    bf_est.fit(X_train, y_train) 
    File "C:\Python27\lib\site-packages\sklearn\grid_search.py", line 804, in fit 
    return self._fit(X, y, ParameterGrid(self.param_grid)) 
    File "C:\Python27\lib\site-packages\sklearn\grid_search.py", line 553, in _fit 
    for parameters in parameter_iterable 
    File "C:\Python27\lib\site-packages\sklearn\externals\joblib\parallel.py", line 800, in __call__ 
    while self.dispatch_one_batch(iterator): 
    File "C:\Python27\lib\site-packages\sklearn\externals\joblib\parallel.py", line 658, in dispatch_one_batch 
    self._dispatch(tasks) 
    File "C:\Python27\lib\site-packages\sklearn\externals\joblib\parallel.py", line 566, in _dispatch 
    job = ImmediateComputeBatch(batch) 
    File "C:\Python27\lib\site-packages\sklearn\externals\joblib\parallel.py", line 180, in __init__ 
    self.results = batch() 
    File "C:\Python27\lib\site-packages\sklearn\externals\joblib\parallel.py", line 72, in __call__ 
    return [func(*args, **kwargs) for func, args, kwargs in self.items] 
    File "C:\Python27\lib\site-packages\sklearn\cross_validation.py", line 1531, in _fit_and_score 
    estimator.fit(X_train, y_train, **fit_params) 
    File "C:\Python27\lib\site-packages\sklearn\pipeline.py", line 164, in fit 
    Xt, fit_params = self._pre_transform(X, y, **fit_params) 
    File "C:\Python27\lib\site-packages\sklearn\pipeline.py", line 145, in _pre_transform 
    Xt = transform.fit_transform(Xt, y, **fit_params_steps[name]) 
    File "C:\Python27\lib\site-packages\sklearn\base.py", line 458, in fit_transform 
    return self.fit(X, y, **fit_params).transform(X) 
    File "C:\Python27\test.py", line 21, in transform 
    i_ = self.est_.coef_.argsort()[::-1][perc_i[:]] 
IndexError: index 6 is out of bounds for axis 0 with size 3 

をそれのnumpyの配列に問題があるようです次の行で.coef_値:この行で

i_ = self.est_.coef_.argsort()[::-1][perc_i[:]]

、私だけを選択しようとしていますそれらのインデックスに基づいて10番目のパーセンタイルを超える値を返します。インデックスはリストperc_iに格納されています。このリストを使用して.coef_配列を正しく索引付けすることはできません。

アレイを行に分割する必要があるため、このエラーが発生しますか?または、パーセンタイルに基づいて.coef_値を抽出するために他の方法を使用する必要がありますか?

+1

問題が.coef_アレイは、各クラスの行に分割されることが確かです。選択メカニズムをより正確にする必要があります。あるクラスのパーセンタイルを上回るフィーチャが存在し、それ以外のフィーチャが存在しない場合はどうなりますか? –

+0

それは良い質問です。私はOPでそれを言及すべきだった - 実際には、その場合、私は機能を選択したいと思います。この場合、機能を選択する方法はありますか?また、 'SelectPercentile()'がこれらのケースをどのように処理するのか知っていますか? http://scikit-learn.org/stable/modules/generated/sklearn.feature_selection.SelectPercentile.html –

+0

FWIWでは、この機能はhttps://github.com/scikit-learn/scikit-projectsで提案されている機能に非常に近いです。 learn/pull/6717ですので、scikit-learnがすぐに 'SelectFromModel'でこれをサポートしてくれることをうれしく思います。 – joeln

答えて

1

Iはsuggestto行の数に基づいてモジュラ演算を使用して係数行列のための関連する列を計算するであろう:

def transform(self, X): 
    perc_i = percentile_sep(self.est_.coef_,self.perc) 
    nclass=self.est_.coef_.shape[0] 
    i_ = list(set(map(lambda x:x%nclass,perc_i))) 
    X_tr = X[:,i_] 
    self.coef_ = self.est_.coef_[i_] 
    return X_tr 
+0

ありがとうございます。私はそれを試して、 '.fit()'の部分はうまくいきました。変換のために、私は 'new_features = bf_est.best_estimator_.named_steps ['feat_s']。transform([list(X_train)])'を使用しましたが、次のエラーメッセージが表示されます: 'Traceback(最新の呼び出し最後):File" C :\ Python27 \ test.py "、 new_features = bf_est.best_estimator_.named_steps ['feat_s']。変形([リスト(X_train)] ファイル" C:\ Python27 \ test.py "行23、変換中 X_tr = X [:、i_] TypeError:リストインデックスは、タプルではなく整数でなければならない。私はリスト '[list(X_train)]'を与えました。これがタプルだと思う理由はありますか? –

+1

タプルの問題の原因は正確にはわかりません。しかし、私はちょうど 'bf_est.best_estimator_.named_steps ['feat_s']。transform(X_train)'を試してみたところ、エラーは出ませんでした。 –

+0

混乱して申し訳ありません。私は間違いを犯した。あなたは正しい - これは期待どおりに動作します。ありがとう。 –

関連する問題