当前位置: 首页 > 知识库问答 >
问题:

scikit learn中OneVsRestClassifier和MultiOutputClassifier的区别是什么?

季凡
2023-03-14

有人能解释一下(也许用例子)scikit learn中OneVsRestClassifier和MultiOutputClassifier的区别吗?

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

  • OneVsRestClassifier——当我们想要进行多类或多标签分类时,它的策略包括为每个类安装一个分类器。对于每个分类器,该类与所有其他类相匹配。(这非常清楚,这意味着多类/多标签分类问题被分解为多个二进制分类问题)

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

共有2个答案

宫弘亮
2023-03-14

这是@tonechave回答的扩展。在阅读这个之前先阅读那个答案。OVR仅当每个标签是二进制标签/类(也称为二进制多标签)时才支持多标签,即样本属于该标签或不属于该标签。当目标是多输出(也称为多类多标签)时,即当每个样本可以属于标签中的任何一个类时,它将不起作用。对于后面的情况,您需要使用skLearning多输出分类器。

换句话说,当目标变量如下所示时,sklearn OVR不起作用,

y_true = np.arr([[2, 1, 0],
                 [0, 2, 1],
                 [1, 2, 4]])

其中label1有4个类[0,1,2,3]; label2有3个类[0,1,2]; label3有5个类[0, 1, 2 , 3, 4]。第一个样本属于label1中的第2类,label2中的第1类,label3中的第0类。把它想象成标签不是互斥的,而每个标签中的类是互斥的。

SKOVR将在以下情况下工作:,

y_true = np.arr([[0, 1, 1],
                 [0, 0, 1],
                 [1, 1, 0]])

其中label1 labe2、label3各只有2个类。所以,样品要么属于那个标签,要么不属于。第一个样本属于label1和label2。

很抱歉,我找不到这种用例的真实示例。

鲁斯伯
2023-03-14

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

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

上述情况通常称为多类分类(也称为多项式分类)。为了适应分类器并通过scikit学习库验证模型,您需要将文本类标签转换为数字标签。要实现这一点,您可以使用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_类二进制分类器池执行此类多类分类,即n_类不同类的数量。这些二进制分类器中的每一个都决定一个项目是否属于特定的类。在这种情况下,您不能将类别标签编码为从0n_classes-1的整数,您需要创建一个二维指示符矩阵。认为样本<代码> n>代码>属于代码< >代码>代码>。然后,指标矩阵的[n,k]条目为1,行n中的其余元素为0。需要注意的是,如果类不是互斥的,则一行中可能有多个1。这种方法称为多标签分类,可通过多标签二进制程序轻松实现:

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问题进行分类,该怎么办?在这种情况下,您打算进行多输出分类。为了简单起见,我将只考虑三个应用程序类,即代码>计算机视觉'< /COD>,<代码>语音处理< /代码>和<代码>其他应用程序< /代码>。数据集的标签数组应为二维:

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

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

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')
 类似资料:
  • #{}带引号,${}不带引号; #{}可以防止SQL注入; ${}常用于数据库表名、order by子句; 一般能用#{}就不要使用${};

  • 本文向大家介绍#{}和${}的区别是什么?相关面试题,主要包含被问及#{}和${}的区别是什么?时的应答技巧和注意事项,需要的朋友参考一下 #{}是预编译处理,${}是字符串替换。 Mybatis 在处理#{}时,会将 sql 中的#{}替换为?号,调用 PreparedStatement 的 set 方法来赋值; Mybatis 在处理{}时,就是把${}替换成变量的值。 使用#{}可以有效的防

  • 我试着用谷歌搜索,但找不到答案。 取自ApacheSpark:map vs mapPartitions? RDD的map和mapPartitions有什么区别 map在每个元素级别运行正在使用的函数,而mapPartitions在分区级别运行该函数。 在这种情况下,什么是元素级别?这只是一行吗?

  • 我浏览了一下Spark中RDD和Dataframe的链接有什么区别? > 我们可以在spark上运行Pandas、numpy数据帧功能吗。对于numpy,np。像df这样的熊猫在哪里和在哪里。分组依据[“”]。agg()

  • 本文向大家介绍redux和flux的区别是什么?相关面试题,主要包含被问及redux和flux的区别是什么?时的应答技巧和注意事项,需要的朋友参考一下 Flux: Store 包含状态和更改逻辑 有多个 Store 所有 Store 都互不影响且是平级的 有单一调度器 React 组件订阅 store 状态是可变的 Redux: Store 和更改逻辑是分开的 只有一个 Store 带有分层 re

  • 本文向大家介绍useState和this.state的区别是什么?相关面试题,主要包含被问及useState和this.state的区别是什么?时的应答技巧和注意事项,需要的朋友参考一下 内部基于 实现,方法返回 state 本身以及一个修改 state 的方法。 通过 修改数据,不会和 一样进行对象属性合并,会直接覆盖。 Hooks 函数组件中,存在的概念,在一次渲染闭包中,state 是固定不