Grid-Search mit Recursive Feature Elimination in scikit-learn-pipeline gibt einen Fehler zurück
Ich versuche, Kette Grid Search and Recursive Feature Elimination in einer Pipeline mit scikit-learn.
GridSearchCV und RFE mit der "nackten" Klassifikator gut funktioniert:
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)
Setzen Klassifizierer in einer pipeline einen Fehler zurück: Absturz mit Laufzeitfehler: Der Klassifikator nicht aussetzen "coef_" oder "feature_importances_" Attribute
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)
EDIT:
Habe ich gemerkt, dass mir nicht klar war, die das problem beschreiben. Dies ist die klarere snippet:
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)
Wie Sie sehen können, der einzige Unterschied ist, dass wir die Schätzer in einer pipeline. Pipeline, verbirgt jedoch "coef_" oder "feature_importances_" Attribute. Die Fragen sind:
- Ist es eine schöne Art des Umgangs mit dieser in scikit-learn?
- Wenn nicht, ist dieses Verhalten gewünscht, aus irgendeinem Grund?
EDIT2:
Aktualisiert, Arbeits-snippet auf der Grundlage der Antwort von @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_)
- Ich würde untersuchen den Quellcode, um zu prüfen, welche Kette von Ereignissen führt zum Absturz mit Laufzeitfehler. Es ist durchaus möglich, dass Sie möglicherweise in der Lage, überschreiben Sie die Eigenschaften des entsprechenden Rendite-Objekt, und fügen Sie einfach zurück in den Variablen - zum Beispiel, wenn Sie identisch sind, wenn zurückgegeben, die von der SVR(). In jedem Fall, make_pipeline() kann nicht wieder die gleiche Art von Objekt als SVR() tut.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Haben Sie ein Problem mit Ihrer Nutzung der pipeline.
Einer pipeline funktioniert wie folgt:
erste Objekt wird auf Daten angewendet, wenn Sie anrufen .fit(x,y) usw. Wenn diese Methode stellt eine .transform () - Methode angewendet wird und diese Ausgabe dient als Eingabe für die nächste Stufe.
Einer pipeline können einen beliebigen gültigen Modell als eine endgültige Objekt, aber alle vorherigen MÜSSEN aussetzen .transform () - Methode.
Nur wie ein Rohr - Sie füttern in Daten und jedes Objekt in der pipeline nimmt der vorherigen Ausgabe und eine weitere Transformation auf es.
Wie wir sehen können,
http://scikit-learn.org/stable/modules/generated/sklearn.feature_selection.RFE.html#sklearn.feature_selection.RFE.fit_transform
RFE macht eine transform-Methode, und sollte daher aufgenommen werden in die pipeline selbst.
E. g.
Dein Versuch hat ein paar Probleme.
Erstens, Sie versuchen zu skalieren, eine Scheibe Ihre Daten. Vorstellen, ich hatte zwei Partitionen, [1,1], [10,10]. Wenn ich normalisieren, indem der Mittelwert der partition, die ich nicht verlieren die Informationen, dass meine zweite partition ist deutlich über dem Mittelwert. Sie sollten die Skala an den start, nicht in der Mitte.
Zweitens, SVR nicht implementieren Sie ein transform-Methode, können Sie nicht integrieren, es als eine nicht abschließende element in einer pipeline.
RFE nimmt ein Modell, das es passt, um die Daten und wertet dann das Gewicht der jeweiligen Funktion.
EDIT:
Können Sie dieses Verhalten, wenn Sie es wünschen, durch die Verpackung des sklearn-pipeline in Ihre eigene Klasse. Was wir wollen, zu tun ist, wenn wir die Daten passen, um die zuletzt Schätzer .coef_ Methode und speichern Sie Sie lokal in unserer abgeleiteten Klasse unter dem richtigen Namen.
Ich schlage vor, Sie schauen in den sourcecode auf github, da dies nur ein Erster start und mehr Fehler überprüfen usw. würde wahrscheinlich erforderlich sein. Sklearn verwendet eine function decorator genannt
@if_delegate_has_method
das wäre eine praktische Sache, um hinzuzufügen, um sicherzustellen, die Methode vergröbert. Ich habe diesen code ausführen, um sicherzustellen, dass es läuft, aber nichts mehr.wenn etwas nicht klar ist, bitte Fragen.
Ich glaube, Sie hatte einen etwas anderen Weg für den Bau der pipeline als das, was aufgelistet wurde in den Dokumentation.
Sind Sie auf der Suche nach diesem?
Sehen das auch nützlich Beispiel für die Kombination von Dinge, die in einer pipeline. Für die
RFE
Objekt, ich habe gerade verwendet die offizielle Dokumentation für den Bau es mit Ihrem SVR estimator - ich habe dann einfach denRFE
Objekt in der pipeline in der gleichen Weise, wie Sie getan hatte, mit dem scaler und estimator-Objekte.RFE(SVR())
mit default-WertC
. 2. Dann, die ausgewählten Funktionen skaliert werden. 3.SVR()
ist ausgestattet mit einem parameter vonparam_grid
. Mein Arbeitsablauf ist folgender: 1. Während der GridSearchCV Funktionen skaliert werden. 2.SVR()
ist ausgestattet mit einem parameter vonparam_grid
. 3. Dann werden die Merkmale mit den kleinsten gewichten geschnitten werden aus dem Modell. 4. Die Schritte 1-3 werden wiederholt, bis die gewünschte Anzahl von features, um wählen erreicht ist.