У меня есть следующий набор данных, в котором столбец Direccion del viento (Pos) имеет категориальные значения
Всего Direccion del viento (Pos) имеет 8 категорий:
- SO - Sur oeste
- SE - Sur este
- S - Sur
- N - Norte
- НЕТ - Nor oeste
- NE - Nor este
- O - Oeste
- E - Эсте
Затем я конвертирую этот фрейм данных в массив numpy и получаю:
direccion_viento_pos
dtype: bool
[['S']
['S']
['S']
...
['SO']
['NO']
['SO']]
Поскольку у меня есть значения символьной строки, я хочу, чтобы это были числовые значения, поэтому мне нужно закодировать категориальные переменные. То есть кодирование имеющегося у нас текста числовыми значениями
Затем я выполняю два действия:
- Я использую LabelEncoder (), чтобы просто кодировать значения в числа в зависимости от того, сколько у меня категорий.
Кодировка метки - это просто преобразование каждого значения в столбце в число.
labelencoder_direccion_viento_pos = LabelEncoder()
direccion_viento_pos[:, 0] = labelencoder_direccion_viento_pos.fit_transform(direccion_viento_pos[:, 0])
- Я использую OneHotEncoding для преобразования каждого значения категории в новый столбец и присваиваю столбцу значение 1 или 0 (True / False):
Это:
onehotencoder = OneHotEncoder(categorical_features = [0])
direccion_viento_pos = onehotencoder.fit_transform(direccion_viento_pos).toarray()
Это так, поскольку я получаю эти новые значения:
direccion_viento_pos
array([[0., 0., 0., ..., 1., 0., 0.],
[0., 0., 0., ..., 1., 0., 0.],
[0., 0., 0., ..., 1., 0., 0.],
...,
[0., 0., 0., ..., 0., 0., 1.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 1.]])
Затем я конвертирую этот массив direccion_viento_pos в dataframe, чтобы лучше визуализировать его:
# Turn array to dataframe with columns indexes
cols = ['E', 'N', 'NE', 'NO', 'O', 'S', 'SE', 'SO']
df_direccion_viento = pd.DataFrame(direccion_viento_pos, columns=cols)
Затем я могу получить по каждому значению категории новый столбец и присвоить столбцу значение 1 или 0 (Истина / Ложь).
Если я использую pandas.get_dummies ( ) , я получаю тот же результат.
Мой вопрос: это лучший способ справиться с категориальными переменными? Наличие столбца для каждой категории и наличие нулей в некоторых из них не помогает иметь смещение или шум в данных, когда применяются алгоритмы автоматического обучения?
Недавно я начал читать об этом в эту статью, но я ценю любые рекомендации по этому поводу
ОБНОВЛЕНИЕ
Я читал о новых способах управления этими категориальными переменными, упомянутыми выше, и обнаружил следующее:
По этой ссылке упражнений с блокнотами Jupyter (на ячейка 59) относятся к книге Практическое машинное обучение с помощью Scikit-Learn и TensorFlow. автор говорит о LabelEncoder
следующее:
Предупреждение: более ранние версии книги использовали класс LabelEncoder или метод Pandas Series.factorize () для кодирования строковых категориальных атрибутов как целых чисел. Однако класс OrdinalEncoder, который планируется ввести в Scikit-Learn 0.20 (см. PR # 10521), предпочтительнее, поскольку он предназначен для входных функций (X вместо меток y)
Это означает, что LabelEncoder используется для кодирования зависимой переменной вместо входных функций. Мой набор данных категориальных переменных direccion_viento является входными функциями.
Изначально в scikit-learn dev версии 0.20 он существовал CategoricalEncoder
. Я копирую этот класс в файл categorical_encoder.py
и примените его:
from __future__ import unicode_literals
import pandas as pd
# I import the Categorical Encoder locally from my project environment
from notebooks.DireccionDelViento.sklearn.preprocessing.categorical_encoder import CategoricalEncoder
# Read the dataset
direccion_viento = pd.read_csv('Direccion del viento.csv', )
# No null values
print(direccion_viento.isnull().any())
direccion_viento.isnull().values.any()
# We select only the first Direccion Viento (pos) column
direccion_viento = direccion_viento[['Direccion del viento (Pos)']]
encoder = CategoricalEncoder(encoding='onehot-dense', handle_unknown='ignore')
dir_viento_encoder = encoder.fit_transform(direccion_viento[['Direccion del viento (Pos)']])
print(" These are the categories", encoder.categories_)
cols = ['E', 'N', 'NE', 'NO', 'O', 'S','SE','SO']
df_direccion_viento = pd.DataFrame(dir_viento_encoder, columns=cols)
И полученный набор данных похож на использование LabelEncoding и OneHotEncoding.
Разница между использованием OneHotEncoder()
и CategoricalEncoder()
заключается в том, что когда я использую КатегорическийEncoder (), не обязательно применять LabelEncoder (), и причина в том, что CategoricalEncoder
может работать напрямую со строками, и мне не нужно сначала преобразовывать значения моих переменных в целые числа.
Это означает, что CategoricalEncoder
, если это то же самое, что OneHotEncoder
или результат их применения, на самом деле то же самое ...
После чтения и поиска в отношении класса CategoricalEncoder()
Орелиен Жерон сообщает нам в своей книге, что CategoricalEncoder
будет устаревшим в стабильной версии scikit-learn-0.20.
Фактически, команда scikit-learn в их текущая главная ветвь обозначает, что CategoricalEncoder()
КатегорическийEncoder недолго существовал в 0.20dev. Его функциональность была добавлена в OneHotEncoder и OrdinalEncoder.
Этот запрос на вытягивание назван Переосмысление API КатегорическогоEncoder? strong> тоже обозначают процесс рабочего процесса, который не рекомендуется CategoricalEncoder()
Затем, как указано выше, я применил OrdinalEncoder
, и результат, который я получил, такой же, как и при применении только LabelEncoder
.
from __future__ import unicode_literals
# from .future_encoders import OrdinalEncoder
from sklearn.preprocessing import OrdinalEncoder
import pandas as pd
# Read the dataset
direccion_viento = pd.read_csv('Direccion del viento.csv', )
# No null values
print(direccion_viento.isnull().any())
direccion_viento.isnull().values.any()
# We select only the first column Direccion Viento (pos)
direccion_viento = direccion_viento[['Direccion del viento (Pos)']]
print(direccion_viento.head(10))
ordinal_encoder = OrdinalEncoder()
direccion_viento_cat_encoded = ordinal_encoder.fit_transform(direccion_viento)
И я получаю этот массив, который аналогичен результату, когда я использовал LabelEncoder()
:
В чем разница между OrdinalEncoder
и LabelEncoder
, взяв за основу ваши концепции:
LabelEncoder (), чтобы просто кодировать значения в число в зависимости от того, сколько у меня категорий. Кодировка метки - это просто преобразование каждого значения в столбце в число.
а также
OrdinalEncoder: кодирует категориальные функции как целочисленный массив. Входные данные этого преобразователя должны быть подобны массиву целых чисел или строк, обозначающих значения, принимаемые категориальными (дискретными) функциями. Функции преобразуются в порядковые целые числа. Это приводит к одному столбцу целых чисел (от 0 до n_categories - 1) для каждой функции.
Могу ли я выбрать результирующий набор данных, созданный с применением метода OneHotEncoding, или выбрать набор данных, созданный с применением метода OrdinalEncoder? Что наиболее подходящее?
Думаю, что необходимо различать номинальные и порядковые характеристики. Порядковые признаки можно понимать как категориальные значения, которые можно сортировать или упорядочивать.
Себастьян Рашка в своей книге по машинному обучению Python говорит, что этот образец относится к категориальным данным.
Например, размер футболки будет порядковым признаком, потому что мы можем определить порядок XL> L> M. Напротив, номинальные характеристики не подразумевают никакого порядка, и, продолжая предыдущий пример, мы могли бы подумать о T -цвет рубашки как номинальная характеристика, поскольку обычно нет смысла говорить, что, например, красный цвет больше синего.
Мои значения direccion_viento ('E', 'N', 'NE', 'NO', 'O', 'S', 'SE', 'SO')
не имеют порядка или любое значение больше или меньше другого. Разве не имеет смысла считать их порядковыми по своей природе? В самом деле?
В этом смысле до этого момента я считаю, что OneHotEncoding - лучший вариант для моих direccion_viento
функций ввода.
Кто-нибудь скажет мне перед следующим:
Зависит от того, что вы планируете делать с данными. Есть разные способы работы с категориальной переменной. Вам нужно выбрать более подходящий> для модели / ситуации, над которой вы работаете, исследуя, подходит ли выбранный вами подход для модели, которую вы используете.
Я буду работать с такими моделями, как кластеризация, линейная регрессия и нейронные сети.
Как я могу узнать, что лучше всего подходит: OrdinalEncoder или OneHotEncoder?