Генерация сбалансированных пакетов для несбалансированных наборов данных

PythonPythonBeginner
Практиковаться сейчас

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

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

🎯 Задачи

В этом проекте вы научитесь:

  • Как реализовать функциональность upsampling и downsampling для балансировки распределения выборок внутри пакета.
  • Как выводить пакет выборок с количеством выборок, равным размеру пакета, где распределение меток внутри пакета尽可能равномерно.
  • Как тестировать несбалансированный конвейер данных, чтобы убедиться, что он работает как ожидается.

🏆 Достижения

После завершения этого проекта вы сможете:

  • Обрабатывать несбалансированные наборы данных в машинном обучении.
  • Применять методы upsampling и downsampling для балансировки распределения классов.
  • Реализовать конвейер данных, который может генерировать сбалансированные пакеты из несбалансированного набора данных.

Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL python(("Python")) -.-> python/FunctionsGroup(["Functions"]) python(("Python")) -.-> python/PythonStandardLibraryGroup(["Python Standard Library"]) python(("Python")) -.-> python/ControlFlowGroup(["Control Flow"]) python(("Python")) -.-> python/DataStructuresGroup(["Data Structures"]) python/ControlFlowGroup -.-> python/for_loops("For Loops") python/DataStructuresGroup -.-> python/lists("Lists") python/FunctionsGroup -.-> python/function_definition("Function Definition") python/PythonStandardLibraryGroup -.-> python/data_collections("Data Collections") subgraph Lab Skills python/for_loops -.-> lab-373136{{"Генерация сбалансированных пакетов для несбалансированных наборов данных"}} python/lists -.-> lab-373136{{"Генерация сбалансированных пакетов для несбалансированных наборов данных"}} python/function_definition -.-> lab-373136{{"Генерация сбалансированных пакетов для несбалансированных наборов данных"}} python/data_collections -.-> lab-373136{{"Генерация сбалансированных пакетов для несбалансированных наборов данных"}} end

Реализация upsampling и downsampling

В этом шаге вы научитесь реализовывать функциональность upsampling и downsampling для балансировки распределения выборок внутри пакета.

Откройте файл unbalanced_data_pipeline.py, расположенный в директории /home/labex/project.

В функции unbalanced_data_pipeline начните с создания defaultdict, называемого counter, для хранения векторов признаков и соответствующих им векторов меток в one-hot кодировке.

    counter = defaultdict(list)
    for x, y in data:
        counter[tuple(y)].append(x)

Это сгруппирует данные по их векторам меток, что упростит проведение upsampling и downsampling.

Далее вычислите количество выборок, которое должно быть включено в каждый пакет для каждой метки. Это можно сделать, поделив размер пакета на количество уникальных меток, а затем сохранив остаток в переменной num_left.

    batch_data = []
    pre_num = batch_size // len(counter.keys())
    num_left = batch_size % len(counter.keys())

Теперь переберите словарь counter и случайным образом отберите необходимое количество выборок для каждой метки. Добавьте эти выборки в список batch_data.

    for y, x in counter.items():
        samples = random.sample(x, pre_num)
        batch_data.extend([[sample, list(y)] for sample in samples])

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

    for _ in range(num_left):
        y = random.choice(list(counter.keys()))
        x = random.choice(counter[y])
        batch_data.append([x, list(y)])

Верните список batch_data.

    return batch_data

В этом шаге вы реализовали функциональность upsampling и downsampling для балансировки распределения выборок внутри пакета. Функция unbalanced_data_pipeline теперь принимает входные данные и размер пакета и возвращает список пакетов с приблизительно сбалансированным распределением классов.

✨ Проверить решение и практиковаться

Тестирование несбалансированного конвейера данных

В этом шаге вы протестируете функцию unbalanced_data_pipeline, чтобы убедиться, что она работает как ожидается.

Добавьте следующий код в файл unbalanced_data_pipeline.py.

