python - scikit-learn 在多类分类中是否默认使用 One-Vs-Rest?
问题描述
我正在处理一个多类问题(4 个类),我正在尝试用 Python 中的 scikit-learn 来解决它。
我看到我有三个选择:
我只是简单地实例化一个分类器,然后我适合训练并用测试评估;
classifier = sv.LinearSVC(random_state=123) classifier.fit(Xtrain, ytrain) classifier.score(Xtest, ytest)
我将实例化的分类器“封装”在 OneVsRest 对象中,生成一个用于训练和测试的新分类器;
classifier = OneVsRestClassifier(svm.LinearSVC(random_state=123)) classifier.fit(Xtrain, ytrain) classifier.score(Xtest, ytest)
我将实例化的分类器“封装”在 OneVsOne 对象中,生成一个用于训练和测试的新分类器。
classifier = OneVsOneClassifier(svm.LinearSVC(random_state=123)) classifier.fit(Xtrain, ytrain) classifier.score(Xtest, ytest)
我了解 OneVsRest 和 OneVsOne 之间的区别,但我无法理解在第一种情况下我在做什么,我没有明确选择这两个选项中的任何一个。在这种情况下 scikit-learn 会做什么?它是否隐式使用 OneVsRest?
对此事的任何澄清将不胜感激。
最好的,先生
编辑:为了清楚起见,我对 SVM 的情况并不特别感兴趣。例如,RandomForest 呢?
解决方案
更新的答案:正如评论和编辑中所阐明的那样,问题更多的是关于 sklearn 的一般设置,而不是关于LinearSVC
下面解释的具体情况。
这里的主要区别是您可以使用的一些分类器具有“内置多类分类支持”,即默认情况下该算法可以区分两个以上的类。例如,一个示例是随机森林,或具有多个输出节点的多层感知器 (MLP)。
在这些情况下,OneVs
根本不需要拥有一个对象,因为您已经在解决您的任务。事实上,使用这样的策略甚至可能会降低您的性能,因为您通过让算法仅在单个二进制实例之间做出决定,从而“隐藏”了算法的潜在相关性。
另一方面,算法喜欢SVC
或LinearSVC
只支持二进制分类。因此,为了扩展这些(性能良好的)算法类别,我们不得不依赖从最初的多类分类任务到二元分类任务的简化。
据我所知,最完整的概述可以在这里找到:如果向下滚动一点,您可以看到其中一种算法本质上是多类的,或者默认使用其中一种策略。
请注意,OVO 下列出的所有算法实际上现在默认采用 OVR 策略!在这方面,这似乎是稍微过时的信息。
初步答案:
这个问题可以通过查看相关的 scikit-learn 文档轻松回答。
通常,对 Stackoverflow 的期望是您至少自己完成了某种形式的研究,因此请考虑先查看现有文档。
multi_class : string, 'ovr' 或 'crammer_singer' (default='ovr')
如果 y 包含两个以上的类,则确定多类策略。
"ovr"
训练 n_classes one-vs-rest 分类器,同时"crammer_singer"
优化所有类的联合目标。虽然从理论的角度来看,crammer_singer 很有趣,因为它是一致的,但它很少在实践中使用,因为它很少能带来更好的准确性并且计算成本更高。如果"crammer_singer"
选择,选项损失、惩罚和对偶将被忽略。
所以,很明显,它使用一对一休息。
顺便说一句,“常规” SVC也是如此。
推荐阅读
- php - 我应该使用什么样的连接,或者我应该为此制作模型?
- sas - 如何在没有标题的上游平面文件中发生结构更改后生成新的导入代码?
- python - 用 Pandas 处理缺失的分类值?
- r - 重命名 index.Rmd 时“找不到站点生成器”
- python - 为什么我在 python 3.7.3 中收到 urlopen no attribute 错误?
- java - 如何获取每个字母并使用子字符串方法将它们添加为点
- sql - 使用 INTO 分配给 Oracle 中的变量
- authentication - 软件租户是用户还是用户组?
- apache - 如何在 Solr 中创建新集合
- javascript - 单击按钮时如何将按钮的值添加到文本区域?