python - scikit learn中的OneVsRestClassifier和MultiOutputClassifier有什么区别?

标签 python scikit-learn classification multilabel-classification multiclass-classification

谁能解释一下(也许可以举例)OneVsRestClassifier 之间的区别是什么?和 MultiOutputClassifier在 scikit-learn 中?

我已阅读文档并了解我们使用:

  • OneVsRestClassifier - 当我们想要进行多类或多标签分类时,它的策略是为每个类安装一个分类器。对于每个分类器,该类与所有其他类进行拟合。 (这很清楚,这意味着多类/多标签分类问题被分解为多个二元分类问题。
  • MultiOutputClassifier - 当我们想要进行多目标分类时(这是什么?),它的策略是为每个目标安装一个分类器 (那里的目标是什么意思?)

我已经使用 OneVsRestClassifier 进行多标签分类,我可以理解它是如何工作的,但后来我发现 MultiOutputClassifier 并且无法理解它与 OneVsRestClassifier 的工作方式有何不同。

最佳答案

多类分类

为了更好地说明差异,让我们假设您的目标是将 SO 问题分类为 n_classes 个不同的、互斥的类。在这个例子中为了简单起见,我们只考虑四个类,分别是'Python''Java''C++''其他语言'。让我们假设您有一个仅由六个 SO 问题组成的数据集,并且这些问题的类标签存储在数组 y 中,如下所示:

import numpy as np
y = np.asarray(['Java', 'C++', 'Other language', 'Python', 'C++', 'Python'])

上述情况通常称为多类分类(也称为多项式分类)。为了拟合分类器并通过 scikit-learn 库验证模型,您需要将文本类标签转换为数字标签。为此,您可以使用 LabelEncoder :

from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
y_numeric = le.fit_transform(y)

这就是数据集标签的编码方式:

In [220]: y_numeric
Out[220]: array([1, 0, 2, 3, 0, 3], dtype=int64)

其中这些数字表示以下数组的索引:

In [221]: le.classes_
Out[221]: 
array(['C++', 'Java', 'Other language', 'Python'], 
      dtype='|S14')

一个重要的特殊情况是只有两个类,即 n_classes = 2。这通常称为二元分类

多标签分类

现在让我们假设您希望使用 n_classes 个二进制分类器池执行这种多类分类,其中 n_classes 是不同类的数量。这些二元分类器中的每一个都会决定项目是否属于特定类别。在这种情况下,您不能将类标签编码为从 0n_classes - 1 的整数,您需要创建一个二维指示矩阵。考虑示例 n 属于 k 类。那么,指标矩阵的[n, k]条目为1,而n行的其余元素为0 。需要注意的是,如果类不是互斥的,则可以有多个 1 连续出现。这种方法被命名为多标签分类,可以通过MultiLabelBinarizer 轻松实现:

from sklearn.preprocessing import MultiLabelBinarizer
mlb = MultiLabelBinarizer()
y_indicator = mlb.fit_transform(y[:, None])

指标如下所示:

In [225]: y_indicator
Out[225]: 
array([[0, 1, 0, 0],
       [1, 0, 0, 0],
       [0, 0, 1, 0],
       [0, 0, 0, 1],
       [1, 0, 0, 0],
       [0, 0, 0, 1]])

以及 1 实际是该数组索引的列号:

In [226]: mlb.classes_
Out[226]: array(['C++', 'Java', 'Other language', 'Python'], dtype=object)

多输出分类

如果您想同时根据两个不同的标准(例如语言和应用程序)对特定的 SO 问题进行分类,该怎么办?在这种情况下,您打算进行多输出分类。为简单起见,我将只考虑三个应用程序类,即 'Computer Vision''Speech Processing' 和 'Other application'。您的数据集的标签数组应该是二维的:

y2 = np.asarray([['Java', 'Computer Vision'],
                 ['C++', 'Speech Recognition'],
                 ['Other language', 'Computer Vision'],
                 ['Python', 'Other Application'],
                 ['C++', 'Speech Recognition'],
                 ['Python', 'Computer Vision']])

同样,我们需要将文本类标签转换为数字标签。据我所知,此功能尚未在 scikit-learn 中实现,因此您需要编写自己的代码。 This thread描述了一些巧妙的方法来做到这一点,但就本文而言,以下单行就足够了:

y_multi = np.vstack((le.fit_transform(y2[:, i]) for i in range(y2.shape[1]))).T

编码后的标签如下所示:

In [229]: y_multi
Out[229]: 
array([[1, 0],
       [0, 2],
       [2, 0],
       [3, 1],
       [0, 2],
       [3, 0]], dtype=int64)

并且可以从以下数组中推断出每一列中的值的含义:

In [230]: le.fit(y2[:, 0]).classes_
Out[230]: 
array(['C++', 'Java', 'Other language', 'Python'], 
      dtype='|S18')

In [231]: le.fit(y2[:, 1]).classes_
Out[231]: 
array(['Computer Vision', 'Other Application', 'Speech Recognition'], 
      dtype='|S18')

关于python - scikit learn中的OneVsRestClassifier和MultiOutputClassifier有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42819460/

相关文章:

python - 如何使用 Scikit-Learn 在 Python 中实现斐波那契数列?

classification - 如何调整分类任务中标签的分级偏差?

text - 机器学习克服拼写错误

python - pytest-xdist 对于单例线程安全吗

python:仅覆盖抽象类中的一些方法

python - Python检查输入变量是否与格式匹配

python - 从 scikit KNeighborsClassifier 打印最近邻居的标签?

python - 无法使用 python 和 dogtail 自动执行远程程序,远程服务器中没有图形界面......

python - Scikit-Learn 中的分类数据转换

java - 使用 weka API 对高维 int vector 进行分类的最佳方法是什么?