Простая, но очень практичная функция

Scikit-learn — одна из наиболее часто используемых библиотек Python в экосистеме науки о данных. Он служит полным инструментом для задач машинного обучения от предварительной обработки данных до оценки модели.

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

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

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

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

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

Новый OneHotEncoder, входящий в состав Scikit-learn 1.1, позволяет группировать редко встречающиеся категории. Давайте сделаем пример, чтобы продемонстрировать, как он используется.

Прежде чем мы начнем, давайте удостоверимся, что у вас правильная версия.

import sklearn
sklearn.__version__
# output
'1.1.2'

Если у вас есть версия до 1.1, вы можете обновить ее с помощью pip.

pip install --upgrade scikit-learn

Давайте создадим образец DataFrame с двумя категориальными функциями.

import pandas as pd
df = pd.DataFrame({
  "City": ["Houston"] * 25 + ["Rome"] * 30 + ["Madrid"] * 3 + 
          ["London"] * 2,
    
  "Division": ["A"] * 30 + ["B"] * 25 + ["C"] * 1 + ["D"] * 4
})
df["City"].value_counts()
# output
Rome       30
Houston    25
Madrid      3
London      2
Name: City, dtype: int64
--------------------------------------
df["Division"].value_counts()
# output
A    30
B    25
C     1
D     4
Name: Division, dtype: int64

В столбце города есть 3 значения для Мадрида и 2 для Лондона, что намного меньше, чем для двух других городов. Распределение значений в столбце деления также аналогично.

Следующим шагом является кодирование этих двух функций.

from sklearn.preprocessing import OneHotEncoder
# create an encoder and fit the dataframe
enc = OneHotEncoder(sparse=False).fit(df)
encoded = enc.transform(df)
# convert it to a dataframe
encoded_df = pd.DataFrame(
     encoded, 
     columns=enc.get_feature_names_out()
)
encoded_df.head()

Поскольку мы не группировали нечастые значения, в закодированных данных имеется 8 столбцов. Попробуем с группировкой, которую можно сделать с помощью параметра min_frequency. Категории, которые имеют меньше вхождений, чем указанная минимальная частота, будут сгруппированы.

# create an encoder and fit the dataframe
enc = OneHotEncoder(min_frequency=5, sparse=False).fit(df)
encoded = enc.transform(df)
# convert it to a dataframe
encoded_df = pd.DataFrame(
     encoded, 
     columns=enc.get_feature_names_out()
)
encoded_df.head()

Теперь у нас есть DataFrame с 6 функциями. Разница будет более существенной при работе с категориями с большим количеством различных значений.

Рассмотрим функцию, которая имеет 20 различных значений, и 95% значений принадлежат 4 различным значениям. Остальные 5% относятся к 16 различным значениям вместе взятым. В этом случае эффективной стратегией будет объединение этих 16 значений в одну группу.

Вы можете стать участником Medium, чтобы разблокировать полный доступ к моим материалам, а также к остальной части Medium. Если вы уже подписались, не забудьте подписаться, если хотите получать электронные письма всякий раз, когда я публикую новую статью.

Спасибо за чтение. Пожалуйста, дайте мне знать, если у вас есть какие-либо отзывы.