Использование KNN-импутации из sklearn на большом наборе данных

Вопрос или проблема

У меня есть большой набор данных ~ 1 миллион строк на 400 признаков, и я хочу заполнить недостающие значения с помощью sklearn KNNImputer.

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

У sklearn KNNImputer есть метод fit и метод transform, поэтому я считаю, что если я обучу экземпляр импьютера на всем наборе данных, то в теории смогу проходить по набору данных, разбивая его на части, и построчно заполнять все недостающие значения с помощью метода transform, а затем реконструировать новый набор данных с заполненными значениями.

Мне интересно, есть ли проблема с размером частей или же трансформация каждой новой строки независима?

50% строк набора данных полностью заполнены… будет ли лучше с точки зрения вычислений обучить объект импьютера только на этой части набора данных?

Вы могли бы использовать memmap

import numpy as np
from tempfile import mkdtemp
import os.path as path
filename = path.join(mkdtemp(), 'newfile.dat') # или вы могли бы использовать другой .dat файл, который уже содержит ваш набор данных

# предполагая, что ваши данные загружены в переменную с именем "data"

fp = np.memmap(filename, dtype="float32", mode="w+", shape=data.shape)
fp[:] = data[:]

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

Таким образом, вы:

  • только изменяете объявление ваших матриц данных, сохраняя ваш код максимально чистым
  • используете встроенный подкласс ndarray из numpy без необходимости явного управления извлечением данных с диска

Ответ или решение

Использование метода KNN Imputation из библиотеки scikit-learn для обработки крупных наборов данных, таких как ваш с миллионом строк и 400 признаками, может привести к проблемам с памятью. Важно подходить к решению этой задачи с особым вниманием к оптимизации и эффективности.

Преимущества и недостатки подхода

Перед тем как начать, рассмотрите преимущества и возможные ограничения вашего подхода:

Преимущества:

  • Сохраняет структурированность данных: Импутация KNN позволяет сохранить распределение и взаимосвязи в данных.
  • Универсальность: Метод подходит для данных с пропущенными значениями в разных местах и разной природы.

Недостатки:

  • Требуется значительный объем памяти: Поиск ближайших соседей к каждой строке может оказаться дорогим процессом.
  • Скорость: Время выполнения может значительно возрасти при увеличении объема обработки данных.

Предложенный метод: Разделение данных на чанки

Ваш подход с разделением данных на чанки, несомненно, стоит оценить. При использовании метода KNNImputer, важно следующее:

  1. Фитинг на полном объеме данных: Ваш метод предполагает применение метода fit на всем наборе данных, что в теории обосновано, так как моделирование должно учитывать всю доступную информацию.
  2. Трансформация по частям: После применения fit, использование transform на чанках данных потенциально снизит нагрузку на оперативную память.

Вопрос независимости обработки чанков

Импутация каждого нового ряда зависит от модели, обученной на всех данных, а не на структурных особенностях чанков. Тем не менее, для точности важно, чтобы каждый чанк был репрезентативен всему набору данных. Процесс импутации для строки требует учета расстояний до всех других строк, что в стандартной реализации требует доступности полной матрицы данных.

Применение только полностью заполненных строк

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

Альтернативный подход: Использование memmap

Использование numpy.memmap для обработки данных — разумный подход для снижения нагрузки на оперативную память. Этот инструмент позволяет работать с данными, находящимися на диске так, как если бы они находились в оперативной памяти, что позволяет обрабатывать данные объемом, превышающим доступную память системы.

Вот пример настройки memmap:

import numpy as np
from sklearn.impute import KNNImputer
from tempfile import mkdtemp
import os.path as path

filename = path.join(mkdtemp(), 'newfile.dat') 
fp = np.memmap(filename, dtype='float32', mode='w+', shape=data.shape)
fp[:] = data[:]

imputer = KNNImputer(n_neighbors=5)
imputer.fit(fp)

for chunk in np.array_split(fp, 10):  # Разделение на чанки
    imputed_chunk = imputer.transform(chunk)
    # ...переработка чанков...

Заключение

Ваш подход в целом обоснован, но требует осторожности в реализации. Разделение на чанки с использованием memmap может стать эффективным решением проблемы потребления памяти. Обдумайте также альтернативы, такие как использование библиотек, специализированных на обработке больших данных, например, Dask или PySpark, которые могут предложить более гибкие решения для масштабных наборов данных.

Оцените материал
Добавить комментарий

Капча загружается...