Как я могу добавить масштабированные данные в исходный набор данных? - PullRequest
0 голосов
/ 29 марта 2020

Я немного запутался с преобразованием и обратным преобразованием различных типов данных. У меня есть датафрейм с числовыми и категориальными столбцами.

  1. Взятие фрейма данных и преобразование категориальных значений в числовые
  2. Взятие нового фрейма данных и масштабирование его.
  3. Запуск моей модели на нем.
  4. Попытка преобразовать его обратно (немасштабированное + преобразование числовых категориальных данных обратно в строки)

Проблема в том, что я выполняю шаги 1-3, но я не уверен, как преобразовать катерогенные данные обратно. Я могу преобразовать фрейм данных, чтобы он больше не масштабировался (в обратном порядке шаг 2), но не уверен, как повторно добавить имена столбцов.

Вот пример, исходные данные:

     totalRevenue Exchange  costOfRevenue
0    2.601740e+11   NASDAQ   1.617820e+11
1    2.601740e+11   NASDAQ   1.617820e+11
2    2.655950e+11   NASDAQ   1.637560e+11
3    2.655950e+11   NASDAQ   1.637560e+11

После преобразование и преобразование обратно, у меня есть

[[2.60174e+11 0.00000e+00 1.61782e+11]
 [2.60174e+11 0.00000e+00 1.61782e+11]
 [2.65595e+11 0.00000e+00 1.63756e+11]
 [2.65595e+11 0.00000e+00 1.63756e+11]

Вот мой код:

catergoryEncoder = OrdinalEncoder()
cleanData['Exchange'] = catergoryEncoder.fit_transform(X_train['Exchange'].values.reshape(-1, 1))

scaler = MinMaxScaler()
scaled = scaler.fit_transform(X_train)
unscaled = scaler.inverse_transform(scaled)

Немасштабированный вывод просто выводит то, что я отображал выше. Я думаю, что некоторые проблемы, с которыми я сталкиваюсь, начинаются с фрейма данных pandas, но после преобразования у меня есть массив NumPy, который мне не совсем понятен, как преобразовать столбец «exchange» обратно.

Мне известна команда для преобразования данных категории обратно: catergoryEncoder.inverse_transform(np.asarray(unscaled.Exchange).reshape(-1, 1)), но я получаю следующую ошибку (подозреваю, потому что имена столбцов теряются при масштабировании / масштабировании):

AttributeError: 'numpy.ndarray' object has no attribute 'Exchange'

Что я могу сделать, чтобы преобразовать это легко назад / вперед? Также я подхожу к этому правильному пути?

1 Ответ

0 голосов
/ 30 марта 2020

Чтобы ответить на первую часть вашего вопроса: почему вы получаете эту ошибку? Ваш OrdinalEncoder был обучен с использованием массива numpy, полученного из значений pandas Ser ie.

Как вы прокомментировали, (действительно ли здесь необходимо изменение формы?) (Np.asarray не должен необходимо, поскольку fit_transform уже дает массив numpy)

catergoryEncoder.inverse_transform(np.asarray(unscaled.Exchange))

приведет к ошибке, поскольку массив numpy не имеет понятия имен столбцов. Вместо этого вам следует вернуть данные Exchange по index :

catergoryEncoder.inverse_transform(unscaled[:,1])

, где 1 - это индекс столбцов, которые вы хотите выбрать. Это должно вернуть вам ваши исходные данные.

Теперь, о правильном / чистом способе реализации таких вещей, стиль Pipelines - это путь к go ( пример ).

PS: использование One Hot Encoding должно устранить необходимость масштабирования данных, поскольку все значения кодируются в диапазоне от 0 до 1.

РЕДАКТИРОВАТЬ

Чтобы ответить на ваши комментарии, см. Полный пример ниже:

Давайте начнем с кадра данных:

df = pd.DataFrame({'Numeric':[0,1,2,3,4,5],'Categorial1':['A','A','A','B','B','B'],'Categorial2':['A','C','A','C','B','C']})
   Numeric Categorial1 Categorial2
0        0           A           A
1        1           A           C
2        2           A           A
3        3           B           C
4        4           B           B
5        5           B           C

Теперь, применяя кодировщик:

from sklearn.preprocessing import OrdinalEncoder
encoder = OrdinalEncoder()
#dtype 'O' mean that columns is of type object, this will get all your non numeric data
categorial_column = [col for col in df.columns if df[col].dtype == 'O'] 
df[categorial_column] = encoder.fit_transform(df[categorial_column])

Обратите внимание, что если вы хотите работать с массивом numpy вместо DataFrame, вы можете "сохранить" индекс ваших категориальных столбцов с помощью:

categorial_index = np.where(df.columns.isin(categorial_column))
n_categorial = len(categorial_column)
df.values[:,categorial_index].reshape(-1,n_categorial)

, предоставив вам следующее (с полным фреймом данных):

   Numeric  Categorial1  Categorial2
0        0          0.0          0.0
1        1          0.0          2.0
2        2          0.0          0.0
3        3          1.0          2.0
4        4          1.0          1.0
5        5          1.0          2.0

Тогда вы уже сделали проклятие:

from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
scaled = scaler.fit_transform(df)
unscaled = scaler.inverse_transform(scaled)

Затем вернитесь к фрейму данных:

df = pd.DataFrame(unscaled, columns=df.columns)
df[categorial_column] = encoder.inverse_transform(df[categorial_column])

, давая вам назад:

   Numeric Categorial1 Categorial2
0      0.0           A           A
1      1.0           A           C
2      2.0           A           A
3      3.0           B           C
4      4.0           B           B
5      5.0           B           C

Теперь вы можете встроить все этапы предварительной обработки в какую-либо функцию или конвейер sklearn и сделать это с помощью й это!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...