检查 sklearn.base
,更具体地说 BaseEstimator
,以及不同的 mixin,很明显,一些 mixin 依赖于调用 .fit
的能力。或 .predict
.
例如,如果我们查看 RegressorMixin
我们会看到它依赖于 .predict
方法。
我的问题是为什么没有强制执行这些方法的接口(interface)/抽象类的实现?
我希望有类似 BaseRegressor
的东西有 .predict()
作为抽象方法和BaseClassifier
有.predict_proba()
和 .predict()
- 或类似的东西
最佳答案
有几件事可以让我们更清楚为什么事情是在像 scikit-learn
这样的包中完成的,它们是这样的:
duck typing vs 继承:关于哪种方法更好,你可以找到很长的争论,虽然它们各有优缺点,但归根结底,归根结底是人们在社区习惯了。作为最近经常使用 Python 的人,我喜欢 duck typing,而且我对它非常满意。与此同时,15 年前,我喜欢抽象类和 OOP 等等,我不明白为什么你会以其他方式做事。我想说的是,使用 Python 的人喜欢 duck typing,这也是为什么您经常在它的一些核心包中看到这种模式的部分原因。
duck typing、contrib 包和扩展:有时检查输入,我们可以检查它的类型,或者 duck type 它以获得特定功能。如果我们检查类型,这意味着对该方法的任何输入实际上都应该继承自那些类,而如果你回避类型,它们可以简单地实现这些方法并且它们很好。这很重要,因为如果开发人员在
scikit-learn
之外编写估算器,例如,他们希望与scikit-learn
的某些部分兼容,他们不会不必依赖于scikit-learn
作为依赖项(因为这样他们就可以从包中继承某个类),只需实现这些方法即可。如果开发人员有限制来保持他们的包和他们的依赖项轻量级,这就变得相关(我们已经在scikit-learn
中看到了这些确切的问题)。
<Mixin
类:Mixin
类背后的想法并不是子类应该继承它们并实现它们的方法;但更多的是通过它们向现有类添加功能,而无需复制/粘贴或重新实现任何方法。例如,TransformerMixin
将fit_transform
方法添加到对象,假设它已经具有fit
和transform
,而不关心对象是估算器还是转换器。同样,您可能会争辩说 OOP 的某种设计模式在这里可能更好,但这是一个永无止境的争论,而且这种方法有效,并且开发人员对此感到满意。
关于python - 哪个 SKLearn 接口(interface)定义了 .fit、.predict 等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56650382/