在执行scikit-learn教程中的多类别示例时
我发现了一个小小的奇怪之处。
>>> import sklearn>>> sklearn.__version__0.19.1>>> from sklearn.svm import SVC>>> from sklearn.multiclass import OneVsRestClassifier>>> from sklearn.preprocessing import LabelBinarizer>>> X = [[1, 2], [2, 4], [4, 5], [3, 2], [3, 1]]>>> y = [0, 0, 1, 1, 2] # 三类>>> clf = OneVsRestClassifier(estimator=SVC(random_state=0))>>> clf.fit(X, y).predict(X)array([0, 0, 1, 1, 2])
这些都很好。现在使用独热编码:
>>> y = LabelBinarizer().fit_transform(y)>>> yarray([[1, 0, 0], [1, 0, 0], [0, 1, 0], [0, 1, 0], [0, 0, 1]])
我期望标签二值化器只对目标进行编码,而不对分类器产生影响。然而,它却产生了不同的结果:
>>> clf.fit(X, y).predict(X)array([[1, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 0], [0, 0, 0]])
在Google Colab上的笔记本(同样的代码却产生了不同的错误,奇怪的是):
回答:
OneVsRestClassifier
在后台本身就应用了 LabelBinarizer
(源代码在 sklearn/multiclass.py
):
def fit(self, X, y): ... self.label_binarizer_ = LabelBinarizer(sparse_output=True) Y = self.label_binarizer_.fit_transform(y) Y = Y.tocsc() self.classes_ = self.label_binarizer_.classes_
因此,额外的 manual 转换是不必要的。实际上,它将你的独热编码的 y
解释为多标签输入。从文档中可以看到:
y
: (稀疏) 数组类型,shape = [n_samples, ], [n_samples, n_classes]
多类别目标。指示矩阵会启动多标签分类。