#python #scikit-learn
#python #scikit-learn
Вопрос:
У меня есть класс, который содержит 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' object has no attribute 'estimators_'.
Если проверка выполняется путем сравнения с None явно,
if self.classifier is None:
self.init_classifier()
он выполняется. Может кто-нибудь объяснить мне, откуда берется эта ошибка атрибута?
Ответ №1:
Чтобы понять, почему такое поведение, вам нужно посмотреть, как работает логическое сравнение объекта в Python. (т. Е. при вызове if A
).
-
Сначала интерпретатор попытается проверить, реализует ли объект специальный метод
__bool__
. Это специальный метод, который либо вернетTrue
, либоFalse
. -
Если
__bool__
специальный метод не определен, интерпретатор попытается использовать__len__
функцию. Если результат равен 0, то выражение вычисляется вFalse
. Отсюда и возникает исключение. -
Если
__len__
функция также не определена, то оператор оценивается какTrue
.
Если мы посмотрим на BaseEnsemble
класс, от которого наследуется RandomForestClassifier
, мы увидим, что он не реализует __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
.