2017-06-06 3 views
0

Ich schreibe eine Klasse namens XGB, die von XGBClassifier (aus der Python-Bibliothek xgboost.sklearn) erbt. Ich schrieb eine init Funktion und einen Sitz ein, hier gezeigt:Python-Vererbung: neue Klasse wird nicht korrekt initialisiert

from xgboost.sklearn import XGBClassifier 
from balanceSmote import BalanceSmote 
from balance import Balance 


class XGB(XGBClassifier): 

def __init__(self,learning_rate=0.5, max_depth=3,colsample_bytree=0.5,n_estimators=300, 
      frac=None,k_neighbors=None,m_neighbors=None,out_step=None): 

    # These are the additional arguments that are not in XGBClassifier 
    if k_neighbors: 
     self.balancingStrategy = 'smote' 
     self.k_neighbors = k_neighbors 
     self.m_neighbors = m_neighbors 
     self.out_step = out_step 
    elif frac : 
     self.balancingStrategy = 'normal' 
     self.frac = frac 
    else: 
     self.balancingStrategy = 'false' 

    # Utilize the motherClass 
    super(XGB,self).__init__(seed=500, 
         learning_rate = learning_rate, 
         max_depth = max_depth, 
         colsample_bytree = colsample_bytree, 
         n_estimators = n_estimators) 

Hier ist mein Testcode:

xgb4 = XGB(learning_rate = 0.1, max_depth = 3, colsample_bytree = 1, n_estimators = 1000) 

xgb4.fit(trainData,trainLabel) 

Die Initialisierung gut zu gehen scheint, aber wenn ich versuche, fit zu verwenden ((), das ein Verfahren von XGBClassifier geerbt), habe ich eine Fehlermeldung, mir zu sagen, ein Parameter fehlt:

File "<ipython-input-3-47344b7fbc76>", line 1, in <module> 
runfile('/Users/celsloaner/Project/SPUDS/code/testSpark.py', wdir='/Users/celsloaner/Project/SPUDS/code') 

File "/anaconda/envs/SPUDS/lib/python3.5/site-packages/spyder/utils/site/sitecustomize.py", line 880, in runfile 
execfile(filename, namespace) 

File "/anaconda/envs/SPUDS/lib/python3.5/site-packages/spyder/utils/site/sitecustomize.py", line 102, in execfile 
exec(compile(f.read(), filename, 'exec'), namespace) 

File "/Users/celsloaner/Project/SPUDS/code/testSpark.py", line 50, in <module> 
xgb4.fit(predictor.trainData,predictor.trainLabel) 

File "/anaconda/envs/SPUDS/lib/python3.5/site-packages/xgboost/sklearn.py", line 396, in fit 
xgb_options = self.get_xgb_params() 

File "/anaconda/envs/SPUDS/lib/python3.5/site-packages/xgboost/sklearn.py", line 177, in get_xgb_params 
xgb_params = self.get_params() 

File "/anaconda/envs/SPUDS/lib/python3.5/site-packages/xgboost/sklearn.py", line 169, in get_params 
if params['missing'] is np.nan: 

KeyError: 'missing' 

Das Problem kommt aus dem Inneren der Mutter-Klasse, die hätten richtig initialisiert werden sollen. Hier ist die Mutter Klasse problematische Funktion:

def get_params(self, deep=False): 
    """Get parameter.s""" 
    params = super(XGBModel, self).get_params(deep=deep) 
    if params['missing'] is np.nan: 
     params['missing'] = None # sklearn doesn't handle nan. see #4725 
    if not params.get('eval_metric', True): 
     del params['eval_metric'] # don't give as None param to Booster 
    return params 

Die Wörterbuch params ist offenbar nicht richtig definiert (die Taste ‚fehlenden‘ existiert nicht), wenn XGBClassifier Initialisierung in XGB Initialisierung aufgerufen wird. Haben Sie eine Idee, was das Problem ist oder wie Sie es verfolgen?

Dank

+0

Wenn es keinen Eintrag in den dict 'params' wie' 'missing'' gibt, erhalten Sie' KeyError', indem Sie versuchen, darauf zuzugreifen. Ändern Sie die Bedingung: 'if params ['missing'] ist np.nan:' to: 'wenn params.get ('missing', np.nan) ist np.nan:' wie für 'eval_metric' – alfasin

+0

Problem ist mit 'params = super (XGBModel, self) .get_params (deep = deep)', was ein 'dict' zurückgibt, das nicht das hat, was Sie wollen. –

+0

Das habe ich verstanden, aber warum? Dieses Wörterbuch wird innerhalb der Mutterklasse erstellt und verwaltet, ich habe es nicht berührt, daher verstehe ich nicht, warum es nicht gut von der Mutterklasse definiert ist, wenn ich es in einer geerbten Klasse verwende. – Salamandre

Antwort

0

Nun, es funktionierte, als ich alle der Mutter Klassenparameter initialisiert, auch wenn der Konstruktor Mutter Klasse soll für sie die Standardwerte haben:

class XGB(XGBClassifier): 

    def __init__(self,max_depth=3, learning_rate=0.1, 
       n_estimators=100, silent=True, 
       objective="binary:logistic", 
       nthread=-1, gamma=0, min_child_weight=1, 
       max_delta_step=0, subsample=1, colsample_bytree=1, colsample_bylevel=1, 
       reg_alpha=0, reg_lambda=1, scale_pos_weight=1, 
       base_score=0.5, seed=0, missing=None, 
       frac=None,k_neighbors=None,m_neighbors=None,out_step=None): 

     if k_neighbors: 
      self.balancingStrategy = 'smote' 
      self.k_neighbors = k_neighbors 
      self.m_neighbors = m_neighbors 
      self.out_step = out_step 
     elif frac : 
      self.balancingStrategy = 'normal' 
      self.frac = frac 
     else: 
      self.balancingStrategy = 'false' 


     super(XGB,self).__init__(max_depth, learning_rate, 
           n_estimators, silent, objective, 
           nthread, gamma, min_child_weight, 
           max_delta_step, subsample, 
           colsample_bytree, colsample_bylevel, 
           reg_alpha, reg_lambda, 
           scale_pos_weight, base_score, seed, missing) 

nicht sicher, ob ich verstehen, die Logik hier, aber es ist immer gut zu wissen :)

Verwandte Themen