【问题标题】:Stacking classifier: Using custom classifier returns error堆叠分类器:使用自定义分类器返回错误
【发布时间】:2020-10-25 20:38:47
【问题描述】:

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

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

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_'

真正让我感到困惑的是,在this 的回答中,身份转换可以用作管道的一部分,我无法想象该对象也有“classes_”。

【问题讨论】:

  • 在没有客户分类器 clf 的情况下取消代码中的工作分类器之一,例如 knn。打印出适合后分配的clf.classes_。现在在您的自定义分类器中添加属性self.classes_ = ...。或者你可能需要继承一个可以做到这一点的类。

标签: python oop machine-learning scikit-learn ensemble-learning


【解决方案1】:

您的代码有 3 个问题:

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

  2. 你的类定义中缺少BaseEstimator(你可以不用它,但它的存在让生活更轻松)

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

【讨论】:

  • 谢谢。可能是个愚蠢的问题,但为什么拥有 BaseEstimator 会让我的生活更轻松?
  • 尝试不使用它,看看你必须定义自己的方法
猜你喜欢
  • 2021-12-19
  • 1970-01-01
  • 2017-12-16
  • 2017-06-30
  • 2020-08-28
  • 2023-03-17
  • 2014-02-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多