多类分类
为了更好地说明差异,假设您的目标是将SO问题分类为n_classes
个不同的互斥类。在本例中,为了简单起见,我们只考虑四个类,即'Python'
、'Java'
、'C++'
和'Other language'
。假设您有一个由六个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
是不同类别的数量。每个二元分类器都会决定一个项目是否属于特定的类别。在这种情况下,您不能将类标签编码为从 0
到 n_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问题进行分类,比如语言和应用程序,那么你就需要进行多输出分类。为了简单起见,我将只考虑三个应用程序类别,分别是'计算机视觉'
、'语音处理'
和'其他应用程序'
。你的数据集的标签数组应该是二维的:
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')