Подвыборка несбалансированного набора данных в тензорном потоке

Новичок в Tensorflow здесь. Это мой первый проект, и я работаю с заранее определенными оценщиками.

У меня чрезвычайно несбалансированный набор данных, где положительные результаты составляют примерно 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

Это, конечно, не работает, потому что итераторы не знают, что внутри них, поэтому условие label == 0 никогда не выполняется. Кроме того, в стандартном выводе есть только один вывод, что означает, что эта функция вызывается только один раз (и это означает, что я до сих пор не понимаю, как на самом деле работает тензорный поток). В любом случае, есть ли способ реализовать то, что я хочу?

PS: Я подозреваю, что предыдущий код, даже если он работал, как задумано, вернул бы меньше одной тысячной от первоначальных отрицательных значений из-за перезапуска счетчика каждый раз, когда он находит положительный результат. Это незначительная проблема, и до сих пор я даже мог найти магическое число внутри флага, которое дает мне ожидаемый результат, не слишком беспокоясь о его математической красоте.


person Gianluca Micchi    schedule 09.04.2018    source источник


Ответы (1)


Вы, вероятно, получите лучшие результаты, если передискретизируете ваш недостаточно представленный класс, а не выбросите данные в вашем избыточно представленном классе. Таким образом вы сохраните дисперсию в чрезмерно представленном классе. Вы также можете использовать имеющиеся у вас данные.

Самый простой способ добиться этого, вероятно, - создать два набора данных, по одному для каждого класса. Затем вы можете использовать Dataset.interleave для равной выборки из обоих наборов данных.

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

person David Parks    schedule 09.04.2018
comment
Большое спасибо за ответ. Мне неясно одно по поводу Dataset.interleave: мне нужно создать два отдельных файла, один с положительными результатами, а другой с отрицательными, верно? - person Gianluca Micchi; 09.04.2018
comment
Это звучит разумно, но в этом нет необходимости. Вам нужно начать с создания двух отдельных объектов набора данных, по одному для каждого из классов. Как вы это сделаете, зависит от вас. Разделение файлов кажется простым делом, но вы, вероятно, могли бы найти способ отфильтровать нежелательный класс из каждого набора данных. Dataset.interleave требует, чтобы вы передавали несколько наборов данных, и он просто выбирает одно значение из каждого по очереди и возвращает его как свой собственный набор данных. Следовательно, он автоматически выполняет работу по уравновешиванию классов. Не забудьте добавить .shuffle к каждому из наборов данных для каждого класса по отдельности. - person David Parks; 09.04.2018