Как кодировать категориальные функции в sklearn?

У меня есть набор данных с 41 функцией [от 0 до 40 столбцов], из которых 7 являются категориальными. Этот категориальный набор делится на два подмножества:

  • Подмножество строкового типа (функции столбца 1, 2, 3)
  • Подмножество типа int в двоичной форме 0 или 1 (функции столбца 6, 11, 20, 21)

Кроме того, признаки-столбцы 1, 2 и 3 (строкового типа) имеют мощность 3, 66 и 11 соответственно. В этом контексте я должен закодировать их, чтобы использовать алгоритм машины опорных векторов. Это код, который у меня есть:

import numpy as np
import pandas as pd
from sklearn import preprocessing
from sklearn import feature_extraction

df = pd.read_csv("train.csv")
datanumpy = df.as_matrix()
X = datanumpy[:, 0:40]  # select columns 1 through 41 (the features)
y = datanumpy[:, 41]  # select column 42 (the labels)

Я не знаю, лучше ли использовать DictVectorizer() или OneHotEncoder() [по причинам, которые я изложил выше], и в основном каким образом их использовать [с точки зрения кода] с матрицей X, которая у меня есть. Или я должен просто присвоить номер каждой мощности в подмножестве строкового типа (поскольку они имеют высокую мощность, и поэтому мое пространство функций будет увеличиваться в геометрической прогрессии)?

EDIT Что касается подмножества типа int, я думаю, что лучший выбор - сохранить функции столбцов такими, какие они есть (не передавать их какому-либо кодировщику). Проблема сохраняется для подмножества строкового типа с высокая кардинальность.


person Gil    schedule 15.11.2016    source источник


Ответы (3)


Это, безусловно, самое простое:

 df = pd.get_dummies(df, drop_first=True)

Если вы получаете переполнение памяти или оно слишком медленное, уменьшите кардинальность:

top = df[col].isin(df[col].value_counts().index[:10])
df.loc[~top, col] = "other"
person simon    schedule 15.11.2016
comment
Насколько я понимаю, это неприемлемый ответ, потому что он не гарантирует согласованности между разными объектами DataFrame (например, поездом и тестом). - person ldavid; 25.10.2017
comment
В случае обучения/тестирования вы можете просто подать заявку до разделения, хотя, конечно, та же проблема может возникнуть с новым набором данных, который вы пытаетесь предсказать. В этом случае одним из решений является указание категорий с использованием категориальных данных pandas, а затем применение одной и той же спецификации к каждому набору данных. Таким образом, get_dummies каждый раз будет использовать одну и ту же кодировку. - person simon; 26.10.2017

Согласно официальной документации One Hot Encoder, его следует применять к комбинированному набору данных (обучение и тестирование). В противном случае он может не сформировать правильную кодировку.

И с точки зрения производительности я думаю, что One Hot Encoder намного лучше, чем DictVectorizer.

person JKC    schedule 10.11.2017
comment
Почему One-Hot Encoder намного лучше, чем DictVectorizer? есть ли какие-либо данные, подтверждающие это? - person WY Hsu; 26.11.2017

Вы можете использовать pandasметод .get_dummies(), предложенный @simon здесь выше, или вы можете использовать эквивалент sklearn, указанный OneHotEncoder.

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

Если для некоторых признаков кардинальность слишком велика, назначьте низкую n_values. Если у вас достаточно памяти, не беспокойтесь, закодируйте все значения ваших функций.

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

person MMF    schedule 16.11.2016
comment
Я согласен с вами, но, поскольку мой набор данных действительно огромен, я также беспокоюсь о времени, которое потребуется для запуска Support Vector. В любом случае, у вас есть база скриптов, использующая OneHotEncoder (я думаю, с предыдущим использованием LabelEncoder)? - person Gil; 16.11.2016