2016-10-13 3 views
5

Ich versuchte Scikit-Learn des RidgeCV Modell Vererbung zu erweitern:vererben Scikit-Learn LassoCV Modell

from sklearn.linear_model import RidgeCV, LassoCV 

class Extended(RidgeCV): 
    def __init__(self, *args, **kwargs): 
     super(Extended, self).__init__(*args, **kwargs) 

    def example(self): 
     print 'Foo' 


x = [[1,0],[2,0],[3,0],[4,0], [30, 1]] 
y = [2,4,6,8, 60] 
model = Extended(alphas = [float(a)/1000.0 for a in range(1, 10000)]) 
model.fit(x,y) 
print model.predict([[5,1]]) 

Es funktionierte perfekt in Ordnung, aber wenn ich von LassoCV zu erben versucht, es ergab folgende Zurückverfolgungs:

Traceback (most recent call last): 
    File "C:/Python27/so.py", line 14, in <module> 
    model.fit(x,y) 
    File "C:\Python27\lib\site-packages\sklearn\linear_model\coordinate_descent.py", line 1098, in fit 
    path_params = self.get_params() 
    File "C:\Python27\lib\site-packages\sklearn\base.py", line 214, in get_params 
    for key in self._get_param_names(): 
    File "C:\Python27\lib\site-packages\sklearn\base.py", line 195, in _get_param_names 
    % (cls, init_signature)) 
RuntimeError: scikit-learn estimators should always specify their parameters in the signature of their __init__ (no varargs). <class '__main__.Extended'> with constructor (<self>, *args, **kwargs) doesn't follow this convention. 

Kann jemand erklären, wie man das repariert?

Antwort

5

Sie möchten wahrscheinlich ein scikit-learn-kompatibles Modell machen, um es weiter mit verfügbarem scikit-learn funktional zu verwenden. Wenn Sie das tun - Sie müssen diese zuerst lesen: http://scikit-learn.org/stable/developers/contributing.html#rolling-your-own-estimator

Kurz: Scikit-Learn hat viele Funktionen wie Schätzer Klonen (Klon() Funktion), Meta-Algorithmen wie GridSearch, Pipeline, Kreuzvalidierung. Und all diese Dinge müssen in der Lage sein, Werte von Feldern innerhalb Ihres Schätzers zu erhalten und den Wert dieser Felder zu ändern (z. B. muss GridSearch Parameter vor jeder Auswertung in Ihrem Schätzer ändern), wie Parameter alpha in SGDClassifier. Um den Wert eines Parameters zu ändern, muss der Name des Parameters bekannt sein. Um Namen aller Felder in jeder Klassifikatormethode get_params von BaseEstimator Klasse (die Sie implizit erben) erfordert alle Parameter in __init__ Methode einer Klasse angegeben werden, weil es einfach ist, alle Parameternamen der Methode __init__ (Blick auf BaseEstimator , das ist die Klasse, die diesen Fehler auslöst).

So einfach will es Ihnen alle varargs wie

*args, **kwargs 

von __init__ Signatur entfernen. Sie müssen alle Parameter Ihres Modells in der Signatur __init__ auflisten und alle internen Felder eines Objekts initialisieren.

Hier ist Beispiel für __init__ Verfahren von SGDClassifier, die von BaseSGDClassifier vererbt wird:

def __init__(self, loss="hinge", penalty='l2', alpha=0.0001, l1_ratio=0.15, 
      fit_intercept=True, n_iter=5, shuffle=True, verbose=0, 
      epsilon=DEFAULT_EPSILON, n_jobs=1, random_state=None, 
      learning_rate="optimal", eta0=0.0, power_t=0.5, 
      class_weight=None, warm_start=False, average=False): 
    super(SGDClassifier, self).__init__(
     loss=loss, penalty=penalty, alpha=alpha, l1_ratio=l1_ratio, 
     fit_intercept=fit_intercept, n_iter=n_iter, shuffle=shuffle, 
     verbose=verbose, epsilon=epsilon, n_jobs=n_jobs, 
     random_state=random_state, learning_rate=learning_rate, eta0=eta0, 
     power_t=power_t, class_weight=class_weight, warm_start=warm_start, average=average) 
+1

Ich war hopimg, dass es eine elegantere Lösung, aber anscheinend ist dies die einfachste. Vielen Dank! –