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

时间:2018-04-09 14:15:37

标签: python tensorflow tensorflow-datasets

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

当然,这不起作用,因为迭代器不知道它们内部是什么,所以标签== 0条件永远不会满足。此外,stdout中只有一个打印,这意味着此函数只调用一次(这意味着我仍然不理解tensorflow是如何工作的)。无论如何,有没有办法实现我想要的东西?

PS:我怀疑之前的代码,即使它按预期工作,也会返回不到千分之一的初始负数,因为每次发现一个正数时重新计数。这是一个小问题,到目前为止,我甚至可以在旗帜中找到一个神奇的数字,它给了我预期的结果,而不用太担心它的数学美。

2 个答案:

答案 0 :(得分:1)

你可能会通过过度采样你的代表性不足的类而不是在过度代表的类中丢弃数据来获得更好的结果。这样,您可以在过度表示的类中保持方差。您也可以使用您拥有的数据。

实现这一目标的最简单方法可能是创建两个数据集,每个类一个。然后,您可以使用Dataset.interleave从两个数据集中均等地进行采样。

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

答案 1 :(得分:0)

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

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