if __name__ == "__main__":
    data = [
        [[1, 2, 5], [1, 0]],
        [[1, 6, 0], [1, 0]],
        [[4, 1, 8], [1, 0]],
        [[7, 0, 4], [0, 1]],
        [[5, 9, 4], [0, 1]],
        [[2, 0, 1], [0, 1]],
        [[1, 9, 3], [0, 1]],
        [[5, 5, 5], [0, 1]],
        [[8, 4, 0], [0, 1]],
        [[9, 6, 3], [0, 1]],
        [[7, 7, 0], [0, 1]],
        [[0, 3, 4], [0, 1]],
     ]
    for epoch in range(10):
        batch_data = unbalanced_data_pipeline(data, 6)
        batch_data = list(batch_data)
        print(f"{epoch=}, {batch_data=}")

В блоке if __name__ == "__main__": мы вызываем функцию unbalanced_data_pipeline с примерами данных и размером пакета 6.

Запустите файл unbalanced_data_pipeline.py, чтобы увидеть вывод.

python unbalanced_data_pipeline.py

Вывод должен быть похож на пример, приведенный в исходном задании:

epoch=0, batch_data=[[[1, 2, 5], [1, 0]], [[4, 1, 8], [1, 0]], [[1, 6, 0], [1, 0]], [[2, 0, 1], [0, 1]], [[7, 0, 4], [0, 1]], [[5, 9, 4], [0, 1]]]
epoch=1, batch_data=[[[4, 1, 8], [1, 0]], [[1, 2, 5], [1, 0]], [[1, 6, 0], [1, 0]], [[2, 0, 1], [0, 1]], [[9, 6, 3], [0, 1]], [[1, 9, 3], [0, 1]]]
epoch=2, batch_data=[[[4, 1, 8], [1, 0]], [[1, 2, 5], [1, 0]], [[1, 6, 0], [1, 0]], [[5, 5, 5], [0, 1]], [[7, 0, 4], [0, 1]], [[8, 4, 0], [0, 1]]]
epoch=3, batch_data=[[[1, 2, 5], [1, 0]], [[1, 6, 0], [1, 0]], [[4, 1, 8], [1, 0]], [[7, 7, 0], [0, 1]], [[8, 4, 0], [0, 1]], [[0, 3, 4], [0, 1]]]
epoch=4, batch_data=[[[4, 1, 8], [1, 0]], [[1, 6, 0], [1, 0]], [[1, 2, 5], [1, 0]], [[5, 5, 5], [0, 1]], [[0, 3, 4], [0, 1]], [[8, 4, 0], [0, 1]]]
epoch=5, batch_data=[[[1, 6, 0], [1, 0]], [[4, 1, 8], [1, 0]], [[1, 2, 5], [1, 0]], [[2, 0, 1], [0, 1]], [[7, 0, 4], [0, 1]], [[7, 7, 0], [0, 1]]]
epoch=6, batch_data=[[[1, 2, 5], [1, 0]], [[1, 6, 0], [1, 0]], [[4, 1, 8], [1, 0]], [[8, 4, 0], [0, 1]], [[5, 9, 4], [0, 1]], [[0, 3, 4], [0, 1]]]
epoch=7, batch_data=[[[1, 2, 5], [1, 0]], [[1, 6, 0], [1, 0]], [[4, 1, 8], [1, 0]], [[2, 0, 1], [0, 1]], [[0, 3, 4], [0, 1]], [[1, 9, 3], [0, 1]]]
epoch=8, batch_data=[[[1, 6, 0], [1, 0]], [[4, 1, 8], [1, 0]], [[1, 2, 5], [1, 0]], [[7, 7, 0], [0, 1]], [[2, 0, 1], [0, 1]], [[0, 3, 4], [0, 1]]]
epoch=9, batch_data=[[[1, 2, 5], [1, 0]], [[4, 1, 8], [1, 0]], [[1, 6, 0], [1, 0]], [[7, 0, 4], [0, 1]], [[0, 3, 4], [0, 1]], [[5, 5, 5], [0, 1]]]

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

✨ Проверить решение и практиковаться

Резюме

Поздравляем! Вы завершили этот проект. Вы можете практиковаться в более лабораториях в LabEx, чтобы улучшить свои навыки.