2016-04-17 4 views
6

मैं विज्ञान-सीखने का उपयोग करके पाइपलाइन में ग्रिड सर्च और रिकर्सिव फीचर एलिमिनेशन श्रृंखला की कोशिश कर रहा हूं।रिकर्सिव फीचर के साथ ग्रिड सर्च विज्ञान-सीखने वाली पाइपलाइन में उन्मूलन एक त्रुटि देता है

GridSearchCV और "नंगे" वर्गीकारक साथ RFE ठीक काम करता है:

from sklearn.datasets import make_friedman1 
from sklearn import feature_selection 
from sklearn.grid_search import GridSearchCV 
from sklearn.svm import SVR 

X, y = make_friedman1(n_samples=50, n_features=10, random_state=0) 

est = SVR(kernel="linear") 

selector = feature_selection.RFE(est) 
param_grid = dict(estimator__C=[0.1, 1, 10]) 
clf = GridSearchCV(selector, param_grid=param_grid, cv=10) 
clf.fit(X, y) 

एक पाइप लाइन में वर्गीकारक लाना एक त्रुटि देता है: RuntimeError: वर्गीकारक "coef_" या "feature_importances_" का खुलासा नहीं करता विशेषताओं

from sklearn.datasets import make_friedman1 
from sklearn import feature_selection 
from sklearn import preprocessing 
from sklearn import pipeline 
from sklearn.grid_search import GridSearchCV 
from sklearn.svm import SVR 

X, y = make_friedman1(n_samples=50, n_features=10, random_state=0) 

est = SVR(kernel="linear") 

std_scaler = preprocessing.StandardScaler() 
pipe_params = [('std_scaler', std_scaler), ('clf', est)] 
pipe = pipeline.Pipeline(pipe_params) 

selector = feature_selection.RFE(pipe) 
param_grid = dict(estimator__clf__C=[0.1, 1, 10]) 
clf = GridSearchCV(selector, param_grid=param_grid, cv=10) 
clf.fit(X, y) 

संपादित करें:

मैंने महसूस किया है कि मैं समस्या का वर्णन स्पष्ट नहीं था। यह स्पष्ट स्निपेट है:

from sklearn.datasets import make_friedman1 
from sklearn import feature_selection 
from sklearn import pipeline 
from sklearn.grid_search import GridSearchCV 
from sklearn.svm import SVR 

X, y = make_friedman1(n_samples=50, n_features=10, random_state=0) 

# This will work 
est = SVR(kernel="linear") 
selector = feature_selection.RFE(est) 
clf = GridSearchCV(selector, param_grid={'estimator__C': [1, 10]}) 
clf.fit(X, y) 

# This will not work 
est = pipeline.make_pipeline(SVR(kernel="linear")) 
selector = feature_selection.RFE(est) 
clf = GridSearchCV(selector, param_grid={'estimator__svr__C': [1, 10]}) 
clf.fit(X, y) 

जैसा कि आप देख सकते हैं, केवल अंतर अनुमानक को पाइपलाइन में डाल रहा है। हालांकि, पाइपलाइन "coef_" या "feature_importances_" विशेषताओं को छुपाती है। प्रश्न हैं:

  1. क्या विज्ञान-सीखने में इसका निपटारा करने का कोई अच्छा तरीका है?
  2. यदि नहीं, तो यह व्यवहार किसी भी कारण से वांछित है?

EDIT2:

अपडेट किया गया, काम टुकड़ा @Chris

from sklearn.datasets import make_friedman1 
from sklearn import feature_selection 
from sklearn import pipeline 
from sklearn.grid_search import GridSearchCV 
from sklearn.svm import SVR 


class MyPipe(pipeline.Pipeline): 

    def fit(self, X, y=None, **fit_params): 
     """Calls last elements .coef_ method. 
     Based on the sourcecode for decision_function(X). 
     Link: https://github.com/scikit-learn/scikit-learn/blob/master/sklearn/pipeline.py 
     ---------- 
     """ 
     super(MyPipe, self).fit(X, y, **fit_params) 
     self.coef_ = self.steps[-1][-1].coef_ 
     return self 


X, y = make_friedman1(n_samples=50, n_features=10, random_state=0) 

# Without Pipeline 
est = SVR(kernel="linear") 
selector = feature_selection.RFE(est) 
clf = GridSearchCV(selector, param_grid={'estimator__C': [1, 10, 100]}) 
clf.fit(X, y) 
print(clf.grid_scores_) 

