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

Gia*_*chi 5 python tensorflow tensorflow-datasets

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

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

我尝试对最后一个想法进行编码,但没有成功。我修改了我的输入函数,使其读起来像

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
Run Code Online (Sandbox Code Playgroud)

当然,这是行不通的,因为迭代器不知道它们里面有什么,所以 labels==0 条件永远不会满足。另外,标准输出中只有一个打印,这意味着该函数仅被调用一次(这意味着我仍然不明白张量流的真正工作原理)。无论如何,有办法实现我想要的吗?

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

Dav*_*rks 2

通过对代表性不足的类别进行过采样,而不是丢弃代表性过高的类别中的数据,您可能会获得更好的结果。通过这种方式,您可以保持代表性过高的类别中的差异。您不妨使用您拥有的数据。

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

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