Python 堆叠分类器:使用自定义分类器返回错误
我在sklearn中使用了StackingClassifier,我希望组件模型是定制分类器。为了做到这一点,我想用一些虚拟代码来测试它,其中自定义分类器与已经存在的模型(在本例中为KNN)完全相同。然而,这会抛出一个错误,我不确定我是否理解原因,并寻求帮助。这可能是相当明显的事情(我对尝试编写自定义分类器和使用ClassifierMixin还不熟悉),但我似乎不知道我遗漏了什么: 代码——没有自定义类的基线示例(有效):Python 堆叠分类器:使用自定义分类器返回错误,python,oop,machine-learning,scikit-learn,ensemble-learning,Python,Oop,Machine Learning,Scikit Learn,Ensemble Learning,我在sklearn中使用了StackingClassifier,我希望组件模型是定制分类器。为了做到这一点,我想用一些虚拟代码来测试它,其中自定义分类器与已经存在的模型(在本例中为KNN)完全相同。然而,这会抛出一个错误,我不确定我是否理解原因,并寻求帮助。这可能是相当明显的事情(我对尝试编写自定义分类器和使用ClassifierMixin还不熟悉),但我似乎不知道我遗漏了什么: 代码——没有自定义类的基线示例(有效): from sklearn.ensemble import Stacking
from sklearn.ensemble import StackingClassifier
from sklearn.pipeline import Pipeline
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_breast_cancer
X, y = load_breast_cancer(return_X_y=True, as_frame=True)
model = StackingClassifier(estimators=[
('tree', Pipeline([('tree', DecisionTreeClassifier(random_state=42))])),
('knn', Pipeline([('knn', KNeighborsClassifier())])),
])
model.fit(X, y)
class MyOwnClassifier(ClassifierMixin):
def __init__(self,classifier):
self.classifier = classifier
def fit(self, X, y):
self.classifier.fit(X,y)
return self
def predict(self, X):
return self.classifier.predict(X)
def predict_proba(self, X):
return self.classifier.predict_proba(X)
model = StackingClassifier(estimators=[
('tree', Pipeline([('tree', DecisionTreeClassifier(random_state=42))])),
('knn', Pipeline([('knn', MyOwnClassifier(KNeighborsClassifier()))])),
])
model.fit(X, y)
代码——与我的自定义类一起使用(不起作用):
from sklearn.ensemble import StackingClassifier
from sklearn.pipeline import Pipeline
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_breast_cancer
X, y = load_breast_cancer(return_X_y=True, as_frame=True)
model = StackingClassifier(estimators=[
('tree', Pipeline([('tree', DecisionTreeClassifier(random_state=42))])),
('knn', Pipeline([('knn', KNeighborsClassifier())])),
])
model.fit(X, y)
class MyOwnClassifier(ClassifierMixin):
def __init__(self,classifier):
self.classifier = classifier
def fit(self, X, y):
self.classifier.fit(X,y)
return self
def predict(self, X):
return self.classifier.predict(X)
def predict_proba(self, X):
return self.classifier.predict_proba(X)
model = StackingClassifier(estimators=[
('tree', Pipeline([('tree', DecisionTreeClassifier(random_state=42))])),
('knn', Pipeline([('knn', MyOwnClassifier(KNeighborsClassifier()))])),
])
model.fit(X, y)
返回错误
AttributeError: 'MyOwnClassifier' object has no attribute 'classes_'
真正让我困惑的是,作为回答,身份转换可以用作管道的一部分,我无法想象该对象也有“类”。您的代码有3个问题:
StackingClassifier
期望在安装的分类器上有一个属性classes
,该属性在错误消息中明确说明。链接的示例确实有,而您的示例没有。如果您像dir(myownsider(kneighborsvidentifier()).fit(X,y))
那样运行,则可以检查它
BaseEstimator
在您的类定义中丢失(您可以不使用它,但它的存在使生活更轻松)
代码中的管道
是无关的杂波,调试代码时不需要这些杂波,只会使调试复杂化
from sklearn.ensemble import StackingClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.base import ClassifierMixin, BaseEstimator
X, y = load_breast_cancer(return_X_y=True, as_frame=True)
class MyOwnClassifier(ClassifierMixin, BaseEstimator):
def __init__(self,classifier):
self.classifier = classifier
def fit(self, X, y):
self.classifier.fit(X,y)
self.classes_ = self.classifier.classes_
return self
def predict(self, X):
return self.classifier.predict(X)
def predict_proba(self, X):
return self.classifier.predict_proba(X)
model = StackingClassifier(estimators=[
('tree', DecisionTreeClassifier(random_state=42)),
('knn', MyOwnClassifier(KNeighborsClassifier()))])
model.fit(X,y)
StackingClassifier(estimators=[('tree',
DecisionTreeClassifier(random_state=42)),
('knn',
MyOwnClassifier(classifier=KNeighborsClassifier()))])
您的代码有3个问题:
StackingClassifier
期望在安装的分类器上有一个属性classes
,该属性在错误消息中明确说明。链接的示例确实有,而您的示例没有。如果您像dir(myownsider(kneighborsvidentifier()).fit(X,y))
那样运行,则可以检查它
BaseEstimator
在您的类定义中丢失(您可以不使用它,但它的存在使生活更轻松)
代码中的管道
是无关的杂波,调试代码时不需要这些杂波,只会使调试复杂化
from sklearn.ensemble import StackingClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.base import ClassifierMixin, BaseEstimator
X, y = load_breast_cancer(return_X_y=True, as_frame=True)
class MyOwnClassifier(ClassifierMixin, BaseEstimator):
def __init__(self,classifier):
self.classifier = classifier
def fit(self, X, y):
self.classifier.fit(X,y)
self.classes_ = self.classifier.classes_
return self
def predict(self, X):
return self.classifier.predict(X)
def predict_proba(self, X):
return self.classifier.predict_proba(X)
model = StackingClassifier(estimators=[
('tree', DecisionTreeClassifier(random_state=42)),
('knn', MyOwnClassifier(KNeighborsClassifier()))])
model.fit(X,y)
StackingClassifier(estimators=[('tree',
DecisionTreeClassifier(random_state=42)),
('knn',
MyOwnClassifier(classifier=KNeighborsClassifier()))])
在没有客户分类器的情况下,取消保存代码中的一个工作分类器
clf
,例如knn
。打印出拟合后分配的clf.classes\uuu
。现在在自定义分类器中添加属性self.classes=…
。或者您可能需要继承一个这样做的类。在没有客户分类器的代码中取消保存一个工作分类器clf
,例如knn
。打印出拟合后分配的clf.classes\uuu
。现在在自定义分类器中添加属性self.classes=…
。或者您需要继承一个类来实现这一点。谢谢。也许是个愚蠢的问题,但为什么有BaseEstimator会让我的生活更轻松呢?试着不用它,看看你定义自己的方法谢谢。也许是个愚蠢的问题,但为什么有BaseEstimator会让我的生活更轻松呢?试着不用它,看看你定义自己的方法