在张量流中对不平衡数据集进行子采样

Subsampling an unbalanced dataset in tensorflow

这里是 Tensorflow 初学者。这是我的第一个项目,我正在使用预定义的估算器。

我有一个极度不平衡的数据集,其中积极结果大约占总数据的 0.1%,我怀疑这种不平衡会显着影响我的模型的性能。作为解决这个问题的第一次尝试,因为我有大量数据,所以我想扔掉大部分底片以创建一个平衡的数据集。我可以看到两种方法:预处理数据以仅保留千分之一的底片,然后将其保存在一个新文件中,然后再将其传递给 tensorflow,例如使用 pyspark;并要求 tensorflow 只使用它找到的一千个负数中的一个。

我试图对最后一个想法进行编码,但没有成功。我将输入函数修改为

def train_input_fn(data_file="../data/train_input.csv", shuffle_size=100_000, batch_size=128):
    """Generate an input function for the Estimator."""

    dataset = tf.data.TextLineDataset(data_file)  # Extract lines from input files using the Dataset API.
    dataset = dataset.map(parse_csv, num_parallel_calls=3)
    dataset = dataset.shuffle(shuffle_size).repeat().batch(batch_size)

    iterator = dataset.make_one_shot_iterator()
    features, labels = iterator.get_next()

    # TRY TO IMPLEMENT THE SELECTION OF NEGATIVES
    thrown = 0
    flag = np.random.randint(1000)
    while labels == 0 and flag != 0:
        features, labels = iterator.get_next()
        thrown += 1
        flag = np.random.randint(1000)
    print("I've thrown away {} negative examples before going for label {}!".format(thrown, labels))
    return features, labels

这当然是行不通的,因为迭代器不知道它们里面有什么,所以永远不会满足 labels==0 条件。此外,stdout 中只有一个打印,这意味着该函数仅被调用一次(这意味着我仍然不明白 tensorflow 的真正工作原理)。不管怎样,有没有办法实现我想要的?

PS:我怀疑之前的代码,即使它按预期工作,也会 return 少于初始负数的千分之一,因为每次找到正数时都会重新开始计数.这是一个小问题,到目前为止,我什至可以在标志内找到一个神奇的数字,它可以给我预期的结果,而不必太担心它的数学美感。

您可能会通过 过度采样 您的 under-represented class 而不是丢弃 over-represented class 中的数据获得更好的结果].这样你就可以保持 over-represented class 的方差。您不妨使用您拥有的数据。

实现这一点的最简单方法可能是创建两个数据集,每个 class。然后您可以使用 Dataset.interleave 从两个数据集中平均采样。

https://www.tensorflow.org/api_docs/python/tf/data/Dataset#interleave

可以使用以下代码轻松实现过采样:

resampled_ds = tf.data.experimental.sample_from_datasets([pos_ds, neg_ds], weights=[0.7, 0.3])

Tensorflow 有一个很好的处理不平衡数据的指南,您可以在这里找到更多的想法: https://www.tensorflow.org/tutorials/structured_data/imbalanced_data#oversampling