Обработка пропущенных (nan) значений в sklearn.preprocessing - PullRequest
0 голосов
/ 21 марта 2019

Я пытаюсь нормализовать данные с пропущенными (то есть, нан) значениями перед их обработкой, используя предварительную обработку scikit-learn.

Очевидно, что некоторые скейлеры (например, StandardScaler) обрабатывают пропущенные значения так, как я хочу - я имею в виду нормализацию существующих значений, сохраняя nans - в то время как другие (например, нормализатор) просто вызывают ошибку.

Я осмотрелся и не нашел - как я могу использовать нормализатор с отсутствующими значениями или воспроизвести его поведение (с norm = 'l1' и norm = 'l2'; мне нужно протестировать несколько вариантов нормализации) как-нибудь иначе?

Заранее спасибо

from sklearn.preprocessing import Normalizer, StandardScaler
import numpy as np

data = np.array([0,1,2,np.nan, 3,4])

scaler = StandardScaler(with_mean=True, with_std=True)
scaler.fit_transform(data.reshape(-1,1))

normalizer = Normalizer(norm='l2')
normalizer.fit_transform(data.reshape(-1,1))    

1 Ответ

2 голосов
/ 21 марта 2019

Проблема с вашим запросом состоит в том, что Normalizer работает таким образом, согласно документации:

Нормализация образцов индивидуально в единицу нормы.

Каждая выборка (то есть каждая строка матрицы данных), по крайней мере, с одним нулевой компонент масштабируется независимо от других образцов, так что его норма (l1 или l2) равна одному ( источник здесь )

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

Вам нужно обойти такую ​​ситуацию. Наиболее разумный способ сделать это:

  1. сначала создайте маску, чтобы записать, какие элементы отсутствовали в вашем массиве
  2. создать массив ответов, заполненный пропущенными значениями
  3. применить нормализатор к вашему массиву после выбора только допустимых записей
  4. записать в свой массив ответов нормализованные значения, основанные на их исходной позиции

вот код, детализирующий процесс, на основе вашего примера:

from sklearn.preprocessing import Normalizer, StandardScaler
import numpy as np

data = np.array([0,1,2,np.nan, 3,4])

# set valid mask
nan_mask = np.isnan(data)
valid_mask = ~nan_mask

normalizer = Normalizer(norm='l2')

# create a result array
result = np.full(data.shape, np.nan)

# assign only valid cases to 
result[valid_mask] = normalizer.fit_transform(data[valid_mask].reshape(-1,1)).reshape(data[valid_mask].shape)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...