# With Pipeline 
est = MyPipe([('svr', SVR(kernel="linear"))]) 
selector = feature_selection.RFE(est) 
clf = GridSearchCV(selector, param_grid={'estimator__svr__C': [1, 10, 100]}) 
clf.fit(X, y) 
print(clf.grid_scores_) 
+0

मैं स्रोत कोड का निरीक्षण करता हूं ताकि यह जांच सके कि घटनाओं की कौन सी श्रृंखला RuntimeError की ओर ले जाती है। यह काफी संभव है कि आप प्रासंगिक रिटर्न ऑब्जेक्ट के गुणों को ओवरराइड कर सकें और केवल चर में वापस जोड़ सकें - उदाहरण के लिए, यदि वे एसवीआर() से लौटे जाने पर समान हैं। किसी भी मामले में, make_pipeline() उसी प्रकार की ऑब्जेक्ट को वापस नहीं कर सकता क्योंकि एसवीआर() करता है। – noumenal

उत्तर

2

आपको पाइपलाइन के उपयोग के साथ कोई समस्या है।

एक पाइप लाइन के रूप में नीचे काम करता है:

पहली वस्तु डेटा को लागू किया जाता है कि विधि एक .transform() विधि को उजागर करता है, तो जब आप फ़िट (एक्स, वाई) आदि कहते हैं, यह लागू किया जाता है और इस उत्पादन है अगले चरण के लिए इनपुट के रूप में इस्तेमाल किया।

एक पाइपलाइन के पास अंतिम वस्तु के रूप में कोई वैध मॉडल हो सकता है, लेकिन सभी पिछले लोगों को एक .transform() विधि का खुलासा करना चाहिए।

बस एक पाइप की तरह - आप डेटा में फ़ीड करते हैं और पाइपलाइन में प्रत्येक ऑब्जेक्ट पिछले आउटपुट लेता है और दूसरा ट्रांसफॉर्म करता है।

हम देख सकते हैं,

http://scikit-learn.org/stable/modules/generated/sklearn.feature_selection.RFE.html#sklearn.feature_selection.RFE.fit_transform

RFE एक विधि को बदलने को उजागर करता है, और इसलिए पाइपलाइन में ही शामिल किया जाना चाहिए। ईजी।

some_sklearn_model=RandomForestClassifier() 
selector = feature_selection.RFE(some_sklearn_model) 
pipe_params = [('std_scaler', std_scaler), ('RFE', rfe),('clf', est)] 

आपके प्रयास में कुछ समस्याएं हैं। सबसे पहले, आप अपने डेटा का एक टुकड़ा स्केल करने की कोशिश कर रहे हैं। कल्पना कीजिए कि मेरे पास दो विभाजन थे [1,1], [10,10]। यदि मैं विभाजन के माध्यम से सामान्यीकृत करता हूं तो मैं जानकारी खो देता हूं कि मेरा दूसरा विभाजन माध्य से काफी महत्वपूर्ण है। आपको शुरुआत में स्केल करना चाहिए, मध्य में नहीं।

दूसरा, एसवीआर एक ट्रांसफॉर्म विधि को लागू नहीं करता है, आप इसे पाइपलाइन में एक गैर अंतिम तत्व के रूप में शामिल नहीं कर सकते हैं।

आरएफई एक मॉडल में ले जाता है जो यह डेटा के लिए उपयुक्त होता है और फिर प्रत्येक सुविधा के वजन का मूल्यांकन करता है।

संपादित करें:

यदि आप, इच्छा अपनी खुद की कक्षा में sklearn पाइपलाइन लपेटकर करके इस व्यवहार शामिल कर सकते हैं। हम क्या करना चाहते हैं जब हम डेटा फिट करते हैं, अंतिम अनुमानक .coef_ विधि पुनर्प्राप्त करें और सही रूप से हमारे व्युत्पन्न वर्ग में स्थानीय रूप से स्टोर करें। मेरा सुझाव है कि आप जीथ्यूब पर स्रोत कोड देखें क्योंकि यह केवल पहली शुरुआत है और अधिक त्रुटि जांच आदि की आवश्यकता होगी। Sklearn @if_delegate_has_method नामक फ़ंक्शन सजावट का उपयोग करता है जो विधि सामान्य सुनिश्चित करने के लिए जोड़ने के लिए एक आसान चीज़ होगी। मैंने यह कोड यह सुनिश्चित करने के लिए चलाया है कि यह रन काम करता है, लेकिन कुछ और नहीं।

