堆叠分类器:使用自定义分类器 returns 错误

Stacking classifier: Using custom classifier returns error

我在 sklearn 中使用 StackingClassifier,我希望组件模型是自定义 classifier。为了做到这一点,我想用一些虚拟代码来测试它,其中自定义 classifier 与现有模型(在本例中为 KNN)完全相同。但是,这会引发错误,我不确定我是否理解原因,并正在寻求帮助。这可能是相当明显的(我是尝试编写自定义 class 化器和使用 ClassiferMixIn 的新手),但我似乎无法弄清楚我遗漏了什么:

代码 -- 没有我的自定义的基线示例 class(有效):

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(不起作用):

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)

returns错误

AttributeError: 'MyOwnClassifier' object has no attribute 'classes_'

真正让我困惑的是,在 答案中,身份转换可以用作管道的一部分,我无法想象那个对象有 'classes_' 要么。

您的代码有 3 个问题:

  1. StackingClassifier 期望属性 classes_ 在合适的 classifier 上可用,这在错误消息中有明确说明。链接的示例确实有它,而你的没有。如果你运行喜欢dir(MyOwnClassifier(KNeighborsClassifier()).fit(X,y)).

    可以检查
  2. BaseEstimator 在您的 class 定义中缺失(您可以没有它,但它的存在让生活更轻松)

  3. Pipelines 在你的代码中是多余的混乱,调试你的代码不是必需的,只会使调试复杂化。

一旦你纠正了这些问题,你就有了一个工作代码:

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()))])