Многослойное разделение Shuffle для больших файлов - PullRequest
0 голосов
/ 27 июня 2018

У меня есть файл CSV 35 ГБ (в будущем ожидается больше) для проблемы двоичной классификации в Керасе. Чтобы обучить и протестировать мою модель, я хочу разбить данные на наборы обучающих / тестовых данных, имеющие одинаковую долю положительных выборок в каждом. Примерно так:

|Dataset type | Total samples | negative samples | positive instances |
|-------------|---------------|------------------|--------------------|
|Dataset      |    10000      |        8000      |       2000         |
|Train        |    7000       |        6000      |       1000         |
|Test         |    3000       |        2000      |       1000         |

Поскольку этот набор данных слишком велик для размещения в памяти, я создал собственный генератор для загрузки данных в пакетном режиме и обучения модели с помощью fit_generator. Поэтому я не могу применить метод StratifiedShuffleSplit от Scikitlearn, чтобы сделать это, так как ему нужен весь набор данных, а не только часть данных, чтобы сохранить пропорцию положительных экземпляров как обучающих, так и тестовых наборов данных.

Редактировать: мои данные имеют следующую форму: 11500 x 160000

Кто-нибудь знает, как я могу делать то, что хочу?

Решение

Я последовал за ответом Яна Линя шаг за шагом. Просто отметьте, что если у вас большое количество столбцов, преобразование Dataframe в hdf5 может завершиться неудачно. Таким образом, создайте файл hdf5 непосредственно из массива numpy

Кроме того, чтобы добавить данные в файл hdf5, мне пришлось сделать следующее (установить maxshape=None для каждого измерения вашего набора данных, размер которого вы хотите изменить без ограничений. В моем случае я изменяю размер набора данных, чтобы добавить неограниченные строки с фиксированный номер столбца):

path = 'test.h5'
mydata = np.random.rand(11500, 160000)
if not os.path.exists(path):
    h5py.File(path, 'w').create_dataset('dataset', data=mydata, maxshape=(None, mydata.shape[1]))
else:
    with h5py.File(path, 'a') as hf:
        hf['dataset'].resize(hf['dataset'].shape[0] + mydata.shape[0], axis=0)
        hf["dataset"][-mydata.shape[0]:, :] = mydata

1 Ответ

0 голосов
/ 27 июня 2018

Я обычно делаю это:

  1. сохраняет данные в файле, таком как numpy.memmap или набор данных HDF5 (если ваш набор данных имеет большое количество функций, используйте h5py вместо pandas.DataFrame.to_hdf() или pytables)
  2. создать целочисленный индекс, используя что-то вроде этого range(dataset.shape[0])
  3. использовать функцию разделения в sklearn, чтобы разбить целочисленный индекс на train / test
  4. передайте целочисленный индекс в ваш генератор и используйте целочисленный индекс, чтобы найти данные в h5py.Dataset или numpy.memmap

Если вы используете keras.image.ImageDataGenerator.flow() в качестве генератора, вы можете обратиться к помощнику, который я написал здесь , чтобы упростить переиндексацию данных.

...