from sklearn.datasets import make_friedman1 
from sklearn import feature_selection 
from sklearn import preprocessing 
from sklearn import pipeline 
from sklearn.grid_search import GridSearchCV 
from sklearn.svm import SVR 

class myPipe(pipeline.Pipeline): 

    def fit(self, X,y): 
     """Calls last elements .coef_ method. 
     Based on the sourcecode for decision_function(X). 
     Link: https://github.com/scikit-learn/scikit-learn/blob/master/sklearn/pipeline.py 
     ---------- 
     """ 

     super(myPipe, self).fit(X,y) 

     self.coef_=self.steps[-1][-1].coef_ 
     return 

X, y = make_friedman1(n_samples=50, n_features=10, random_state=0) 

est = SVR(kernel="linear") 

selector = feature_selection.RFE(est) 
std_scaler = preprocessing.StandardScaler() 
pipe_params = [('std_scaler', std_scaler),('select', selector), ('clf', est)] 

pipe = myPipe(pipe_params) 



selector = feature_selection.RFE(pipe) 
clf = GridSearchCV(selector, param_grid={'estimator__clf__C': [2, 10]}) 
clf.fit(X, y) 

print clf.best_params_ 

यदि कुछ भी स्पष्ट नहीं है, तो कृपया पूछें।

+0

धन्यवाद आपके उत्तर के लिए @Chris। मैं समस्या का वर्णन स्पष्ट नहीं था। मुझे विशेष रूप से आश्चर्य है कि एक अनुमानक के "coef_" या "feature_importances_" विशेषताओं को कैसे पहुंचाया जा सकता है जो पाइपलाइन द्वारा छिपा हुआ प्रतीत होता है। – hubi86

+0

मेरा संपादन अब इस पते को संबोधित करता है। शुभ लाभ। – Chris

0

द्वारा प्रदान की जवाब मुझे लगता है कि तुम क्या में सूचीबद्ध किया गया से पाइप लाइन के निर्माण की एक अलग तरह से किया था के आधार पर pipeline documentation

क्या आप इसे ढूंढ रहे हैं?

X, y = make_friedman1(n_samples=50, n_features=10, random_state=0) 

est = SVR(kernel="linear") 

std_scaler = preprocessing.StandardScaler() 
selector = feature_selection.RFE(est) 
pipe_params = [('feat_selection',selector),('std_scaler', std_scaler), ('clf', est)] 
pipe = pipeline.Pipeline(pipe_params) 

param_grid = dict(clf__C=[0.1, 1, 10]) 
clf = GridSearchCV(pipe, param_grid=param_grid, cv=2) 
clf.fit(X, y) 
print clf.grid_scores_ 

यह भी देखें useful example एक पाइपलाइन में चीजों को जोड़ने के लिए। RFE ऑब्जेक्ट के लिए, मैंने अपने एसवीआर अनुमानक के साथ इसे बनाने के लिए official documentation का उपयोग किया - मैं बस RFE ऑब्जेक्ट को उसी तरह पाइपलाइन में डालता हूं जैसा आपने स्केलर और अनुमानक ऑब्जेक्ट्स के साथ किया था।

+0

आपके उत्तर के लिए धन्यवाद लेकिन मेरा समाधान अलग-अलग काम करता है। आपका वर्कफ़्लो: 1. ग्रिडशर्चसीवी सुविधाओं के दौरान 'सी' के डिफ़ॉल्ट मान के साथ 'आरएफई (एसवीआर())' का उपयोग करके चुना जाता है। 2. फिर, उन चयनित सुविधाओं को स्केल किया गया है। 3. 'एसवीआर()' 'param_grid' से एक पैरामीटर के साथ लगाया गया है। मेरा वांछित वर्कफ़्लो निम्न है: 1. ग्रिडशर्चसीवी सुविधाओं के दौरान स्केल किया गया है। 2. 'एसवीआर()' 'param_grid' से एक पैरामीटर के साथ लगाया गया है। 3. फिर, सबसे छोटे वजन वाले फीचर्स मॉडल से छिड़के जाते हैं। 4. चरण 1-3 दोहराए जाते हैं जब तक कि चुनिंदा सुविधाओं की वांछित संख्या तक नहीं पहुंच जाती है। – hubi86

संबंधित मुद्दे