scikitlearn-RandomForestClassifier をメンバー変数として保持するクラスがあります。
__init__ メソッドでは、最初に None に初期化されます。
def __init__(self):
self.classifier = None
そして
その後、必要なパラメータがすべて利用可能になると、RandomForestClassifier が作成され、
このメンバー変数に割り当てられます:
def init_classifier(self):
self.classifier = RandomForestClassifier(**params)
(デバッガーでは、self.classifier が意味のあるものに初期化されていることがわかります。)
分類子をデータに適合させることになっているクラス メソッドでは、最初に次のことがチェックされます。
分類子はすでに初期化されています:
if not self.classifier:
self.init_classifier()
これにより、AttributeError が発生します。「RandomForestClassifier」オブジェクトには属性「estimators_」がありません。
None と明示的に比較することによってチェックが行われる場合、
if self.classifier is None:
self.init_classifier()
それは通り抜けます。誰かこれがどこにあるのか説明してもらえますかAttributeError の原因は?
------------------------
この動作の理由を理解するには、Python でオブジェクトのブール比較がどのように機能するかを調べる必要があります。 (つまり、if A を呼び出すとき)。
まず、インタプリタはオブジェクトが特別なメソッド __bool__ を実装しているかどうかを確認しようとします。これは、True または False を返す特別なメソッドです。
__bool__ 特殊メソッドが定義されていない場合、インタープリターは __len__ 関数の使用を試みます。結果が 0 の場合、式は False と評価されます。ここで例外が発生します。
__len__ 関数も定義されていない場合、ステートムent は True と評価されます。
RandomForestClassifier の継承元である BaseEnsemble クラスを見ると、__bool__ 特殊メソッドは実装されていませんが、__len__ 特殊メソッドは実装されていることがわかります。
def __len__(self):
"""Return the number of estimators in the ensemble."""
return len(self.estimators_)
つまり、if not self.classifier: を呼び出しているときは、その __len__ 関数を呼び出していることになります。コードの現時点では、RandomForestClassifier はまだ適切にインスタンス化されておらず (これは私の推測です)、estimators_ 属性がないため、例外が発生します。
オブジェクトがインスタンス化されていないことを確認したい場合は、常に明示的に None との比較を呼び出します。その場合、インタプリタはオブジェクトを None と照合してチェックします。