Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 堆叠分类器:使用自定义分类器返回错误_Python_Oop_Machine Learning_Scikit Learn_Ensemble Learning - Fatal编程技术网

Python 堆叠分类器:使用自定义分类器返回错误

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

我在sklearn中使用了StackingClassifier,我希望组件模型是定制分类器。为了做到这一点,我想用一些虚拟代码来测试它,其中自定义分类器与已经存在的模型(在本例中为KNN)完全相同。然而,这会抛出一个错误,我不确定我是否理解原因,并寻求帮助。这可能是相当明显的事情(我对尝试编写自定义分类器和使用ClassifierMixin还不熟悉),但我似乎不知道我遗漏了什么:

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

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会让我的生活更轻松呢?试着不用它,看看你定义自己的方法