2017-11-02 19 views
0

LabelBinarizerからカスタマイズされたエンコーダクラスを作成しました。ここに見えるのは"最大再帰深度超過"エラーを伴うLabelBinarizerの継承エラー

class my_lb(LabelBinarizer): 

    def fit(self, X, y=None): 
    self.fit(X) 

    def transform(self, X, y=None): 
    return self.transform(X) 

    def fit_transform(self, X, y=None): 
    return self.fit(X).transform(X) 

そして、フィット方法で発生した「最大再帰深度超過」エラーがあります。私はオンラインでいくつかのノートの後にそれを正しく行うことができました:

class my_lb(LabelBinarizer): 

    def __init__(self): 
    super().__init__() 

    def fit(self, X, y=None): 
    super().fit(X) 

    def transform(self, X, y=None): 
    return super().transform(X) 

    def fit_transform(self, X, y=None): 
    return super().fit(X).transform(X) 

しかし、私の質問は、どのように私の問題を解決するのですか?私はここに他の記事(私は明白な無限ループを構築していることがわかります)の原因を理解することができますが、私はLabelBinarizerのコードを読んで、それはかなり普通に見えます。私は無限ループを引き起こす可能性のあるものは見つけられません。

def fit(self, y): 
     self.y_type_ = type_of_target(y) 
     if 'multioutput' in self.y_type_: 
      raise ValueError("Multioutput target data is not supported with " 
           "label binarization") 
     if _num_samples(y) == 0: 
      raise ValueError('y has 0 samples: %r' % y) 
     self.sparse_input_ = sp.issparse(y) 
     self.classes_ = unique_labels(y) 
     return self 

私はここで何が欠けているのですか?また、継承クラスを作成するときにスーパーが必要なときに、私がよりよく知るのに役立ちます。

+0

クラスを継承していて、そのメソッドの1つを変更しない場合は、そのクラスでオーバーライドしないでください。メソッドのバージョンを削除すると、親クラスのバージョンが自動的に呼び出されます。 'super'を呼び出すバージョンは、実際には正しいとは思われません。あなたは、親クラスのメソッドに渡すのではなく、単に' y'パラメータを破棄しています。 –

+0

2番目のチャンクは、パイプラインクラスで共通の問題を解決するためのもので、エンコーダは実際にはパイプラインメソッドではうまく動作しませんでした。それで、私の呼び出しメソッドが、対応する親関数を呼び出す以外の何もしないことがわかります。ここのyパラメータは、パイプライン内の他の関数と一貫性を持たせるためのプレースホルダです。 – fnosdy

答えて

0

super()を呼び出す前に、表示されているいずれかのメソッドを呼び出すと、無限再帰が発生していました。 fittransformは明らかですが、呼び出されたことがあっても返されることはなく、再帰の最大深度を超えることになります。

fit_transformは、self.fit(X).transform(X)を呼び出していました。だから最初にしたのはself.fit(X)です。エラーが発生するまで繰り返し呼び出されました。

修正されたバージョンはfittransformという親クラスのバージョンに、super()を呼び出してコールを渡します。したがって、呼び出されません。実際、これらの呼び出しがあると、super()fit_transformから呼び出す必要はありません。

しかし、最良の修正が単に派生クラスでfittransformの定義を削除し、必要ありませんfit_transformからsuper()への呼び出しを、削除することです。

+0

ああ、本質的に、私の例ではスーパーは、自分自身が要求を親関数に渡し、親オブジェクトに割り当てられたものを自分自身として収集するということです。私はこの権利を考えていますか? – fnosdy

+0

'super()'を呼び出すと、スーパークラスの新しいオブジェクトが常にインスタンス化されますか? –

+0

@fnosdyはい、 'super()'は、あなたのオーバーライドをバイパスして直接親クラスのメソッドにアクセスすることができます。 –

関連する問題