首页 > 解决方案 > 如何验证验证标签与训练标签的范围相同,Python Numpy

问题描述

作为项目的一部分,我需要在 Python 中训练一个多标签文本分类器。我正在遵循某种指南,但由于我在 Python 方面的经验不足,我在理解验证验证标签与训练标签在同一范围内的部分代码时遇到了一些问题。+ 这是抛出错误的原因。

我试图理解的代码是这个:(更具体地说,这段代码的前两行是让我感到困惑的那些)

num_classes = max(np.array(train_labels)) + 1
missing_classes = [i for i in range(num_classes) if i not in train_labels]
if len(missing_classes):
    raise ValueError('Missing samples with label value(s) '
                     '{missing_classes}. Please make sure you have '
                     'at least one sample for every label value '
                     'in the range(0, {max_class})'.format(
                        missing_classes=missing_classes,
                        max_class=num_classes - 1))

if num_classes <= 1:
    raise ValueError('Invalid number of labels: {num_classes}.'
                     'Please make sure there are at least two classes '
                     'of samples'.format(num_classes=num_classes))

unexpected_labels = [v for v in test_labels if v not in range(num_classes)]
if len(unexpected_labels):
    raise ValueError('Unexpected label values found in the test set:'
                     ' {unexpected_labels}. Please make sure that the '
                     'labels in the validation set are in the same range '
                     'as training labels.'.format(
                         unexpected_labels=unexpected_labels))

还有它给我的错误:

    num_classes = max(np.array(train_labels)) 
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

如果这对您来说很重要,那么在此代码块之前编写的代码是:

lb = preprocessing.LabelBinarizer()
train_labels = lb.fit_transform(train_df['label'])
train_labels = np.squeeze(train_labels)

print(lb.classes_)

test_labels=lb.transform(test_df['label'])
test_labels=np.squeeze(test_labels)

这给了我这个输出: [67 68 69 70]

任何帮助我更好地理解将不胜感激。

标签: pythonnumpyerror-handlingpreprocessortext-classification

解决方案


num_classes = max(np.array(train_labels)) + 1

train_labels这仅在包含范围内的整数值时才有意义(0, n_classes)(类似于[1, 0, 3, 2, 0, 2, 3, 1, 0]4 个类)。这似乎不是你在这里所拥有的......

lb.classes_ == [67, 68, 69, 70]表示这些是 中的唯一值train_df['label']LabelBinarizer接受一个任意标签数组,并且“one-hot”将它们编码为一个由 0 和 1 组成的数组,其形状为(n_samples, n_classes)。就像是:

>> train_labels
array([[1, 0, 0, 0],
       [0, 0, 0, 1],
       ...
       [0, 1, 0, 0]])

1无论有多少类,该数组中的最大值始终为 。

max此外,您只能在一维数组上调用内置函数。您得到的错误来自max试图比较可迭代的值的事实,在 2D numpy 数组的情况下是行向量。这是模棱两可的,这就是为什么您无法以这种方式找到最大值的原因:

>> np.array([0, 1, 0]) > np.array([1, 0, 0])
array([False,  True,  False])

(要实际找到 numpy 数组的最大值,请np.max()改用。)

在任何情况下,如果您想要二值化标签数组表示的类数,您只需获取列数即可:

>> train_labels.shape[-1]
4

以下行旨在检查每个类中是否至少有一个实例,但如果是二进制二维数组train_labels,则同样没有意义:train_labels

missing_classes = [i for i in range(num_classes) if i not in train_labels]

您可以转换train_labels为整数标签数组:

>> np.argmax(train_labels, axis=-1)
array([0, 3, ... , 1])

或者您可以检查每列中是否至少有一个非零值:

>> np.sum(train_labels, axis=0) > 0
array([ True,  True,  True,  True])

>> np.all(np.sum(train_labels, axis=0) > 0)
True

推荐阅读